写点什么

叮咚买菜自建 MongoDB 上云实践

  • 2021 年 12 月 22 日
  • 本文字数:9682 字

    阅读完需:约 32 分钟

叮咚买菜自建MongoDB上云实践

图片随着近年来公有云技术及云基础设施的发展,越来越多的企业转为使用公有云来托管自己的服务。云数据库因为数据可靠性、资源弹性、运维便捷行,云上数据库服务也正成为企业数据管理的较好的选择。


本文以叮咚买菜自建 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/drivers/java/sync/v4.3/compatibility/


golang


https://docs.mongodb.com/drivers/go/current/compatibility/


php


https://docs.mongodb.com/drivers/php/


其他


https://docs.mongodb.com/drivers/


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, 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, 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 完善的监控告警、数据备份回档、跨地域容灾、实时巡检、7x24 小时在线服务等,使得可运维性、数据安全、故障预发现等能力得以增强


迁移到腾讯云,也可以利用腾讯云技术团队的技术优势,帮助分析定位解决一些 MongoDB 深层次的疑难技术问题


关于作者

叮咚买菜技术团队:


叮咚买菜基础技术,支撑叮咚买菜核心业务的资源、数据、基础架构,是一支技术背景深厚、充满激情与理想、坚持同目标共进退,打胜仗的团队。尤其重视技术人才培养和发展成长,很多技术骨干都是内部成长发展起来的。


腾讯云 MongoDB 团队:


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

用户头像

还未添加个人签名 2019.07.27 加入

还未添加个人简介

评论

发布
暂无评论
叮咚买菜自建MongoDB上云实践