博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MongoDB 哈希分片为什么数据大小不均匀?
阅读量:7250 次
发布时间:2019-06-29

本文共 1411 字,大约阅读时间需要 4 分钟。

今天接到一个用户反馈的问题,sharding集群,使用wiredtiger引擎,某个DB下集合全部用的hash分片,show dbs 发现其中一个shard里该DB的大小,跟其他的集合差别很大,其他基本在60G左右,而这个shard在200G左右?

_2017_08_02_7_31_54

由于这个DB下有大量的集合及索引,一眼也看不出问题,写了个脚本分析了一下,得到如下结论

  1. somedb 下所有集合都是hash分片,并且chunk的分布是比较均匀的
  2. show dbs 反应的是集合及索引对应的物理文件大小
  3. 集合的数据在各个shard上逻辑总大小是接近的,只有shard0占用的物理空间比其他大很多

从shard0上能找到大量 moveChunk 的记录,猜测应该是集合的数据在没有开启分片的情况下写到shard0了,然后开启分片后,从shard0迁移到其他shard了,跟用户确认的确有一批集合是最开始没有分片。

所以这个问题就转换成了,为什么复制集里集合的逻辑空间与物理空间不一致?即collection stat 里 sizestorageSize 的区别。

mymongo:PRIMARY> db.coll.stats(){    "ns" : "test.coll",    "size" : 30526664,    "count" : 500808,    "avgObjSize" : 33,    "storageSize" : 19521536,    "capped" : false,    ....}

逻辑存储空间与物理存储空间有差距的主要原因

  1. 存储引擎存储时,需要记录一些额外的元数据信息,这会导致物理空间总和比逻辑空间略大
  2. 存储引擎可能支持数据压缩,逻辑的数据块存储到磁盘时,经过压缩可能比逻辑数据小很多了(具体要看数据的特性,极端情况下压缩后数据变大也是有可能的)
  3. 引擎对删除空间的处理,很多存储引擎在删除数据时,考虑到效率,都不会立即去挪动数据回收删除的存储空间,这样可能导致删除很多文档后,逻辑空间变小,但物理空间并没有变小。如下图所示,灰色的文档删除表示被删除。删除的空间产生很多存储碎片,这些碎片空间不会立即被回收,但有新文档写入时,可以立即被复用。

_2017_08_02_8_03_44

而上述case里,集合数据先分到一个shard,然后启用分片后,迁移一部分到其他shard,就是一个典型的产生大量存储碎片的例子。存储碎片对服务通常影响不大,但如果因为空间不够用了需要回收,如何去强制的回收这些碎片空间?

  • 数据清理掉重新加入复制集同步数据,或者直接执行resync命令 (确保有还有其他的数据备份)
  • 对集合调用 compact 命令

2017-08-03 15:42:04 update

关于 compact操作,有同学问道,

mongdb中由于删除了大量的数据,但是没有释放磁盘空间给系统,想通过compact命令来释放磁盘空间;但是对compact命令有几个疑问

  1. compact命令在WiredTiger引擎上是库级别锁还是collection级别锁?
  2. 执行compact命令需要多大的空余磁盘空间呢
  • compact 加的是DB级别的互斥写锁,同一个DB上的读写都会被阻塞
  • compact基本不需要额外的空间,wiredtiger compact的原理是将数据不断往前面的空洞挪动,并不需要把数据存储到临时的位置(额外的存储空间)。

参考资料

转载地址:http://kvebm.baihongyu.com/

你可能感兴趣的文章
mysql 开源 ~ canal+otter系列(2)
查看>>
跟我一起写 Makefile (Linux )
查看>>
CC2640R2F&TI-RTOS 拿到 TI CC2640R2F 开发板 第二件事就是 LED 驱动 ,点个灯
查看>>
ELASTIC SEARCH 性能调优
查看>>
Java并发总结(三):中断线程
查看>>
Beer Refrigerator
查看>>
hadoop输入分片计算(Map Task个数的确定)
查看>>
TYVJ P1008 传球游戏
查看>>
MVC基础
查看>>
【BZOJ】 Hash Killer I II III
查看>>
为什么st2 chrome无法显示api中的例子
查看>>
Python 3.6 -win64环境安装PIL模块
查看>>
redis事务需要注意的坑------RedisConnectionFailureException
查看>>
SPOJ 4110 Fast Maximum Flow (最大流模板)
查看>>
ECMAScript面向对象(二)——之创建对象方法总结
查看>>
git实践:对比svn
查看>>
1 管理入门
查看>>
C#递归遍历指定目录下的所有文件(包括子目录下的文件)
查看>>
SpringMVC的工作流程
查看>>
JS比较好用的一些方法搜集
查看>>