写点什么

这 300 条数据变更,引发了十亿级核心集群的罢工惨案!

  • 2021-06-30
  • 本文字数:2406 字

    阅读完需:约 8 分钟

这300条数据变更,引发了十亿级核心集群的罢工惨案!

线上某核心 mongodb 集群数据量很少,单表数据量十亿级,但是该集群比较核心,影响公司收入流水。本文通过分享本次踩坑来分享整个故障经过,该故障为一次经典的 mongodb 分片 sharding 集群踩坑故障,包括变更通知不到位、部署架构不到位、变更考虑不仔细等。

一、问题背景

某核心 mongodb 历史集群(入职前就有的一个集群),在对现在所有 mongodb 集群进行风险梳理过程中,发现该集群存在一些潜在的集群抖动风险,该集群架构及流量时延曲线如下:





如上图所示,该分片集群由 3 个分片组成,集群读写流量很低,峰值 QPS 约 4-6W/s,平均时延 1ms,每个分片采用 mongodb 复制集架构实现高可用。通过巡检发现该集群存在如下几个问题:


  • 该集群只包含两个用户库,userbucket 库和 feeds_content 库,两个库中只有 feeds_xxxxxxx.collection1 启用了分片功能;第一个 userbucket 库存储集群路由信息,第二个 feeds_xxxxxxx 库存储约十亿数据信息;

  • 由于该集群主要是读多写少集群,读流量都是读取 feeds_xxxxxxx 库中的数据,并且客户端做了读写分离,所以几乎大部分读流量都在分片 1。分片 2 和分片 3 只有少量数据。


库表信息如下表所示:


库名

表名

功能说明

userbucket

whitexxx/expxxx

用户路由信息表,约300条数据。用户访问feeds_xxxxxxx库前必须先获取该表得用户路由数据




feeds_xxxxxxx

feeds_xxx_pool

十亿级数据,未启用分片

hardware_xxx_cost

未启用分片,少量数据

news_xxx_profile

数亿数据,未启用分片

resource_xxx_info

数千万数据,启用分片

resource_xxx_info

未启用分片,数亿数据

resource_xxx_info

未启用分片,数亿数据

......

......


上面的描述可以总结为下图:



从上图可以看出,分片 2 和分片 3 几乎没起到任何作用;由于分片 3 有两个节点为低 IO 的 sata 盘,可能影响 userbucket 库的读写,因此考虑直接 removeShard 从集群中剔除分片 3 和分片 2。

二、操作过程

由于分片 3 为低 IO 服务器,有潜在抖动集群抖动分享;同时分片 2 和分片 3 几乎都是浪费的分片,因此打散直接通过如下 removeshad 命令删除分片 3 和分片 2 信息,腾出无用服务器资源,如下图所示:



  • 步骤 1:登陆任一一个代理,假设是代理 mongos1。

  • 步骤 2:由于分片 3(也就是 shard_8D5370B4 分片)为 userbucket 库的主分片,因此报错了,提示"you need to drop or movePrimary these databases",意思是我们需要提前把该库的主分片信息迁移到其他分片。

  • 步骤 3:通过 movePrimary 命令把 userbucket 库的主分片从分片 3 迁移到分片 1。

  • 步骤 4:登陆监控列表中的其他两个代理 mongos2、mongos3,通过 db.adminCommand({"flushRouterConfig":1}) 强制刷新路由信息。


注意事项:由于 movePrimary 过程,其他代理不会感知到该库的主分片变化,因此需要强制刷新路由信息或者重启其他节点的 mongos,参考如下:


三、用户反馈大部分请求业务请求不可用

对含有 300 条数据的 userbucket 库变更后,当我还在若无其事的处理其他集群性能调优的时候,用户突然反馈该核心集群部分访问不可用(注意:是整个 10 亿级表部分访问不可用,不仅仅是变更的 300 条数据访问不可用)。


收到电话后很突然,和业务人员详细对接后可以基本上确定是因为这 300 条数据变更引起。业务获取这 300 条数据的时候,部分请求获取成功,部分请求获取失败,说明肯定和 movePrimary 有关系。


于是,除了对监控列表中的所有代理做 flushRouterConfig 强制路由刷新外,还重启了所有的代理,但是业务反馈,还是有部分请求获取不到数据。比较棘手,我自己通过所有的 mongos 代理查看 userbucket 库下面的 300 条数据,完全可以获取到数据。


于是怀疑是不是还有未刷新路由的 mongos 代理,于是登陆任一 mongos 代理获取 config.mongos 表,查看结果如下:



上面的 config.mongos 表记录了该集群所有的代理信息,同时记录了这些代理和集群最后一次 ping 通信的详细时间信息。很明显,该表中记录的代理原不止集群监控列表中的代理个数,比监控列表中的个数要多。


最终,把 config.mongos 表中罗列的当前在线的所有代理强制通过 flushRouterConfig 刷新路由后,业务恢复。

四、问题总结

通过前面的分析可以得出,由于早期集群监控中漏掉了部分代理,造成这部分代理对应的 userbucket 路由信息是 movePrimary 前的路由信息,也就是指向了错误的分片,因此出现了路由不到数据的情况,如下图所示:



  • 为何用户 userbucket 库对应表中数据有的成功有的失败?

因为部分代理在 moveprimary 后,没有强制刷新该表路由信息,造成部分代理路由获取数据的时候路由错误。


  • 为何该 300 条数据部分路由信息错误会造成整个 10 亿集群部分访问不可用?

和业务实现逻辑有关系,因为业务在获取这 10 亿条数据前首先需要获取业务的路由信息,刚好业务路由信息存在了 userbucket 库对应表中,业务在获取数据前必须要获取到业务的路由信息数据,如果 userbucket 数据获取不到,用户就无法确定指向 feeds_xxxxxxx 数据。


  • 为何会遗漏部分代理重启或者强制路由刷新?

历史原因,造成部分代理业务代码有配置,但是服务端集群监控元数据遗漏了,也就是服务端集群监控漏掉了部分代理,这部分代理没有监控起来。也有可能是 mongos 代理扩容,但是集群监控列表中没有加入元数据。


  • movePrimary 操作最安全的操作方法?

官方建议 movePrimary 操作成功后需要强制路由刷新或者重启 mongos,但是 movePrimary 操作成功和 mongos 重启这个过程中有个中间状态,如果中间状态业务读或者些该迁移的库下面的表,还是可能路由错误。


因此,最佳安全的 moveprimary 可以通过如下两个方法操作:


方法一:shutdown 所有代理,只留下一个代理,等该代理 moveprimary 成功后在重启其他 mongos 代理。切记别遗漏代理,出现本文踩坑类似情况,提前检查 config.mongos 表。


方法二:如果某些库的主分片在需要 removeShard 下掉的分片的时候,对该库的表启用分片功能,启用分片功能后会有 chunk 信息,当 removeShard 某个分片的时候会自动迁移该分片的 chunk 到其他分片,整个过程可以保证所有代理获取最新最完整的路由信息(所有代理通过 chunk version 版本管理机制来实时更新最新的路由信息)。


作者介绍

杨亚洲,前滴滴出行专家工程师,现任 OPPO 文档数据库 mongodb 负责人,负责数万亿级数据量文档数据库 mongodb 内核研发、性能优化及运维工作,一直专注于分布式缓存、高性能服务端、数据库、中间件等相关研发。后续持续分享《MongoDB 内核源码设计、性能优化、最佳运维实践》,Github 账号地址:https://github.com/y123456yz


本文转载自:dbaplus 社群(ID:dbaplus)

原文链接:这300条数据变更,引发了十亿级核心集群的罢工惨案!

2021-06-30 08:001278

评论

发布
暂无评论
发现更多内容

Apache APISIX Summit ASIA 2022——5月20日开启开源生态探索之旅

API7.ai 技术团队

网关 API网关 APISIX 开源生态 summit

基于SpringBoot2+redis+Vue商管系统,秒杀等,可二次开发接私活

Java架构追梦

Java spring 后端开发

已开源!分发业务看过来【跨端动态模板引擎】

阿里巴巴文娱技术

ios android 开源 开发工具 移动开发

国产ETL自动化运维调度工具 TASKCTL 控制容器概述

敏捷调度TASKCTL

大数据 DevOps 分布式 自动化运维 Kafka ETL

知乎疯传3W次,堪称最强Java面试题,顺利拿下京东T5的35K*16 薪 Offer...

Java架构追梦

程序员 java面试 offer 后端开发

华为云持续快速增长,IaaS市场排名中国第二、全球第五

科技热闻

蒙牛乳业加入星策开源社区,携手推动企业智能化转型建设

星策开源社区

人工智能 机器学习 企业数智化 智能化转型

netty系列之:可能有人听过ThreadLocal,但一定没人听过ThreadLocal对象池

程序那些事

Java Netty 程序那些事 4月月更

KMRE 再升级!你们想要的功能它来了~

优麒麟

开源 软件 安卓 优麒麟 KMRE

蚂蚁三面被挂,幸获内推,历经5轮终于拿到口碑offer

Java架构追梦

java面试 后端开发 程序员面试 大厂Offer

百度ToB垂类账号权限平台的设计与实践

百度开发者中心

已开源,就等你来!优酷动态模板研发体系为分发提效30%!

阿里巴巴文娱技术

开源 前端 开发工具 移动开发 开发框架

【架构视角】一篇文章带你彻底吃透Spring

潘大壮

spring 后端 springboot 后端开发

划重点,2022 常见的面试题和八股文都为大家总结出来了

Java架构追梦

程序员 java面试 后端开发 Java面试八股文

没想到我也可以入职阿里,两年CRUD,二本毕业,备战两个月面试阿里,侥幸拿下offer定

Java架构追梦

Java 程序员 后端开发

【高并发】如何使用互斥锁解决多线程的原子性问题?这次终于明白了!

冰河

并发编程 多线程 协程 异步编程 精通高并发系列

大数据培训Spark SQL知识点与实战分析

@零度

spark 大数据开发

恒源云(Gpushare)_VSA:一个可变形尺寸窗口自注意力模型

恒源云

深度学习 GPU算力

华为云持续快速增长 践行“深耕数字化,一切皆服务”

科技热闻

字节”再次起跳!内部651页剖析HotSpot 源码手册,GitHub开源

Java架构追梦

Java 程序员 后端开发 字节

原生JavaScript灵魂拷问(二),你能全部答对吗?

战场小包

JavaScript 前端 4月月更

总结JAVA全栈知识点,七面阿里成功斩获P8Offer

Java架构追梦

程序员 java面试 后端开发

【三级等保】三级等保办理流程经验大分享

行云管家

网络安全 等保 等级保护 等保三级 等保2.0

【堡垒机】2022年网络安全堡垒机厂商排名看这里!

行云管家

网络安全 堡垒机 移动云 网络安全堡垒机

浅谈小程序开源业务架构建设之路

百度开发者中心

恒源云(Gpushare)_社区小伙伴的技术小闲谈

恒源云

深度学习 算法

三生万物,万企明道|明道云发布三周年

明道云

我以为自己MySQL够牛逼了,直到看到了Alibaba的面试题,是我不配了。。

Java架构追梦

Java 后端开发 MySQL 运维 程序员面试

神秘男嘉宾登场,引爆全场灯光?

龙智—DevSecOps解决方案

Atlassian Confluence confluence插件

OneFlow学习笔记:从OpExprInterpreter到OpKernel

OneFlow

数据结构 学习笔记 虚拟机 代码 oneflow

这300条数据变更,引发了十亿级核心集群的罢工惨案!_大数据_dbaplus社群_InfoQ精选文章