从 MongoDB Java Rx 驱动程序迁移到反应式流驱动程序的性能下降

Posted

技术标签:

【中文标题】从 MongoDB Java Rx 驱动程序迁移到反应式流驱动程序的性能下降【英文标题】:Performance hit migrating from MongoDB Java Rx driver to reactive streams driver 【发布时间】:2022-01-07 01:28:18 【问题描述】:

我们正在尝试从基于 RxJava 的旧 Mongo 驱动程序 mongodb-driver-rx (v1.5.0) 升级到较新的 mongodb-driver-reactivestreams (v1.13.1) - 由于依赖关系,这不是最新的,但肯定是更新了很多.旧的 RxJava 已经停产多年。新驱动程序一切正常,但在高负载下,性能受到太大影响,我们无法解释原因。

关于我们应用的一些背景信息:

我们的 (Java) 应用程序在 AWS EC2 上运行(高峰期大约有 30 个 m5.xlarge 实例),并且基于 Vertx 和 RxJava 堆栈。我们正在运行一个具有 1 个主节点和 2 个辅助节点的 Mongo 集群(m5.12xlarge)。在高峰时间与 Mongo 的典型同时连接数是几千。我们有一个基于 gatling 的负载测试,通常运行 1 小时,使用 60 个 AWS EC2 实例、1 个主要的 Mongo 和 2 个类似生产环境的辅助设备,同时有 10 万用户。

一些观察:

对一段简单的集成测试代码(执行一些常见的数据库操作)进行微基准测试表明新旧驱动程序之间没有显着的性能差异。 使用旧驱动程序,我们在负载测试中看到了良好的整体性能,平均 20 毫秒响应时间和 200 毫秒响应时间在 99% 的百分位数内。 使用新驱动程序,运行相同的负载测试,事情会爆炸(平均响应时间超过 2000 毫秒,最终由于等待队列已满,超过 60% 的请求失败)。 如果我们只使用 1 个 EC2 实例和 1.6k 个并发用户(即每个实例的负载相同)运行负载测试,新旧驱动程序之间没有显着的性能差异,并且运行相对顺利。李>

MongoDB 驱动程序设置:

clusterSettings = "hosts=[localhost:27017], mode=MULTIPLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='LatencyMinimizingServerSelectoracceptableLatencyDifference=15 ms', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='30000 ms', maxWaitQueueSize=500, description='null'"
connectionPoolSettings = "ConnectionPoolSettingsmaxSize=100, minSize=0, maxWaitQueueSize=50000, maxWaitTimeMS=5000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=300000, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[]"
heartbeatSocketSettings = "SocketSettingsconnectTimeoutMS=10000, readTimeoutMS=10000, keepAlive=true, receiveBufferSize=0, sendBufferSize=0"
readPreference = "primary"
serverSettings = "ServerSettingsheartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverListeners='[]', serverMonitorListeners='[]'"
socketSettings = "SocketSettingsconnectTimeoutMS=10000, readTimeoutMS=0, keepAlive=true, receiveBufferSize=0, sendBufferSize=0"
sslSettings = "SslSettingsenabled=false, invalidHostNameAllowed=true, context=null"
writeConcern = "WriteConcernw=null, wTimeout=null ms, fsync=null, journal=null"

我们尝试过的事情: (全部无效)

切换 Mongo db 版本(我们目前仍在使用 3.6,但我们也尝试过 4.0); 围绕每个 db 操作添加基于 Vertx 的 RxJava 调度程序(我们尝试过 Schedulers.io()RxHelper.scheduler(vertx)) 使用包含AsynchronousChannelGroupAsynchronousSocketChannelStreamFactoryFactory 配置Mongo 设置,固定线程池大小为100; 使用包含NioEventLoopGroupNettyStreamFactoryFactory 配置Mongo 设置; 使用每个实例的最大 Mongo 连接池(从 100 到 500 不等);

暂时无法帮助我们的事情: (我们知道这些,其中一些在我们的路线图中,但现在它们太耗时了)

更好的索引管理(我们已经对此进行了优化,没有使用低效 collscan 的查询) 将应用拆分为更小的服务 通过使用内存中 JVM 缓存 (Guava) 或远程缓存 (Redis) 来减轻 Mongo 的负载 - 我们已经在某种程度上做到了这一点 摆脱 Vertx 以支持例如 Spring Boot

这似乎是某种池或线程问题,但我们无法确定确切的问题,并且分析这种问题也非常困难。

对可能导致问题的原因以及如何解决问题有任何想法吗?

【问题讨论】:

从两次运行中获取 JFR 并进行比较? 【参考方案1】:

这可能不是您要寻找的答案,但您为什么不使用official Vert.x client for MongoDB?

(由于声誉低,无法发表评论)

【讨论】:

感谢您的回复。我们知道它的存在,但我们不愿意使用它有两个原因:1)为此修改代码库需要大量工作; 2) 未来我们将从 Vertx 过渡到 Spring Boot,因此在这方面减少我们对 Vertx 的依赖而不是增加它是有意义的。

以上是关于从 MongoDB Java Rx 驱动程序迁移到反应式流驱动程序的性能下降的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose / Mongodb 迁移到 MySQL

从 mongoDB 迁移后的 AWS DocumentDB 错误

从 Postgres 迁移到 MongoDB

使用 pymongo 将数据从 Mysql 迁移到 MongoDB

将数据从 PostgreSQL 迁移到 MongoDB

将 Rails 项目从 MySQL 迁移到 MongoDB