前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mongos连接模型探究

Mongos连接模型探究

作者头像
MongoDB中文社区
发布2019-04-22 15:44:25
5660
发布2019-04-22 15:44:25
举报
文章被收录于专栏:MongoDB中文社区MongoDB中文社区

经常有同学会问, client/mongos/mongod之间的连接模型是怎样的关系,一个客户端连接对应多少个对后端mongod的连接。这个问题是有意义的,因为我们知道,client到mongod之间的连接,是 one-thread-per-connection的模式的,而且每个连接线程默认分配1MB内存,一千个连接就是1GB的内存; 而且活跃连接多了,内核态的线程切换引起的性能开销又是一个让人头痛的问题。one-thread-per-connection的模型相当传统(落后),该模型将线程切换/调度交给操作系统管理,带来的结果就是:延迟不可控。不过mongos接入层的引入,较好的缓解了该问题,本文主要介绍mongos和mongod之间的连接池模型,以及调优参数项。

◆◆

连接模型

◆◆

mongos作为client和mongod之间的中间层,需要管理两方面的连接

  1. client对mongos的连接
  2. mongos对mongod分片以及每个副本集的连接

mongos对client的连接模型

client对mongos的连接采用one-thread-per-connection的模式,listener线程负责accept到新的连接,每个连接新分配一个线程来处理,线程栈大小默认为1MB。

总结,mongos对客户端的连接模型是采用one-thread-per-connection的经典方式。 另外,该方式有一个较为严重的问题:在活跃连接较多的场景下,会引起较多的线程切换,导致处理延时难以量化。

mongos对后端分片的连接模型

mongos对后端分片mongod的连接模型如下图。 mongos采用ASIO网络框架,每个用户请求通过网络实践回调/异步状态机的Reactor模型驱动。ReactorPool被划分为N个ReactWorker,每个Worker对等的处理用户请求。每个Worker中有M个连接池(M=后端所有mongod的个数)。如果后端有3分片,每个分片3副本,则每个Worker中管理9个连接池。

用户请求被RoundRobin到ReactWorker中,如下代码所示:

◆◆

mongos连接池可调优参数

◆◆

mongos连接池可调优参数主要在 src/mongo/executor/connectionpool.h 和 src/mongo/executor/connectionpool.cpp 中。默认值为

连接池的细分

上面我们说过,mongos有一个ASIO的ReactorPool,每个Pool有有若干个连接池,每个连接池负责管理某个特定的mongod的连接。 每个连接池又分为 1. readyPool (管理空闲连接) 2. processingPool (管理在创建中/定期检查健康状态的连接) 3. checkoutPool (管理正在使用中的连接)

对于一个特定的连接,它在三个池中的状态转移关系如下图。

  1. minConnections 为默认为1,表示每个worker默认对每个mongod初始连接是1,且如果readyPool中连接过多,最终会将readyPool连接个数收敛到1
  2. maxConnections 默认没做限制,表示每个worker不限制对后端mongod的连接个数
  3. refreshTimeout 和 refreshRequirement, 每个连接有最长IdleTime,大小为refreshRequirement,默认为5分钟,超过这个值,如果当前连接个数大于minConnections,就会丢弃该连接,否则对该连接进行heartBeat后重新放回readyPool。refreshTimeout参数不重要,表示与mongod进行heartBeat的超时时间。

相关代码如下所示:

hostTimeout 如果该连接池长时间没有处理任何请求,就将该连接池全部释放掉。

ASIO ReactorWorkerPool大小

mongodb 提供taskExecutorPoolSize参数挑中mongos的ReactorPool的大小。用户可以通过setParameter参数,在mongos的配置文件中指定。该参数默认没有指定,因此mongos默认的workerPool大小为cpu核心个数(cat /proc/cpuinfo)。

有价值的调优项

1. minConnection和 refreshRequirement

minConnection值默认为1, 举个例子,如果在一个8核机器上默认配置部署mongos,则mongos对后端每个mongod有1X8=8个连接,如果是3副本,2分片,则总用有1X8X3X2=48个连接。如果有流量峰值,或后端mongod处理不过来,则会创建新的连接,峰值过去后,多余的连接会在refreshRequrement指定的时间后释放。 如果对业务平均响应和平均峰值间隔有个合理的预估,就可以有把握的调整这两个值的大小。 举个例子,如果两分片,平均写入响应时间在10ms,写入TPS要求为1000。峰值间隔为5分钟。则minConnection最好设置大于 1000/2(两副本)/100(10ms)=5,从而防止冷启动带来的延迟开销。refreshRequirement = 5X2 = 10分钟,idle回收时间大于业务峰值间隔。从而避免峰值时创建新的连接。

2. maxConnection

这个值默认没有做限制,这样非常容易使mongos对mongod造成connection-flood。如果mongod请求处理超过客户端超时。客户端对mongos发起重试,mongos对mongod的请求还在checkoutPool中没有回收,readyPool中不够分配,只能创建新连接处理客户端的重试,重试依然超时,如此往复导致对mongod的连接数暴增。 这个值建议通过最大QPS/TPS来估算。以写为例: maxConnection = maxTPS / nShards / nMongos / taskExecutorPoolSize

3. taskExecutorPoolSize 与mongos部署模式

mongos默认不适合单机多部署,因为asioWorker的个数等于CPU核心个数。如果单机多部署,则需要考虑线程切换带来的影响。比较合理的mongos单机部署多方式是使用cgroups或taskset将mongos binding到对应的核上。并且binding的核心个数 = taskExecutorPooSize

end

作者:孔德雨

  • MongoDB中文社区深圳分会主席
  • 现就职于腾讯互娱 技术运营部
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Mongoing中文社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档