MongoDB疑难解析:为什么升级之后负载升高了?

  • 时间:
  • 浏览:0

关闭表的 balancer 可不后能 处理升级以前负载升高的问题图片,以后竟然是为什么我么我会么会会升级到 4.0 以前 CPU 负载较高, 而 3.2 版本稳定在低位呢?这必须肯能是另好几次 意味:4.0 版本更频繁的处在 moveChunk, 持续的删除数据意味 CPU 负载一直较高;3.2 版本较少的处在 moveChunk,太满再删除数据什么都 负载很低。

balancer 过程中,会对集合做一次随机排序,当有多个集合的数据须要均衡时,迁移时也是随机的,并是否迁移完另好几次 集合开使英文下另好几次 集合。

重点关注上述的迁移阈值,只是这名 迁移的阈值 threshold 在 3.2 和 4.0 版本有所不同。

统计最近另好几次 周期,开启 balancer 以前 moveChunk 的状态:

什么都 本次问题图片的根本是: 4.0 版本和 3.2 版本的 balancer 与 moveChunk 的逻辑是否有差别?同样的操作,为哪此 4.0版本的集群会有较多的 moveChunk ?

3.2 和 4.0 版本的异步删除多进程 具体实现略有不同,以后,根本过程还是一致的,用另好几次 队列保存须要删除的 range, 循环的取队列的数据删除数据。什么都 异步删除数据多进程 是按照 chunk 进入队列的顺序,逐个删除。总入口:

设置土办法 如下:

To minimize the impact of balancing on the cluster, the balancer only begins balancing after the distribution of chunks for a sharded collection has reached certain thresholds. The thresholds apply to the difference in number of chunks between the shard with the most chunks for the collection and the shard with the fewest chunks for that collection. The balancer has the following thresholds:

也只是说,splitChunk 操作有滞后性,即使数据分布均衡,是否肯能 splitChunk 执行时间的差异意味 chunks 分布处在底下的不均匀状态,意味絮状的 moveChunk 。

moveChunk 是另好几次 复杂的动作, 大致过程如下:

无论 3.2 还是 4.0 的 balancer ,默认的检测周期为 10s , 肯能处在了 moveChunk ,检测周期为 1s 。balancer 基本过程也大致相同:

从上表可知此场景下, {_id : hashed} 分片类型集合数据基本肯能均匀了,从不重启开启 balancer 。肯能 每个chunk 文档数较多,删除会比较耗资源。

网易游戏高级运维工程师,MongoDB和MySQL数据库爱好者,目前专注于SAAS平台的开发与运维工作。

3.2 版本 _secondaryThrottle 默认 true, 3.4 开使英文版本默认 false,什么都 3 .2 版本和4.0 版本 moveChunk 迁移数据时,4.0版本会调慢完成,迁移中 目的分片的每秒 insert 量级也会更多,对 CPU 负载也会某些许的影响。

以后从代码上,从3.4 版本开使英文,此阈值的逻辑就肯能变化了,以后文档并没办法 更新。

4.0 版本在删除数据时,按批删除数据,每次删除数量计算土办法 如下:

db.adminCommand({setParameter:1,migrateCloneInsertionBatchDelayMS:0})

db.adminCommand({setParameter:1,migrateCloneInsertionBatchSize:0})

首先可不后能 明确,升级以前 CPU 负载升高和 balancer 迁移数据有关。观察升级以前 4.0 版本,周二打开 balancer 期间的负载状态和 mongostat 结果:

split chunks 一般是在插入、更新、删除数据时,由 mongos 发出到分片的 splitVector 命令,此二十四时片才会判断是否须要 split 。以后 mongos 并我想知道每个 chunk 真正的数据量,是利用另好几次 简单的估算算法判断的。

可不后能 发现,CPU 负载升高和 delete 数据的状态很吻合。而迁移数据数据以前源节点须要删除迁移走的数据,什么都 肯定有絮状的 delete 。迁移数据以前的删除也会有如下的日志:

3.2 版本 db/range_deleter.cpp 多进程 入口 RangeDeleter::doWork()

4.0 版本 db/s/metadata_manager.cpp scheduleCleanup 前会有另好几次 唯一的多进程 执行清理任务

有较多的参数可不后能 灵活的控制删除速率,默认状态下,900s 以前开使英文清理 chunks 的数据,每次清理 128 个文档,每隔 20ms 删除一次。具体通过以下参数设置:

可不后能 在 config.settings 设置 _secondaryThrottle 和 waitForDelete 设置 moveChunk 过程中 插入数据和删除数据的 write concern

本文是“我和MongoDB的故事”征文比赛的二等奖得主李鹏冲的文章。下面亲戚亲戚当我们歌词 歌词 并肩来欣赏下。

use config db.settings.update(

{ "_id" : "balancer" },

{ $set : { "_secondaryThrottle" : { "w": "majority" } ,"_waitForDelete" : true } },

{ upsert : true }

)

设置土办法 如下:

近期线上另好几次 三分片集群从 3.2 版本升级到 4.0 版本以前,集群节点的 CPU 的负载升高了什么都 (10% -> 40%), 除了版本的升级,项目逻辑和操作量均无变化。关闭 Balancer 以前 CPU 负载回归正常,稳定在 10% 以下。为此,必须一直关闭当前正在写入表的 balancer , 每周二打开 balancer 开启均衡,在此期间节点的 CPU 负载持续稳定在 40% 。集群有 3 个分片,除了 MongoDB 版本的变化,项目有一种的逻辑无任何变化。没办法 升级以前 CPU 负载较大变化的身旁是哪此意味呢?

3.2 版本和 4.0 版本,此要素逻辑最大的区别只是, 3.2 版本 balancer 在 mongos,4.0 版本在 config(3.4版本开使英文),moveChunk 过程和删除数据的逻辑基本没办法 差异。

当通过 mongos 处在插入和更新删除操作时,mongos 会估算对应 chunks 的数据量的大小,满足条件会触发splitChunk 的操作,splitChunk 以前肯能会意味集群的 chunk 分布不均匀。balancer 检测数据的分布状态,当数据分配不均匀时,发起 moveChunk 任务,将数据从 chunks 较多的分片迁移到 chunks 较少的分片,迁移以前源节点会异步删除迁移走的 chunk 数据。

The balancer stops running on the target collection when the difference between the number of chunks on any two shards for that collection is less than two, or a chunk migration fails.

另外,3.4.18/3.6.10/4.0.5 及以前版本,还有以下参数 (Parameter) 调整插入数据的速率:

作者:李鹏冲

目的分片,首没能删除要移动的 chunk 的数据。什么都 会有另好几次 删除任务。

const size_t kDefaultImbalanceThreshold = 2; const size_t kAggressiveImbalanceThreshold = 1;

const size_t imbalanceThreshold = (shouldAggressivelyBalance || distribution.totalChunks()

< 20)

? kAggressiveImbalanceThreshold: kDefaultImbalanceThreshold;

// 这里确实 有个 1 ,以后实际差距为 1 的以前太满再处在迁移,肯能判断迁移时,还有另好几次 指标:平均每个分片的最大 ch

unks 数量,必须当 chunks 数量大于这名 值的以前才会处在迁移。

const size_t idealNumberOfChunksPerShardForTag = (totalNumberOfChunksWithTag / totalNumberOfShardsWithTag) + (totalNumberOfChunksWithTag % totalNumberOfShardsWithTag ? 1 : 0);

3.2 版本, chunks 数量小于 20 的以前为 2, 小于 30 的以前为 4, 大于 30 的以前为 8 。也只是说假设两分片集群,某个表有 30 个chunk , 每个分片分别有 47 和 53 个chunk 。没办法 此时 balance 认为是均衡的,太满再处在迁移。

每次 balancer 会检测所有集合的状态,每个集合最多另好几次 迁移任务 ; 以后构造迁移任务时,肯能某个集合中含最多数量的分片肯能最少数量 chunks 的分片,肯能属于某另好几次 迁移任务,没办法 此集合本轮 balancer 太满再处在迁移。最后,本次检测出的迁移任务完成以前才开使英文下次 balancer 过程。

53094:2019-10-08T10:09:24.035199+08:00 I SHARDING [Collection Range Deleter] No documents remain to delete in dt2log.tbl_log_item_2019301 range [{ id: -3074457345618258302 }, { id: -3033667061349287030 })

53095:2019-10-08T10:09:24.035222+08:00 I SHARDING [Collection Range Deleter] Waiting for m ajority replication of local deletions in dt2log.tbl_log_item_2019301 range [{ _id: -3074 457345618258302 }, { _id: -3033667061349287030 })

53096:2019-10-08T10:09:24.035274+08:00 I SHARDING [Collection Range Deleter] Finished dele ting documents in dt2log.tbl_log_item_2019301 range [{ _id: -3074457345618258302 }, { _id

: -3033667061349287030 })

关于此阈值,官方文档是否介绍:

int threshold = 8;

if (balancedLastTime || distribution.totalChunks() < 20) threshold = 2;

else if (distribution.totalChunks() < 30) threshold = 4;

什么都 从监控和日志判断, CPU 负载较高主只是肯能迁移数据以前的删除意味。以后集群的表是否 {_id : hashed} 分片类型的表,数据量较大,以后每条数据较小,平均每个 chunk 10w+ 的文档数,删除数据速率约 30-30/s ,什么都 移动另好几次 chunk 意味的删除就会持续 10 分钟左右。

maxToDelete = rangeDeleterBatchSize.load();

if (maxToDelete <= 0) {

maxToDelete = std::max(int(internalQueryExecYieldIterations.load()), 1); // 128

}

4.0 版本,chunks 数量差距大于 2 的以前就会处在迁移。同样的上述例子中,每个分片分别有 47 和 53 个 chunk时, balance 认为是不均衡的,会处在迁移。