开发者社区> 张友东(林青)> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

大量的集合为何导致Secondary无法同步?

简介:
+关注继续查看

最近遇到一个user case,因为集合数量太多,导致Secondary节点无法进行initial sync(主备同步的第一步,可理解为从Primary上全量拷贝数据)。

副本集使用wiredtiger存储引擎,一共60,000+集合,平均每个集合4个索引,wiredtiger的集合及每个索引都对应一个单独的文件来存储,数据目录下总共300,000+文件,listDatabases命令执行时,会遍历所有DB的每个集合,获取集合及其索引文件占用的存储空间信息,实现类似如下的伪代码。

listDatabases() {
    dbNames = getAllDatabaseNames();
    for db in dbNames {
        sizeOnDisk = 0;
        for coll in db.getAllColletions() {
                size += coll.size();
                for index in coll.getAllIndexes() {
                    size += index.size();
                }    
        }
        addToOutput(db, size);
    }       
}

使用wiredtiger引擎时,获取集合及索引文件大小信息时,需要打开一个特殊的cursor来读取,整个listDatabases需要遍历300,000+个文件来逐个获取大小信息,导致整个命令的执行开销很大,总耗时在30s以上。

Secondary在执行initial sync时,其过程类似如下

  1. 删除本地除local外的所有数据库
  2. 执行listDatabases命令,获取同步源上所有DB的列表
  3. 针对每个DB,调用listCollections获取所有集合信息,并遍历所有集合,同步集合内的文档并建立索引。
  4. ......

initial sync执行时,设置了socket timeout为30s,而listDatabases的执行时间是超过30s的,导致同步在listDatabases时就一直超时失败,10次重试后仍然失败,Secondary进程就直接退出了。

2016-06-27T20:59:46.494+0800 I REPL     [rsSync] ******
2016-06-27T20:59:46.495+0800 I REPL     [rsSync] initial sync pending
2016-06-27T20:59:46.499+0800 I REPL     [rsSync] no valid sync sources found in current replset to do an initial sync
2016-06-27T20:59:47.499+0800 I REPL     [rsSync] initial sync pending
2016-06-27T20:59:47.517+0800 I REPL     [rsSync] initial sync drop all databases
2016-06-27T20:59:47.517+0800 I STORAGE  [rsSync] dropAllDatabasesExceptLocal 1
2016-06-27T20:59:47.517+0800 I REPL     [rsSync] initial sync clone all databases
2016-06-27T21:00:17.517+0800 I NETWORK  [rsSync] Socket recv() timeout  10.182.4.106:27017
2016-06-27T21:00:17.517+0800 I NETWORK  [rsSync] SocketException: remote: (NONE):0 error: 9001 socket exception [RECV_TIMEOUT] server [10.1.1.6:27017] 
2016-06-27T21:00:17.519+0800 E REPL     [rsSync] 6 network error while attempting to run command 'listDatabases' on host '10.1.1.6:27017' 
2016-06-27T21:00:17.519+0800 E REPL     [rsSync] initial sync attempt failed, 9 attempts remaining

问题已反馈给官方团队,详情见SERVER-24948,在3.4版本里会去掉socket timeout来解决这个问题。

实际上,同步过程中listDatabases只需要获取所有DB的名称即可,并不需要size信息,所以我们的想法是给listDatabases命令加一个 {nameOnly: true}的选项,让命令只返回所有DB的名称信息,这样整个开销会很小,SERVER-3181也遇到类似问题,提了相同的解决思路,我们会在MongoDB云数据库里加上这个选项用于主备同步,github pull request

使用MongoDB时,建议用户还是合理的控制下集合数量(集合数量太多,很可能存储设计上也有问题,得好好review下),集合数量一旦大了,有可能面临各种问题,就如同上述的场景listDatabases耗时长,想监控数据库的容量使用情况都难。

上述问题其他的解决方案

  • Primary(同步源)上使用mmapv1引擎,内存足够的情况下,listDatabases的开销要更小些。
  • Secondary同步时不设置或设置更长的socket超时时间
  • 加新节点上,将Primary的数据拷贝到新的节点,跳过initial sync

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Room数据库 -- TypeConverter简单理解
Room数据库 -- TypeConverter简单理解
77 0
Swift:JKContactsKit 获取通讯录的联系人
Swift:JKContactsKit 获取通讯录的联系人
53 0
教你如何快速打造个人专属博客(轻量、简易、高逼格)
教你如何快速打造个人专属博客(轻量、简易、高逼格)
33 0
吃灰的云主机不要忘,部署个人博客,隔壁开发都馋哭了(下)
笔者置办个人博客的技术选型: 简洁:界面简洁,排版合理,不需要花里花哨; 简单:上手简单,开箱即用,输出文章即可,无需过于关注实现细节; 快:加载快,性能高效,移动端适配(地铁上也可以康康);
24 0
浏览器“黑客”(3)
浏览器“黑客”(3)
49 0
MongoDB Secondary 延时高(同步锁)问题分析
背景介绍 MongoDB 复制集里 Secondary 不断从主上批量拉取 oplog,然后在本地重放,以保证数据与 Primary 一致。同步原理参考MongoDB复制集同步原理解析 Secondary 拉取到一批 oplog 后,在重放这批 oplog 时,会加一个特殊的 Lock::ParallelBatchWriterMode 的锁,这个锁会阻塞所有的读请求,直到这批 oplog 重放完成。
6395 0
MongoDB Secondary同步慢问题分析(续)
在MongoDB Scondary同步慢问题分析文中介绍了因Primary上写入qps过大,导致Secondary节点的同步无法追上的问题,本文再分享一个case,因oplog的写入被放大,导致同步追不上的问题。 MongoDB用于同步的oplog具有一个重要的『幂等』特性,也就是说,一条oplo
5984 0
+关注
张友东(林青)
阿里云高级技术专家
105
文章
18
问答
来源圈子
更多
让用户数据永远在线,让数据无缝的自由流动
+ 订阅
相关文档: 云数据库 OceanBase 版 可信账本数据库 云原生关系型数据库 PolarDB PostgreSQL引擎
文章排行榜
最热
最新