关于mongodb:叮咚买菜自建MongoDB上云实践

2次阅读

共计 12489 个字符,预计需要花费 32 分钟才能阅读完成。


随着近年来私有云技术及云基础设施的倒退,越来越多的企业转为应用私有云来托管本人的服务。云数据库因为数据可靠性、资源弹性、运维便捷行,云上数据库服务也正成为企业数据管理的较好的抉择。

本文以叮咚买菜自建 MongoDB 数据库整体迁徙上腾讯云 MongoDB 为背景,分享叮咚买菜上云过程中的遇到的疑难问题及对应的性能优化解决办法等,次要包含以下分享内容:

云上 MongoDB 版本选型

平安上云及切换计划

叮咚买菜业务侧性能优化

上云遇到的疑难问题及解决办法

自建上云收益

1. 叮咚买菜自建 MongoDB 上云背景

叮咚买菜业务以生鲜即时配送为外围,兼备新批发电商和生鲜供应链的特点,对高并发和数据一致性有硬性要求。在疾速扩张的过程中,很多服务技术选型以 MongoDB 作为其次要数据存储。相比其余非即时业务场景,叮咚买菜对数据库拜访时延、稳定性、数据一致性、数据安全性也有更刻薄的要求。

借助腾讯云 MongoDB 产品欠缺的自动化运维、数据安全备份回档、云弹性等能力,能够疾速补齐叮咚买菜的外围 MongoDB 数据库根底技术能力,确保数据团队能够熟能生巧的撑持业务开发。

叮咚数据团队基于自建成本、物理资源有余等起因,通过综合评估,决定把 MongoDB 数据迁徙到腾讯云 MongoDB 上。

2. 云上版本举荐及切换计划

业务正式开始迁徙前,联合叮咚 DBA 和业务同学理解具体场景、MongoDB 集群部署形式、业务 MongoDB 用法、内核版本、客户端版本、客户端 driver 类型等。提前理解到用户第一手信息:
自建 MongoDB 版本较低

客户端 driver 次要包含 java 和 PHP

集群部署都带 tag

集群存在较频繁的抖动问题

2.1. 腾讯云 MongoDB 内核版本举荐
叮咚自建 MongoDB 因历史起因统一放弃在官网 MongoDB-3.2 版本,在一些场景存在性能瓶颈,例如用户主从读写拆散时候会遇到读超时等问题。思考到用户对性能要求较高,同时联合以下技术点,最终举荐用户应用腾讯云 MongoDB-4.0 版本,次要起因如下:

非阻塞从节点读(叮咚买菜遇到的低版本次要问题)

MongoDB-4.x 开始,引入了非阻塞的从节点读(Non-Blocking Secondary Reads),彻底解决了 3.x 版本从节点批量重放 oplog 时候加全局 ParallelBatchWriterMode 类型 MODE_X 锁引起的读从节点读阻塞问题。

存储引擎优化(低版本的次要问题)

相比 3.2 版本,4.0 对存储引擎做了很多优化,例如 cache 脏数据淘汰、锁粒度、更全的引擎参数调整反对等,极大的解决了低版本后盾加索引、大流量读写等引起的客户端拜访阻塞问题。

更好的写性能

相比 3.2 版本,除了下面提到的非阻塞从节点读引起的读性能晋升外,在写性能方面 4.0 也更有劣势。

更多有用新性能

通过几个大版本迭代,4.0 版本相比 3.2 新增了十分多有用性能,例如 Retryable Writes(可重试写)、Change Streams(变更流操作)、Tunable Consistency(更强的可调一致性)、Schema Validation(模式查看)、平安性能加强、事务反对、更丰盛的操作类型等。

分片模式集群扩容 balance 效率更高

4.0 版本相比 3.2 版本,减少分片扩容后的数据迁徙采纳更好的并发迁徙策略,扩容数据迁徙速率更高。

为何不抉择更高的 MongoDB 版本

MongoDB 版本越高性能越多,例如更高版本反对分布式事务、多字段 hash 片建反对等。因为叮咚次要是正本集集群,并且对这些新性能需要不强烈,同时综合集群稳定性思考,最终抉择 4.0 版本。

客户端 driver 版本兼容性,缩小用户客户端革新老本

因为内核版本较低,如果降级到高版本,首先须要思考对应客户端 driver 版本是否兼容低版本 driver。如果客户端版本和内核不兼容,则须要进行 driver 降级甚至代码革新,因而客户端 driver 兼容性也是 MongoDB 内核版本抉择的一个要害指标。叮咚技术团队通过验证,确认客户端版本齐全兼容 4.0 内核,代码无需任何革新。

罕用客户端 driver 与 MongoDB 内核版本兼容性详见:

Driver 类型

官网兼容性阐明

Java

https://docs.mongodb.com/driv…

golang

https://docs.mongodb.com/driv…

php

https://docs.mongodb.com/driv…

其余

https://docs.mongodb.com/driv…

2.2. 平安上云迁徙计划
叮咚自建 MongoDB 集群蕴含局部重要数据,务必保障迁徙的数据一致性。罕用通用迁徙计划如下:

通用迁徙计划

下面的迁徙计划步骤如下:

步骤 1:腾讯云 DTS for MongoDB 全量 + 增量形式实时同步自建数据到云上 MongoDB

步骤 2:抉择凌晨业务低峰期判断 DTS 提早进度,提早追上后,业务停写

步骤 3:确保源集群最初一条 oplog 同步到指标集群,客户端 IP 地址切到指标集群

通过下面的操作步骤,最终实现不同版本的 MongoDB 上云。然而,该上云计划有个危险,假如业务切换到指标新集群后局部读写有问题,这时候就须要回滚到源自建集群。因为切换到新集群过程后,可能局部写流量到了指标集群,这时候指标集群相比源集群就会有更多的数据。这时候,切回到源集群后,也存在数据不统一的状况,即便把指标集群增量 oplog 回写到源集群,也可能存在乱序写入引起的数据凌乱问题。

优化计划

为了解决极其状况下回滚引起的数据失落、数据凌乱、数据不统一等问题,叮咚业务集群采纳如下更加平安可回滚切割计划:

当业务流量从源叮咚自建 MongoDB-3.2 集群切换到腾讯云 MongoDB-4.0 后,如果存在版本兼容、业务拜访异样等问题,则可间接回滚到腾讯云 MongoDB-3.2 版本,因为回滚集群和源自建集群版本统一,并且通过 DTS 实时同步,因而,能够肯定水平保障回滚流程数据不凌乱、不抵触、不失落,也可保障切割出问题时候的疾速回滚。

因为叮咚业务 MongoDB 存储了局部重要数据,不容许数据失落及凌乱,对数据一致性要求极高。以后计划在切换过程中,仍存在向前回滚时数据提早、连贯串更换后利用写错等危险。因而为了确保实时同步及回滚数据一致性十拿九稳,除了 DTS 的回滚计划,叮咚在业务侧减少了几层爱护:通过订阅和扫描,针对外围库的数据进行校验;通过流量检测进行业务反查;如果呈现业务数据不统一,能够通过工具进行可灰度、可控速的形式进行补齐。

3. 叮咚自建 MongoDB 上云遇到的问题及优化解决办法

叮咚不同业务从 3.2 版本上云降级到 4.0 版本过程中,遇到了一些性能瓶颈问题,次要包含以下问题:

腾讯云 MongoDB 短链接性能优化

叮咚业务侧短链接优化

Session 定期刷新引起的集群抖动问题

3.1. 短链接性能优化解决办法
以叮咚集群其中某业务为例,该业务局部接口应用 PHP driver,因而会波及到大量的 MongoDB 短链接拜访,以下别离阐明叮咚自建集群短链接瓶颈优化及腾讯云 MongoDB 短链接优化过程。

3.1.1. PHP 业务短链接瓶颈起因
PHP 一次申请拜访,须要如下交互过程日志如下:

2021-11-04T12:45:36.621+0800 I NETWORK  [conn6] received client metadata from …  
2021-11-04T12:45:36.621+0800 I COMMAND  [conn6] command admin.$cmd command: isMaster …  
2021-11-04T12:45:36.622+0800 I COMMAND  [conn6] command adminxx.users command: saslStart  …  
2021-11-04T12:45:36.626+0800 I COMMAND  [conn6] command admin.$cmd command: saslContinue  …  
2021-11-04T12:45:36.627+0800 I ACCESS   [conn6] Successfully authenticated as principal  …  
2021-11-04T12:45:36.627+0800 I COMMAND  [conn6] command adminxx.users command: saslContinue  
2021-11-04T12:45:36.627+0800 I COMMAND  [conn6] command admin.$cmd command: ping…    
2021-11-04T12:45:36.627+0800 I COMMAND  [conn6] command x.test  command: find { find: "test"  
2021-11-04T12:45:37.636+0800 I NETWORK  [conn6] end connection …

从下面的简化日志能够看出,一次 find 申请预计须要上面多个操作步骤,并且屡次能力实现,次要流程如下:

TCP 三次握手链接

客户端发送 isMaster 命令给服务端获取所连节点的一些状态信息、协定兼容信息等

进行 sasl 屡次认证交互

Ping 探测获取往返时延

真正的业务拜访,例如这里的 find 查问申请

四次挥手敞开本次链接对应申请

下面的流程体现出一次拜访,不仅仅建链、断链开销、还有屡次认证交互以及其余额定交互开销,最终无效拜访只占用极少一部分开销,有效拜访节约了零碎大部分开销。此外,PHP 业务单次访问的总时延减少,单次访问总时延如下:

PHP 单次访问时延 = 建链工夫 +isMaster()交互工夫 + 认证工夫 +ping 工夫 + 数据拜访工夫

3.1.2. 叮咚自建 MongoDB 集群短链接部署优化
该用户集群尽管数据量不是很大,然而流量较高,读写总流量数万 / 秒,如果间接采纳一般正本集模式集群,则存在 MongoDB 存储节点因为短链接流量高引起的负载问题。叮咚自建 MongoDB 为了解决短链接拜访引起的瓶颈问题,采纳如下架构:

上图为某业务集群,业务读写流量较高,总流量数万 /S,其中有一部分 PHP 业务。思考到 PHP 业务短链接每次拜访须要屡次认证交互,会减少 mongo 内核压力,因而用户采纳分片架构集群部署,单个分片。客户端程序和 mongos 部署在同一台服务器,每个客户端通过本地 mongodb:///var/run/mongodb-order.sock/ 拜访,通过该架构来解决短链接带来的性能瓶颈。

3.1.3. 腾讯云 MongoDB 部署架构及优化过程
MongoDB 部署架构

腾讯云 MongoDB 采纳叮咚相似架构,惟一区别是 mongos 代理叮咚部署在客户端机器本地部署,MongoDB 则是独立部署,云上 MongoDB 部署架构如下:

MongoDB 短链接优化

在业务正式上线前,MongoDB 团队对 PHP 短链接进行了提前的摸底测试(后端分片无瓶颈,压一个 mongos),测试后果存在如下景象:

服务器 CPU 闲暇

listener 线程 CPU 耗费较高

短链接并发越高链接报错比例越高。

后端分片 MongoDB 无瓶颈

通过剖析,netstat 查看发现大量的 SYN_RECV、FIN_WAIT 状态的链接,同时客户端大量链接报错,阐明 mongos 代理解决链接不及时,这和 MongoDB 内核网络线程模型有较大的关系,MongoDB 所有客户端申请由 listener 线程进行 accept 解决,accept 获取到一个新链接,则创立一个线程,该线程负责该链接当前的所有数据读写。

一个 mongos 过程只有一个 listener 线程,当客户端链接并发较高的时候,很容易造成链接排队,最终造成客户端链接超时。不过,该瓶颈能够通过部署多个 mongos 来解决,多个 mongos 就会有多个 listener 线程,accept 解决能力就会加强。

最终,综合老本及性能思考,抉择多个最低规格 (2PU/4G) 的 mongos 来解决短链接瓶颈。

除了多 mongos 部署外,还对 MongoDB 内核 listen backlog 队列长度进行了适当的调整,缓解队列满引起的客户端链接异样问题。

net.listenBacklog 配置在 3.6 版本开始反对,调研了罕用服务端中间件 nginx、redis,这类中间件都反对 listen backlog 配置,默认取值别离如下:

Nginx 默认取值:511

Redis 默认取值:511

MongoDB 默认取值:SOMAXCONN

SOMAXCONN 也就是操作系统 /proc/sys/net/core/somaxcon 文件中的值,线上默认取值 128。批改 somaxcon 为 10240,配置 net.listenBacklog 为 511,放弃和 nginx、redis 举荐默认值 511 统一。通过测试,net.listenBacklog 调整后,4C 规格测试,短链接异样超时景象会有较大缓解。

listenBacklog 配置

测试后果

128

2000 并发约 10% 左右申请链接报错

511

2000 并发无任何链接报错

3.2.Session 定期刷新业务抖动优化解决过程
3.2 降级到 4.0 版本上云过程中,除了用户短链接 PHP 瓶颈外,另外一个就是 session 会话定期刷新引起的业务抖动问题。

3.2.1. 业务抖动景象
用户从 3.2 版本升级到腾讯云 4.0 版本后,腾讯云 MongoDB 集群流量监控图如下:

如上图所示,整个景象如下:

update 周期性流量尖刺,尖刺周期 5 分钟

delete 周期性流量尖刺,尖刺周期 30 分钟

流量尖刺过程中,时延也对应减少,周期性抖动

CPU 周期性耗费

3.2.2. 线下模仿测试
当客户端泛滥,连接数过高的状况下,正本集主节点有霎时大量 update 甚至 delete 操作,mongostat 和 mongotop 监控如下(测试条件:500 并发短链 +500 并发长链接,进行 insert 持续性写入测试):

mongostat 监控发现大量未知 update 操作,甚至远超过失常 insert 流量

从下面能够看出,存在大量 update 更新操作,同时该操作类型统计甚至超过失常的 insert 写入。

mongotop 确定流量来自于哪一个表

500 并发短链接及 500 并发长链接同时进行持续性 insert 写入测试,发现 mongostat 监控中存在大量的 update 更新操作,而咱们的测试中没有进行 update 更新操作,于是通过 mongotop 获取 update 操作起源,监控后果入下图所示:

从上图能够看出,大量的 update 操作来自于 config 库的 system.sessions 表,这是一个潜在隐患。

其余潜在隐患(system.sessions 表集中过期)

system.sessions 表默认 30 分钟过期,因为 session 会话数据都是集中刷新到 system.sessions 表,因而该表还存在集中过期的状况,集中过期将让 update 定期更新和过期操作叠加,进一步减轻集群抖动。

3.2.3.session 模块内核实现
从 MongoDB-3.6 版本开始,MongoDB 开始逐渐反对单文档事务,从而开始引入 session 逻辑会话模块。不论是正本集 mongod 还是分片集群的 mongos,都会启动一个定时器刷新 cache 中缓存的 session 信息到 config 库的 system.session 表中。

通过走读 MongoDB 内核代码,确定该问题是对 system.sessions 表做更新引起,内核对应次要代码实现由 LogicalSessionCache 模块负责 session 会话治理操作。上面通过一次残缺的客户端拜访为例,剖析 session 模块外围原理及次要代码实现:

步骤 1:客户端发送 isMaster 命令到服务端,服务端告诉客户端是否反对 session 治理

客户端通过发送 isMaster 命令给服务端,如果服务端反对 session 会话治理模块,则返回 session 会话超时工夫信息给客户端。

步骤 2:客户端申请携带”lsid”信息发送给服务端

服务端收到客户端”lsid”信息后,查看本地 cache 是否有该 session 信息, 如果本地 cache 没有该 session 信息则增加到本地。一个”lsid”代表一个 session 会话信息。

如果业务没有创立 session 信息,则默认对一个链接创立一个会话信息,链接和 session 一一对应。

步骤 3:启动定时器,定期把 cache 中的 session 信息 system.sessions 表中

mongos 和 mongod 实例都会启动一个后盾线程,定期把 cache 中的所有 sessions 信息同步到 config 库的 system.sessions 表中。同步的 session 会话信息能够分为以下两类。

1.activeSessions 沉闷 session

activeSessions 会话信息次要包含一个定时器周期沉闷的 session 信息 (一个定时器周期该 session 对应的客户端有拜访 MongoDB) 和新创建的 session 会话信息。

mongos 或者 mongod 会定期把 activeSessions 信息一条一条一次性 update 到正本集对应 system.sessions 表中。

2.endSessions 会话信息

endsessions 会话信息次要包含客户端显示通过 endSession 命令完结的会话信息和闲暇工夫超过 system.sessions 表对应 TTL 过期工夫的会话信息。

客户端被动触发 endSession 的 session 会话信息,mongos 也是在同一个定时器中通过 remove 操作 system.sessions 表,从而实现 cache 和 system.sessions 表的一致性。Remove 操作和沉闷 session 的 update 操作在同一个定时器实现,update 更新结束后,立马进行 remove 操作。

如果是短链接,并且敞开链接前被动进行了 endSession 完结会话操作,正本集可能还存在 system.sessions 表大量 remove 的操作。

如果 session 长时间闲暇,则通过 system.sessions 表的 TTL 索引来触发本地 cache 的清理工作。

定时器相干

定时器默认定时工夫 5 分钟,能够通过 logicalSessionRefreshMillis 配置。

System.sessions 表 TTL 过期工夫

默认 30 分钟过期。

会话统计信息

会话统计信息通过“db.serverStatus().logicalSessionRecordCache”命令获取,如下图所示:

logicalSessionRecordCache 统计中,能够分为两类:session 类统计和 transaction 事务类统计,外围统计项性能阐明如下:

统计类型

统计项

统计内容阐明

Session 统计

activeSessionsCount

以后沉闷会话数

lastSessionsCollectionJobEntriesRefreshed

上一个周期刷新到 system.session 表的沉闷会话数

lastSessionsCollectionJobEntriesEnded

上一个周期刷新到 system.session 表的 endSessions 会话数

lastSessionsCollectionJobCursorsClosed

上一个周期内清理的

Transaction 统计

lastTransactionReaperJobEntriesCleanedUp

本周期内清理的 transactions 表数据条数

3.2.4. Session 问题 MongoDB 内核优化解决
从下面的原理能够看出,业务抖动次要因为 cache 中的 session 定期集中式刷新,以分片 MongoDB 集群为例,内核层面能够通过以下形式优化缓解、也能够通过减少内核配置开关躲避。

无 MongoDB 内核开发能力:参数调优、部署优化

如果没有 MongoDB 内核开发能力,能够通过以下办法进行 session 内核参数调优和部署形式调整来缓解问题:

办法一:mongos 及正本集 mongod 部署工夫打散,防止所有节点定时器同时失效

以后集群默认启动后,所有代理和 mongod 简直都是同时启动的,代理启动时差较小,session 定时器可能同一时间触发,能够手动打散到不同工夫点重启,包含所有 mongos 和正本集 mongod。

办法二:短链接业务思考定时刷新周期适当调短

短链接默认每次申请会生成一个 session 会话,拜访结束后不会被动告诉 MongoDB 内核开释 session,因而,session 在定时周期内会大量挤压,能够思考缩短定时工夫来躲避大量短连贯 session 的定期刷新操作。例如 logicalSessionRefreshMillis 从默认 5 分钟调整为 30 秒,则集中式的 session 刷新会散列到多个不同工夫点。

办法三:长链接业务适当调大定时刷新周期

理论测试验证中,默认官网 driver 长链接 (包含 golang、java、c 客户端测试验证) 都是一个链接对应一个 session 会话 id,也就是同一个申请客户端携带的”lsid”放弃不变。MongoDB 内核实现中,只有每一个链接对应的定时周期内有一次以上沉闷申请拜访,则会再次缓存该 session id,session id 刷新到 config.sessions 表中后,cache 中会革除。

从下面的长链接 session cache 流程能够看出,个别长链接用户都是连接池配置,总连接数越高 session 也会越高。因而长链接能够通过以下调整缩小 session 定期刷新的影响:

管制连接池最大连接数,缩小 cache 中的 session 总量

适当调大 logicalSessionRefreshMillis 刷新周期,缩小频繁刷新的影响

内核减少禁用 session 会话性能开关

在 3.6 以下版本,MongoDB 是没有 session 会话治理模块的,为了反对事务和可重试写性能而引入。

剖析了 MongoDB-c-driver 客户端,发现客户端第一次报文交互是否携带“lsid”给服务端是依据 isMaster 的返回内容中是否携带由”logicalSessionTimeoutMinutes”来决定的,如下:

实际上用户从 MongoDB-3.2 版本升级到 4.0,用户也不须要事务、可重试写性能,客户端齐全没必要默认走 session id 生成流程。如果客户端不触发 session id(也就是报文交互中的”lsid”),则就不会触发 Mongo 服务端内核启用 session 定期刷新功能模块。因而,能够思考在 MongoDB 内核代码实现中,客户端 isMaster 获取相干信息的时候,不返回“logicalSessionTimeoutMinutes”信息,这样客户端就不会生成”lsid”信息发送给服务端。

4.0 官网代码默认写死,MongoDB 内核实现减少 session 模块反对开关,如果业务没有事务等需要,内核不应答“logicalSessionTimeoutMinutes”信息给客户端,这样客户端认为服务端不反对该性能,就不会被动生成 session id 交互。

阐明:session 会话模块性能开关反对,以后已验证 c driver、java、php,测试验证 session 问题彻底解决,应用该性能切记对客户端进行提前验证,可能不同客户端对 logicalSessionTimeoutMinutes 解决逻辑不统一,特地是应用 spring+MongoDB 整合的客户端。

3.2.5. 叮咚长链接 session 问题用户侧优化
叮咚用户某长链接通过腾讯云 MongoDB 提供的节点地址本人对集群也做了具体的流量监控,监控曲线如下图所示:

在对该长链接用户进行 MongoDB 内核优化前,能够看出流量周期性尖刺,并且发现一个归类:随着该 java 长链接流量 qps 越高,定期的 sessionupdate 尖刺越重大。

利用线上 MongoDB 进行复现,应用 MongoDB 官网 java driver 测试后果和之前的长链接剖析统一,也就是一个链接一个 session 会话,也就是 java 服务定期最大的 session update 不会超过总连接数。然而叮咚用户的 java 服务通过 MongoDB 内核日志,看到如下景象:

Thu Sep  2 18:07:19.833 I COMMAND  [conn48527] command xx.xxx command: insert {insert: "xx", ordered: true, $db: "xx", $clusterTime: { clusterTime: Timestamp(1630577239, 387), signature: {hash: BinData(0, B37C8600CE543BEE2D8085730AADD91CB13C14AF), keyId: 7002593870005403649 } }, lsid: {id: UUID("3ce872be-5a8d-4a1b-b656-8ba33b3cb15d") } } ninserted:1 keysInserted:2 numYields:0 reslen:230 locks:{Global: { acquireCount: { r: 2, w: 2} }, Database: {acquireCount: { w: 2} }, Collection: {acquireCount: { w: 1} }, oplog: {acquireCount: { w: 1} } } protocol:op_msg 0ms  
Thu Sep  2 18:07:19.921 D COMMAND  [conn48527] run command xx.$cmd {insert: "xxxx", ordered: true, $db: "xxx", $clusterTime: { clusterTime: Timestamp(1630577239, 429), signature: {hash: BinData(0, B37C8600CE543BEE2D8085730AADD91CB13C14AF), keyId: 7002593870005403649 } }, lsid: {id: UUID("ab3e1cb8-1ba1-4e03-bf48-c388f5fc49d1") } }  
Thu Sep  2 18:07:19.922 I COMMAND  [conn48527] command xxx.xxx command: insert {insert: "oxxx", ordered: true, $db: "maicai", $clusterTime: { clusterTime: Timestamp(1630577239, 429), signature: {hash: BinData(0, B37C8600CE543BEE2D8085730AADD91CB13C14AF), keyId: 7002593870005403649 } }, lsid: {id: UUID("ab3e1cb8-1ba1-4e03-bf48-c388f5fc49d1") } } ninserted:1 keysInserted:2 numYields:0 reslen:230 locks:{Global: { acquireCount: { r: 2, w: 2} }, Database: {acquireCount: { w: 2} }, Collection: {acquireCount: { w: 1} }, oplog: {acquireCount: { w: 1} } } protocol:op_msg 0ms  
Thu Sep  2 18:07:19.765 I COMMAND  [conn48527] command xxx.xxx command: find {find: "xxx", filter: { status: { $in: [ 1, 2, 4, 5, 9, 11, 13, 3, 7, 15] }, order_number: "xxxxxxxxxxxxxxxxxxx", is_del: false }, sort: {_id: -1}, $db: "xxx", $clusterTime: {clusterTime: Timestamp(1630577239, 375), signature: {hash: BinData(0, B37C8600CE543BEE2D8085730AADD91CB13C14AF), keyId: 7002593870005403649 } }, lsid: {id: UUID("ed1f0fd8-c09c-420a-8a96-10dfe8ddb454") } } planSummary: IXSCAN {order_number: 1} keysExamined:8 docsExamined:8 hasSortStage:1 cursorExhausted:1 numYields:0 nreturned:4 reslen:812 locks:{Global: { acquireCount: { r: 1} }, Database: {acquireCount: { r: 1} }, Collection: {acquireCount: { r: 1} } } protocol:op_msg 0ms  

从下面的日志能够看出,即便是同一个长链接下面的屡次会话,客户端也会携带多个不同的”lsid”发送给 MongoDB 服务端,因而须要解决为何 java 服务同一个链接屡次拜访会生成多个 session id,即”lsid”。

通过排查客户端,最终定位问题是客户端的埋点监控在降级到 MongoDB-4.0 后,触发每次申请生成一个新的”lsid”。

4. 叮咚买菜自建上云收益总结

自建 MongoDB 迁徙腾讯云 MongoDB 后,带来了如下收益:

通过梳理拆分,把一些外围的简单的 MongoDB 集群,垂直拆分为多个集群,耦合性升高,稳定性进步

集群稳定性进步,上云前业务遇到的各种 MongoDB 拜访毛刺和抖动问题失去了彻底解决

腾讯云 MongoDB 相比自建 MongoDB 性能更好,并可能充分利用云的弹性扩容能力,不必预留过多的硬件资源,从而节俭了较大老本

腾讯云 MongoDB 欠缺的监控告警、数据备份回档、跨地区容灾、实时巡检、7×24 小时在线服务等,使得可运维性、数据安全、故障预发现等能力得以加强

迁徙到腾讯云,也能够利用腾讯云技术团队的技术劣势,帮忙剖析定位解决一些 MongoDB 深层次的疑难技术问题

对于作者
叮咚买菜技术团队:

叮咚买菜根底技术,撑持叮咚买菜外围业务的资源、数据、基础架构,是一支技术背景深厚、充斥激情与现实、保持同指标共进退,打胜仗的团队。尤其器重技术人才培养和倒退成长,很多技术骨干都是外部成长倒退起来的。

腾讯云 MongoDB 团队:

腾讯云 MongoDB 以后服务于游戏、电商、社交、教育、新闻资讯、金融、物联网、软件服务等多个行业;MongoDB 团队 (简称 CMongo) 致力于对开源 MongoDB 内核进行深度钻研及持续性优化(如百万库表、物理备份、免密、审计等),为用户提供高性能、低成本、高可用性的平安数据库存储服务。后续继续分享 MongoDB 在腾讯外部及内部的典型利用场景、踩坑案例、性能优化、内核模块化剖析。

正文完
 0