spring-data-mongodb v3.4.18+MongoDB 5.0插入性能异常求助
Spring Data MongoDB 高负载下插入性能骤降问题分析
问题场景与异常表现
系统基于Spring v5.3.36 + MongoDB Server v5.0搭建,当使用spring-data-mongodb v3.4.18 + mongodb-driver-sync v4.6.1组合时,高负载下MongoRepository.insert(doc)调用出现严重性能问题,具体表现为:
- 连接池无法扩容:即使配置
MongoClientSettings.applyToConnectionPoolSettings(builder -> builder.maxSize(1000)),MongoDB服务器端观测到的实际连接池大小从未超过70 - 频繁关闭连接:调试日志中出现大量
"Closing connection connectionId"记录,日志片段如下:
2024-06-14 14:54:30.366 [pool-14859-thread-1] DEBUG o.s.data.mongodb.core.MongoTemplate.insertDocument - Inserting Document containing fields: [_id, ... sessionId, actionHost, _class] in collection: collection_xyz 2024-06-14 14:54:33.163 [pool-14859-thread-1] DEBUG org.mongodb.driver.connection.debug - Closing connection connectionId{localValue:406} 2024-06-14 14:54:33.164 [pool-14859-thread-1] DEBUG org.mongodb.driver.operation.debug - retryWrites set to true but the server is a standalone server. 2024-06-14 14:54:33.164 [pool-14859-thread-1] DEBUG org.mongodb.driver.protocol.command.debug - Sending command '{"insert": ...}, "documents": [{"_id":...}]}' with request id 15074 to database my_db on connection [connectionId{localValue:390, serverValue:95}] to server localhost:27017 2024-06-14 14:54:33.169 [pool-14859-thread-1] DEBUG org.mongodb.driver.protocol.command.debug - Execution of command with request id 15074 completed successfully in 4.30 ms on connection [connectionId{localValue:390, serverValue:95}] to server localhost:27017
- 调用延迟极高:
MongoTemplate.insertDocument()日志与驱动实际执行插入的时间间隔长达3秒
对比验证(无代码修改)
切换为spring-data-mongodb v3.2.12 + mongodb-driver-sync v4.2.3组合(适配MongoDB Server v4.4)后,性能恢复正常:
- 连接池正常扩容:MongoDB服务器端观测到的连接池大小稳定在约350
- 无频繁关闭连接日志:未出现
"Closing connection connectionId"相关记录 - 延迟极低:
MongoTemplate.insertDocument()与驱动执行的时间间隔仅为毫秒级
根因分析
结合日志与版本差异,问题根源在于spring-data-mongodb v3.4.x 与 mongodb-driver-sync v4.6.x 组合在单机MongoDB场景下的会话处理逻辑缺陷:
- 日志中
"retryWrites set to true but the server is a standalone server"的提示表明,驱动在单机模式下会自动禁用重试写,但spring-data-mongodb v3.4.18在处理插入操作时,错误地尝试开启会话(Session)并绑定到连接,而单机MongoDB不支持会话相关特性,导致驱动被迫关闭当前连接并重新获取新连接 - 频繁的连接关闭与重建会导致连接池无法有效扩容(每次重建连接都需要额外开销,且连接被频繁销毁无法积累到配置的maxSize),同时
MongoTemplate.insertDocument()到实际执行插入的间隔时间被连接销毁、重建的耗时占用,直接引发3秒级的延迟 - spring-data-mongodb v3.2.x版本未引入该会话绑定逻辑,或对单机场景做了正确兼容,因此搭配低版本驱动时无此问题
备注:已排除数据库服务器性能、JVM堆内存、连接空闲时间配置等因素的影响。
内容的提问来源于stack exchange,提问作者Herbert Wu
相关产品推荐
相关产品推荐

