2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

这 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:001387

评论

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

精妙绝伦!10年阿里工作经验总结出这份亿级高并发系统设计手册,真的太强了!

退休的汤姆

Java、 面经 社招 Java工程师 秋招

字节内部MySQL宝典意外流出!堪称数据库的天花板

退休的汤姆

Java、 面经 Java工程师 秋招 MySQL 数据库

创建第一个 Cypress 应用后使用命令行 npx Cypress open 报错的原因分析

汪子熙

前端开发 自动化测试 Cypress web开发 8月月更

封仲淹:OceanBase社区版4.0未来畅想

OceanBase 数据库

ModelBox开发体验:使用YOLOv3做口罩检测

华为云开发者联盟

人工智能 ModelBox

SAP Fiori Launchpad Tile,UI5 应用,和 PFCG Role 的对应关系

汪子熙

SAP Fiori Launchpad ui5 8月月更

SAP AMDP 介绍 - ABAP 托管的 HANA 数据库过程

汪子熙

数据库 SAP abap 8月月更 AMDP

云原生数据库白皮书,发布!

华为云开发者联盟

数据库 云原生 后端 华为云 白皮书

为什么 DevOps 会失败?

飞算JavaAI开发助手

从InfluxDB到TDengine,阳光氢能为什么会做出这个选择?

TDengine

数据库 tdengine 时序数据库

Spring Security + Vue + Flowable 怎么玩?

江南一点雨

Java spring springsecurity flowable

产品和管理必备技能 Top 5

宇宙之一粟

产品 领导力 8月月更

开源一夏 | STM32对接涂鸦wifi模块项目(智能插座-开源)

矜辰所致

开源 stm32 WiFi物联网智能插座 8月月更 涂鸦智能

【LeetCode】合并区间Java题解

Albert

LeetCode 8月月更

芯声智能亮相亚洲智能穿戴展,智能头盔声学方案为骑手保驾护航

硬科技星球

企业如何将自身的数字技术及研究成果快速对外发布应用

ModelWhale

数字化转型 部署 应用模型 对外接口 协同开发

如何做好分支管理,保证高效CI/CD?

华为云开发者联盟

git 开发

使用 OpenTelemetry 零代码修改接收 SkyWalking 追踪数据

Daocloud 道客

云原生 可观测性 Skywalking OpenTelemetry

J2EE进阶(三)struts2 <s:action>标签的用法及Spring在web.xml中的配置

No Silver Bullet

spring Struts2 8月月更 <s:action>

开源一夏 | 如何在 JavaScript 中创建虚拟键盘

海拥(haiyong.site)

JavaScript 开源 前端 8月月更

即时通讯安全篇(十):IM聊天系统安全手段之通信连接层加密技术

JackJiang

网络安全 https 网络编程 即时通讯 SSL/TLS

企业数字化转型,如何实现业务部门与算法部门共同探索模型开发优化

ModelWhale

数据分析 工作流 数字化转型 业务思维 协同开发

企业引进外部专家合作开发时,如何保证数字资产既开放又安全?

ModelWhale

数字化转型 数据安全 资产安全 技术专家 协同开发

【有奖评测局】阿里云容器镜像 ACR 测评团限时招募中!

阿里巴巴中间件

阿里云 云原生 容器镜像

MSE 费芮新金融行业标杆案例

阿里巴巴中间件

阿里云 微服务 云原生

ArkID 企业级开源 IDaaS/IAM 统一身份认证授权管理解决方案

龙归科技

开源项目 iam SSO Idaas

「数澈软件」获5300万元种子轮融资,构建新一代软件供应链防火墙

SEAL安全

软件供应链安全

2022 OceanBase数据库大赛开启,30W奖金等你来拿!

OceanBase 数据库

Go-Excelize API源码阅读(十七)——GetPageLayout、SetPageMargins

Regan Yue

Go 开源 源码解析 8月日更 8月月更

企业如何跨部门实现模型应用全生命周期管理

ModelWhale

数字化转型 应用模型 迭代管理 跨部门沟通 算法模型

阿里云 EMAS Serverless 重磅发布

hum建应用专家

云原生

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