Skip to main content

Command Palette

Search for a command to run...

对mongo分片集群创建索引

Updated
1 min read

1. 场景

现在我们需要给大规模的mongodb集群添加索引,当集群规模巨大的时候,创建索引是一个非常可怕的操作,因为一个索引的创建的过程非常长,因为即使是稀疏索引也是需要遍历现存的所有数据的才能完成的,而且创建索引时间比较漫长的,可能在中间出现创建索引的节点宕机什么的问题;而且创建索引本身是不一个不可逆的过程,创建完之后马上删除索引是会出现很严重的问题;为此对于这个场景我们需要思考更加多一些;

2. 方案

mongo的集群模式包含有mongos + mongod replication,创建索引肯定不能直接从mongos下发,虽然从理论上可行,但是如果出现其他的没有考虑的情况的话,到时候影响面就会很巨大的;所以我们的方案基本上是这样的:

1. 一组一组shard进行创建索引的; 将db对应的primaryId对应shard放在最后去创建索引;
2. 全部完成之后再在mongos在统一创建索引;
真实创建索引是在mongod段的,所以mongos最后的创建索引是不会有任何影响,并且不会有副作用的;

2.1 知识点: 每一个db都会存在一个primary节点

在做实验的过程中,上面的第一步做完之后,从mongos段能通过getIndexes这个函数看到对应的索引,这非常奇怪,因为我本身没有对mongos进行索引创建的;最终在分析mongos的也源码发现,发现这个索引信息是去db的PrimaryId对应的shard上获得的,这个primaryId的信息要如何获得呢?

use config
db.databases.find()
//结果
{ "_id" : "test_LCC", "primary" : "shard1", "partitioned" : true }
{ "_id" : "exporter", "primary" : "shard2", "partitioned" : true }

结论: 只要对primaryId的shard创建了索引,那么mongos就能看到对应的索引;所以在创建索引的时候需要将其放在最后来创建索引,主要是为了安全性,怕遇到未知的行为;

2.2 扩容集群是否需要手动创建索引

测试结果是不需要,因为当进行movechunk的时候,mongodb会创建对应的db/coll/对应的索引

3. 预案

目前主要集中在副本集内部的创建索引的故障的场景预案上;

3.1 primary在创建索引的时候挂了怎么办

目前mongodb 副本集创建索引是primary先完成,然后secondary会并发创建索引的; 所以在当前场景下,primary挂了就切主,新的primary理论上不会知道要创建索引,而老的primary会重启然后开始恢复创建索引的进度,并且不会启动端口提供服务; 所以针对这个场景的步骤:

1. 观察新的primary是否能提供正常的服务; 
2. 观察老的primary重启之后是不是在进行索引恢复过程中; 关键字为:"Index Build" 会出现类似的"Index Build (background): 235900/319691570 0%" 如果这个日志滚动中那么表示节点正在创建索引;
3. 等到老的primary创建索引成功之后,关键字为:"build index done",会有类似的日志:"build index done. scanned 324427514 total records. 4909 secs" 
4. 如果老的primary创建成功之后,先去新的primary查看对应的collection是否有创建索引,正常情况是不会有的;这个时候把之前创建索引的语句在新primary重新执行
5. 观察服务的稳定性吧
3.2 primary创建成功之后,secondary并行创建过程中宕机

关于这个场景需要分开两种情况来聊:

  • secondary宕机不影响majority写 ```
  • 重启secondary观察创建索引的进度即可; ```
  • 多个secondary出现宕机开始影响到majority写的时候 ```
  • 关闭正在恢复索引的secondary
  • 启动参数加入"--noIndexBuildRetry",这样让secondary忽略恢复索引的过程的;直接起来提供服务
  • 等整个副本集对外写入稳定的时候,这个时候可能的情况是集群内部有几个节点存在索引,有几个节点没有的;
  • 在保证副本集副本数安装的情况下,找一个有索引的副本进行锁库,然后将数据同步给其他的没有索引的节点,
  • 数据同步完之后,启动;
  • 最后要将"--noIndexBuildRetry"参数删除掉
    ##### 3.3 primary 创建索引过程中,性能影响很大的
    
  • 切主,将主迁移到其他的节点上
  • 找研发讨论后期应该如何处理
    ##### 3.4 primary创建成功,但是secondary并行创建的性能抖动很大的
    
  • 选择几个secondary节点,修改启动参数,加入"--noIndexBuildRetry",然后重启;保证不会对写入有影响
  • 保留一个或者多个节点进行索引创建
  • 创建成功之后,通过数据copy的方式来让那些没有索引的节点也有索引 ```

More from this blog

Ai时代的工具链

本周是black Friday,我订阅了几个AI服务,还是蛮贵的...不过这样基本上构成我目前整体的知识阅读的过程,随着Ai的不断发展,工具链的替换可能是很重要的一个过程的。我主要订购了以下几个工具: Memo: 这个工具的主要作用是将视频/audio转srt,并且带有ai翻译的工具;当然我觉得它做的非常好的是,它把整个链路做的非常好的,并且可以用本地的资源做audio->text;而且它自带了很多的ai功能,比如对字幕进行进一步的AI的处理,提问,summarize和思维导图等等;目前我主要...

Nov 30, 20251 min read

做了一个噩梦

今天凌晨4点多起来看了一眼丈母娘的发烧是否ok...就导致我有点睡不着的,刷了一会推特之后又开始睡觉了,于是就开始做了一个很可怕的梦。 噩梦 那天,我不知道是在哪里..我带着女儿和我弟出去玩的,貌似是一个风景山区。于是我就带着女儿和弟弟出去玩的;我们走啊走, 沿着一条路一直走..突然看到一个小道有一家饭店的,这个饭店是比较特殊,有很多海鲜的;我看上了一只大龙虾,我问多少钱的,他说大概就70rmb就可以的。。。我觉得很划算的,我心想:我买下来,到时候把老婆叫过来一起吃的,并且告诉她这个才70rmb...

Nov 24, 20251 min read

子女教育-2

下面我分享一个推特上的一个关于子女教育的推 哈哈哈哈,李诞这个视频我看过 我给你分享几个我和我女儿之间的小故事 第一个故事 我经常给小朋友说:你们现在上学的成绩不重要,你们现在数学考试都是语文脑筋急转弯,语文考试都是历史背诵,一点用都没有,你出了社会就知道,社会根本没有选择题,社会要有选择题就好了,最难的是你遇到困难,你连门都找不到。我第一次这样讲的时候是女儿小学4年级,那时候我女儿听的一愣一愣的,她不明白,但是觉得我的理论和学校的不一样,很狂妄,但是她很喜欢,哈哈哈哈。 她什么时候真正明...

Nov 13, 20251 min read

被诈骗-马来西亚

最近我在国内,我老婆在马来;最近在计划搬家的,找的那个房子不包含一些必要的家具,于是我老婆就必须要买点家具的,主要是沙发和餐桌..我们本来计划是说去ikea去买,但是我老婆觉得ikea的家具不便宜,并且款式一般的,最终问了中介找了一个二手平台找找看不错的家具。 我老婆挑了两个家具的,我看了一下价格也不算便宜的,但是我老婆喜欢的,于是我就说你觉得ok那就购买吧。我还顺便问了一下,这个家具能不能线下看一下货的,但是我老婆说这货在很远的地方的,大概是300公里的一个城市的。那我就说这个包邮吗,我老婆说...

Nov 13, 20251 min read

当下和最近想做的事情

1. Current 当下 最近依然还在中国,已经回来快一个月了. 最近一直在忙着带丈母娘看病和住院的。索性一切都还在可控范围内的,丈母娘由于糖尿病控制的很差导致本身的冠心病也复发. 这次去浙江省人民医院去做了造影检查和支架植入的手术的,不过这一切都比我预估的要顺利,我就怕她由于长时间没吃药和高血糖的持续的时间太长了,会带来严重的问题,不过好在没有发生最坏的事情的。 因为做了手术,所以这段时间我和我老婆的姐姐每人轮换的陪床,不过陪床真的好累的,因为睡得很不好的,特别的累。不过好在都结束了,而且丈...

Nov 9, 20251 min read

Keep Move - 永不止步

39 posts