前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从MongoDB迁移到TokuMx

从MongoDB迁移到TokuMx

作者头像
happy123.me
发布2018-06-04 10:10:54
1.4K0
发布2018-06-04 10:10:54
举报
文章被收录于专栏:乐享123

WHY:

原因无它,MongoDB的 BSON格式带来的磁盘空间消耗实在太严重了,将mongodb的数据库文件gzip一把,一般能到原大小的1/10。

mongodb提出的解决办法有以下几个:

定期repaire或Compact,但是repaire带来的性能消耗实在太大,repaire或compact的时候插入性能基本上就是渣了,另外100G级别的数据库文件需要数小时才能压缩完毕。
采用Capped Collections,这样在创建collections的时候可以指定数据库文件能占用的最大空间大小及单个document大小,当存储数据超过这个大小的时候会自动删除最老的数据,空出空间来。但这样做弊端就是你不知道会有多少数据被删掉,另外需要你对这个表插入的document大小心中有数。
建立自己的清理机制,定期把无用的数据清理出去。这样虽然比Capped Collections可控制,但是对删除掉的磁盘空间利用率进一步下降了,很多时候,你删掉一半数据,能重新利用的空间可能也就10%。这是由MongoDB对于单个Document的空间分配机制决定的。
最后一种方法就是合理规划,分库分表,然后在mongodb.conf里面设置选项:directoryperdb = true,这样mongo每个数据库都会建立一个文件夹,这样删除单库的时候数据文件就删干净了,空间自然清理出来了,这个选项我强烈推荐打开,即使你没有空间上的困扰,打开后也对数据库管理维护由不小的方便。当然指望这种办法删数据局限性就太大了。

详细说一下mongo对于删除空间的重新利用方法:

1.首先mongodb删除一个document的时候并不是物理上真正删除数据,而是维护一个deleteList链表数组,每次删除就在链表里面做一个标记。怎么表示这次删除的空间大小范围呢,如图示:

1 2 3 4 5 6 7 8 9

--------------------------------------- |<32 | 32-64| 64-128|....| < 4M| 4M-8M| --deleteList --------------------------------------- | | | | | | | | | | | | +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+

2.对每一个被删除的docment计算其大小,然后插入到合适的链表中去,这样下次插入新数据的时候,先计算合适的空间大小,再在这个链表数组中找到合适的空闲空间指针地址,插入数据。如果没有合适的,再去开辟新空间。

3.这个链表数组每个大小区间是代码里写死的,可参见namespace_detail.h: int bucketSizes[] = { 32, 64, 128, 256, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000,0x400000, 0x800000};

那么插入一条新的docement时,如何计算这个合适的空间分配大小就要斟酌了。mongo采取两种办法,选择哪一种可以在创建collection的时候指定:

1.Padding计算方式,这也是mongodb默认的方式。每次开辟空间的时候,采用公式 实际大小*(1+paddingFactor),这个 paddingFactor一般比较小,在0.01-1之间,是根据插入document的大小自动变化的。可以在mongodb的shell里用db.stats()查看这个值。另外,repaire会把这个值置为1,compact操作可以手工指定这个值。

2.采用usePowerOf2Size方式,这种方式和mongodb的磁盘空间分配比较相像,就是以22, 23, 24….大小增长,每次分配相近的空间大小

网上有人评价道:这两种方式各有优劣,padding方式会为文档开辟更合适的大小,而且paddingFactor比较小,一般为0.01-0.09,不会浪费空间,文档更新小的话也不会移动文档位置。但是当大量更新和删除的时候,这种方式重复利用空间的能力就比较小,因为在deleteList中,不太容易找到合适的已删除文档,而且一旦更新就会又移动位置,磁盘重复利用率低,增长快,碎片多。相比之下,usePowerOf2Size方式,Mongodb每次都会开辟比文档大的多的空间,使用空间变多,但是更新和删除的容错率就会比较高,因为在deleteList列表中更容易找到合适的删除文档(每个列表中的文档大小都是相同的固定的),更新的时候也不会大量移动位置,磁盘重复利用率高,增长慢。

看起来这些策略很靠谱,但我实际用起来两种方法其实效果都不好,另外usePowerOf2Size的表现好一些,mongodb自2.6开始把这种分配方式变成默认的了。
啰嗦了半天,我想说的就是, mongodb的存储受他的MMap内存管理所限,改来改去利用率没有本质提升。

How to do?

升级Tokumx

看看Tokumx的介绍: “TokuMX is the MongoDB you know and love but built on top of Fractal Tree indexes from Tokutek.”

从上层看,Tokumx 可以看成是Mongodb的克隆,仅仅是底层的存储方式用它们的Fractal Tree算法替换了mongodb的存储而已。

关于Fractal Tree,了解不多,从官方文档看,是对B-Tree的一个改进,通过对BTree的下级树叶保存子节点的缓冲区减少IO次数,另外可以用zlib等压缩算法存储数据

存储方式的改变,也改变了MongoDB默认用的MMap内存管理算法,Tokumx采用自定义的内存管理,直接表现就是占用内存可以手工控制了(事实上也推荐你指定一个内存占用值),不像MongoDB那样对内存的占用贪得无厌。得益于Fractal Tree,因为I/O的减少,分形树索引不会要求索引必须小于内存。即使超过内存的限制,TokuMX依然可以维持很高的写入性能。

可以参考这里 以及这里 以及这里 以及这里

Tokumx宣称了很多很好的特性:

  • Benefits for Developers
  • 20x faster w/o tuning
  • Transactions w/o tedious code
  • Switch w/o changing your app
  • Benefits for DevOps
  • Use fewer servers; avoid upgrades
  • 90% compression = less flash
  • Scalability w/o losing data integrity

与MongoDB对比,官方宣称的限制有两个:

  • 不支持全文索引
  • 不支持GEO地理信息

我们看中的就是他的磁盘占用,对这两个限制不Care。

Migrating data from MongoDB into TokuMX

怎样迁移,参考官方Wiki

How about

将Mongodb(2.4.9) 迁移到TokuMx (1.5.0),插入的document多是4K左右,原Mongodb数据库达到TB级别,感性体验:
  • 数据存储占用空间大幅下降,说只用原来的1/10并不夸大
  • 每个collection及index都会存在单独的文件中,这样删除单表或索引后会立即释放占用的空间
  • 同一个表,删除老数据,插入新数据,空间重复利用率>80%
  • 写入速度没有20x的提升,但各种情况下,最差情况提升1倍是有的
  • 读性能没有下降
在我看来,与MongoDB相比,Tokumx的不足有以下几点:
  • 稳定性; 因为采用了自定义的内存管理,不如MongoDB的MMap方式管理稳定,如果cacheSize设置不合适,而Tokumx的机器还有其他占用内存比较大的进程,会导致OOP,被系统杀掉的几率比较大。这要求我们设置cacheSize要斟酌一下。可以参考这里; 顺便说一下,如果你的系统内存占用控制得当,是没有多大问题的。
  • Tokumx的 Capped Collections性能比较渣,但是在我看来,存储方式的改变已经不需要这种方式了,所以这个不是问题。
  • 我没有找到从Tokumx重新迁回MongoDB的现成工具,将来要迁回来,可能要手工写工具自己导数据
  • Mongodb升级,新Feature的支持,还有商业化的问题。Tokumx的官网上的blog有人问了这个问题,问Tokumx有没有同MongoDB Merge的计划,开发者做了回答,很详尽。 首先Tokumx的开发团队很小的,可能不会及时跟进Mongodb的新Feature移植 第二两家公司有不同的商业化考量,另外代码的Merge有一定工作量,未来不太可能合并 Tokumx只专注于存储性能的改进
更新:经过一段时间使用,发现了如下问题:
  • 压缩后大量update是会带来大量碎片
  • 高写入性能会造成同步出现巨大延迟
  • 还是会莫名down掉,down掉几率还是要比Mongodb大
再次更新:经过实际数据测试,usePowerOf2Size的磁盘重复利用的确比较好
  • 采用Padding 的存储方式,磁盘重复利用率为32%
  • 采用usePowerOf2Size 的存储方式,磁盘重复利用率为73%
  • 采用usePowerOf2Size 的存储方式比Padding 的存储方式,磁盘多占用10%

所以假如有一年的数据,Padding的存储方式,storageSize为1T,设定过期时间是1年,那么第二年后,数据库增长为1.7T

同样的数据,usePowerOf2Size 的存储方式,storageSize为1.1T,设定过期时间是1年,那么第二年后,数据库增长为1.5T

这个数字会根据插入记录的离散度有所变化,但大概比例应该就是这样的。

总的来说,Tokumx还是只适合单机用啊,机器一多,各种毛病都来了~~~,大家如果分布式,等mongodb 2.8版本更靠谱一些。
2015-05 更新:升级到 mongodb3.0.3,切换到 WiredTiger存储引擎 ,各方面工作良好,建议升级 。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • WHY:
    • mongodb提出的解决办法有以下几个:
      • 定期repaire或Compact,但是repaire带来的性能消耗实在太大,repaire或compact的时候插入性能基本上就是渣了,另外100G级别的数据库文件需要数小时才能压缩完毕。
      • 采用Capped Collections,这样在创建collections的时候可以指定数据库文件能占用的最大空间大小及单个document大小,当存储数据超过这个大小的时候会自动删除最老的数据,空出空间来。但这样做弊端就是你不知道会有多少数据被删掉,另外需要你对这个表插入的document大小心中有数。
      • 建立自己的清理机制,定期把无用的数据清理出去。这样虽然比Capped Collections可控制,但是对删除掉的磁盘空间利用率进一步下降了,很多时候,你删掉一半数据,能重新利用的空间可能也就10%。这是由MongoDB对于单个Document的空间分配机制决定的。
      • 最后一种方法就是合理规划,分库分表,然后在mongodb.conf里面设置选项:directoryperdb = true,这样mongo每个数据库都会建立一个文件夹,这样删除单库的时候数据文件就删干净了,空间自然清理出来了,这个选项我强烈推荐打开,即使你没有空间上的困扰,打开后也对数据库管理维护由不小的方便。当然指望这种办法删数据局限性就太大了。
      • 看起来这些策略很靠谱,但我实际用起来两种方法其实效果都不好,另外usePowerOf2Size的表现好一些,mongodb自2.6开始把这种分配方式变成默认的了。
      • 啰嗦了半天,我想说的就是, mongodb的存储受他的MMap内存管理所限,改来改去利用率没有本质提升。
  • How to do?
    • 升级Tokumx
      • 将Mongodb(2.4.9) 迁移到TokuMx (1.5.0),插入的document多是4K左右,原Mongodb数据库达到TB级别,感性体验:
      • 在我看来,与MongoDB相比,Tokumx的不足有以下几点:
      • 更新:经过一段时间使用,发现了如下问题:
      • 再次更新:经过实际数据测试,usePowerOf2Size的磁盘重复利用的确比较好
      • 总的来说,Tokumx还是只适合单机用啊,机器一多,各种毛病都来了~~~,大家如果分布式,等mongodb 2.8版本更靠谱一些。
      • 2015-05 更新:升级到 mongodb3.0.3,切换到 WiredTiger存储引擎 ,各方面工作良好,建议升级 。
  • Migrating data from MongoDB into TokuMX
  • How about
相关产品与服务
云数据库 MongoDB
腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档