你的 ChatMemory 卡顿?MySQL vs Redis 性能实测
上一篇我实现了 Spring AI ChatMemory 的两种持久化方式:MySQL 和 Redis。评论区有人问:“到底是哪个快?”很多博客都说Redis 比 MySQL 快很多,但到底快多少?我直接上测试,写了 3 个测试接口,跑了 6000 字的性能对比…结果可能超出你的预期:写入快 60%,读取却慢 6.5 倍!一、为什么做性能对比?在实现 ChatMemory 持久化时,我遇到了一个经典选择:MySQL: 生产稳定,数据可查询,支持 ACIDRedis: 高性能,支持 TTL,适合缓存很多博客都说Redis 比 MySQL 快很多,但到底快多少?我做了这个测试:测试环境:CPU: Intel i7内存: 16GB磁盘: SSDSpring Boot 3.3.5 Spring AI 1.0.0测试工具:写入测试:/perf/write?count10000混合测试:/perf/mixed?writeCount5000readEvery100二、MySQL 版测试结果Step 1: 启动 MySQL 版应用CHAT_MEMORY_TYPEmysqljava-jarhello-ai.jarStep 2: 写入 10000 条消息访问:http://localhost:8080/perf/write?count10000结果:写入 10000 条消息耗时: 2245 ms (0.22 ms/条)Step 3: 混合测试(写 5000 条,每 100 条读一次)访问:http://localhost:8080/perf/mixed?writeCount5000readEvery100结果:混合测试:写入 5000 条,其中读取 50 次 总耗时: 992 ms 写入耗时: 931 ms 读取耗时: 61 ms 平均读取耗时: 1.22 ms/次详细分析:操作耗时平均耗时写入 10000 条2245 ms0.22 ms/条写入 5000 条931 ms0.19 ms/条读取 50 次61 ms1.22 ms/次MySQL 的优势:✅ 事务支持,数据一致性保证✅ 数据可查询,方便调试✅ 生产环境稳定可靠MySQL 的劣势:❌ 每次写入都要执行 SQL❌ 需要处理事务提交❌ 磁盘 I/O 限制性能三、Redis 版测试结果Step 1: 启动 Redis 版应用CHAT_MEMORY_TYPEredisjava-jarhello-ai.jarStep 2: 写入 10000 条消息访问:http://localhost:8080/perf/write?count10000结果:写入 10000 条消息耗时: 898 ms (0.09 ms/条)Step 3: 混合测试(写 5000 条,每 100 条读一次)访问:http://localhost:8080/perf/mixed?writeCount5000readEvery100结果:混合测试:写入 5000 条,其中读取 50 次 总耗时: 1406 ms 写入耗时: 1007 ms 读取耗时: 399 ms 平均读取耗时: 7.98 ms/次详细分析:操作耗时平均耗时写入 10000 条898 ms0.09 ms/条写入 5000 条1007 ms0.20 ms/条读取 50 次399 ms7.98 ms/次四、性能对比:写入 vs 读取写入性能对比:MySQL: 10000 条 → 2245 ms (0.22 ms/条) Redis: 10000 条 → 898 ms (0.09 ms/条) 差异: Redis 快 60% ⚡读取性能对比:MySQL: 平均 1.22 ms/次 Redis: 平均 7.98 ms/次 差异: MySQL 快 6.5 倍 混合测试对比:测试项MySQLRedis胜者写入 5000 条931 ms1007 ms✅ MySQL读取 50 次61 ms399 ms✅ MySQL总耗时992 ms1406 ms✅ MySQL五、为什么写入快,读取慢?写入性能:Redis 快 60%✅原因:MySQL: 每次写入要执行 SQL,处理事务,磁盘 I/ORedis: 内存写入,JSON 序列化,无磁盘 I/O读取性能:MySQL 快 6.5 倍✅原因:MySQL: 直接从数据页读取,二进制格式Redis: JSON 序列化/反序列化,解析对象,额外 CPU 开销六、生产选型建议什么时候用 MySQL?✅读取密集型应用需要查询历史对话数据需要长期存储和备份团队熟悉关系型数据库需要 ACID 事务保证适合的应用:AI 客服系统,用户频繁咨询企业内部 AI 助手,需要查询历史记录数据分析平台,需要导出对话记录什么时候用 Redis?✅写入密集型应用会话记忆只保留最近 N 条(如 20 条)需要自动过期(会话超时)分布式部署,需要共享内存对写入性能要求高适合的应用:ChatGPT 类应用,持续对话,频繁写入AI 助手,每轮对话都要更新记忆聊天机器人,多用户并发,高写入混合方案:MySQL Redis⭐高级方案:MySQL 持久化 Redis 缓存// MySQL 持久化JdbcChatMemoryRepositorymysqlRepo;// Redis 缓存RedisChatMemoryRepositoryredisRepo;// 写入:先写 MySQL,再写 RedisredisRepo.saveAll(conversationId,messages);mysqlRepo.saveAll(conversationId,messages);// 读取:先读 Redis,没有再读 MySQLListMessagemessagesredisRepo.findByConversationId(conversationId);if(messagesnull||messages.isEmpty()){messagesmysqlRepo.findByConversationId(conversationId);// 回填 RedisredisRepo.saveAll(conversationId,messages);}优势:MySQL 确保数据持久化Redis 提供高性能读取灵活应对不同场景七、如何切换存储后端?Spring AI ChatMemory 支持两种存储,切换非常简单!方案 1:配置文件切换application.yml:spring:ai:chat:memory:type:redis# mysql 或 redisdata:redis:host:localhostport:6379MySQL 配置:spring:ai:chat:memory:type:mysql# 默认值datasource:url:jdbc:mysql://localhost:3308/hello_aiusername:rootpassword:root方案 2:环境变量切换启动时设置:# 使用 RedisCHAT_MEMORY_TYPEredisjava-jarhello-ai.jar# 使用 MySQLCHAT_MEMORY_TYPEmysqljava-jarhello-ai.jar八、总结核心结论:指标MySQLRedis胜者写入性能0.22 ms/条0.09 ms/条✅ Redis 快 60%读取性能1.22 ms/次7.98 ms/次✅ MySQL 快 6.5 倍写入 10000 条2245 ms898 ms✅ Redis最佳实践:写入密集:用 Redis,快 60%读取密集:用 MySQL,快 6.5 倍混合场景:根据读写比例选择长期存储:用 MySQL,数据不丢会话超时:用 Redis,TTL 自动清理如果 ChatMemory 卡顿,试试这些方法:切换到 Redis:写入性能提升 60%调小 maxMessages:减少数据量,如从 50 改为 20优化 SQL 索引:MySQL 加索引,查询更快批量写入:减少事务次数,提升吞吐量使用连接池:JDBC/HikariCP,减少连接开销下一篇预告:ChatMemory 分布式部署方案关注我,获取更多 Spring AI 开发干货!写在最后我是一名 8年 Java 后端,正在转型 AI 应用开发。Spring AI 系列会持续更新,从 hello world 到 RAG 到 Agent,一路踩坑一路写。如果你也在转型 AI,关注我,一起走。有问题评论区聊,我会逐条回复。如果这篇文章帮到了你,点个赞就是对我最大的鼓励❤️