之前的文章介绍过TokuTek公司出品的TokuDB,其主要特色是在拥有完整事务处理能力的前提下,实现了大幅度的数据压缩,并有着良好的性能 表现。TokuTek的工程师再接再厉,把目前非常流行的NoSQL数据库MongoDB的底层替换成与TokuDB同样的存储引擎,达到了非常好的效 果。
MongoDB拥有灵活的文档型数据结构和方便的操作语法,在新兴的互联网应用中得到了广泛的部署,但对于其底层的存储引擎,我一直有一些保留意 见。据我了解,其采用了MMAP的方式来操作数据文件,这就导致我们无法限制MongoDB进程所使用的内存容量,目前最好的部署办法就只能是将其单独部 署在一台服务器上。另外,MongoDB也不能严格的支持事务,对于并发写入的锁的粒度也非常粗。
TokuMX的出现解决了这一切,它为MongoDB替换了一颗真正的数据库存储引擎,我们现在可以像使用MySQL数据库一样精确的指定TokuMX最大可用内存,它也完整支持的事务处理。当然了,TokuTek引以为傲的数据压缩能力也是一点也没落下。
TokuMX经过多次发布,现在是1.3.2版本,是免费开源软件,官方网站可以下载:
http://www.tokutek.com/products/tokumx-for-mongodb/
软件体积也比较大(大概73M),国内下载比较慢,我搬运了一份到百度网盘:
http://pan.baidu.com/s/1ksfWj
TokuMX 实现了绝大部分MongoDB 2.4的功能,应用程序无需做任何修改。但需要注意的是,TokuMX的数据存储格式与MongoDB完全不一样,需要使用mongodump导出数据,然后用mongorestore导入才可以使用。
官方用户站内指南下载地址:
http://www.zeuux.com/group/mysql/file/content/443/
来源:http://xmgu2008.blog.163.com/blog/static/13912238020140279353937/
TokuMX的数据压缩能力令人惊喜
相比原生的MongoDB, TokuMX 提供了三个主要的特性:性能的优化提升,数据压缩特性,支持事物。不过实际使用中到底怎么样呢?
作为已经使用两个月的用户的我表示很满意,公司线上的一个产品使用 TokuMX 两个月以来并没有出现问题。而且让我印象最为深刻的是TokuMX对数据的压缩能力。
因为对写做了优化和压缩,在不影响性能的前提下 TokuMX 比原生的 MongoDB 节约了90%的存储空间。
下面是我们的实际情况: 为了比较,我在同一各集群上起了两套MongoDB,一个是原生的,一个是TukuMx,并使用相同的数据。使用中发现原MongoDB中的数据大小为32GB,而导入到TokuMX中只有3.4GB,果真是节约了90%的存储空间。
具体数据如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
# du -sh sudops_tokumx
3.4G sudops_tokumx
# du -sh sudops_mongodb
32G sudops_mongodb
# ls -tlrh sudops_mongodb/
total 32G
-rwxr-xr-x 1 root root 6 Mar 20 22:29 mongod.lock
-rw------- 1 root root 2.0G Mar 20 22:54 local.9
-rw------- 1 root root 2.0G Mar 20 22:54 local.8
-rw------- 1 root root 2.0G Mar 20 22:54 local.7
-rw------- 1 root root 2.0G Mar 20 22:54 local.6
-rw------- 1 root root 2.0G Mar 20 22:54 local.5
-rw------- 1 root root 2.0G Mar 20 22:54 local.11
-rw------- 1 root root 2.0G Mar 20 22:54 local.10
-rw------- 1 root root 2.0G Mar 20 22:54 local.4
-rw------- 1 root root 2.0G Mar 20 22:54 local.3
-rw------- 1 root root 2.0G Mar 20 22:54 local.2
-rw------- 1 root root 64M Mar 20 22:54 local.0
-rw------- 1 root root 128M Mar 20 23:23 sudops.1
-rw------- 1 root root 256M Mar 20 23:24 sudops.2
-rw------- 1 root root 2.0G Mar 20 23:25 sudops.5
-rw------- 1 root root 512M Mar 20 23:25 sudops.3
drwxr-xr-x 2 root root 4.0K Mar 20 23:26 journal
-rw------- 1 root root 64M Mar 20 23:27 sudops.0
-rw------- 1 root root 16M Mar 20 23:27 local.ns
drwxr-xr-x 2 root root 4.0K Mar 20 23:27 _tmp
-rw------- 1 root root 16M Mar 20 23:27 sudops.ns
-rw------- 1 root root 1.0G Mar 20 23:27 sudops.4
-rw------- 1 root root 2.0G Mar 20 23:27 local.1
-rw------- 1 root root 2.0G Mar 20 23:28 local.12
# ls -trlh sudops/
total 3.4G
-rw------- 1 root root 0 Mar 18 17:16 __tokumx_lock_dont_delete_me_temp
-rw------- 1 root root 0 Mar 18 17:16 __tokumx_lock_dont_delete_me_recovery
-rw------- 1 root root 0 Mar 18 17:16 __tokumx_lock_dont_delete_me_logs
-rw------- 1 root root 0 Mar 18 17:16 __tokumx_lock_dont_delete_me_environment
-rw------- 1 root root 0 Mar 18 17:16 __tokumx_lock_dont_delete_me_data
-rwxr-xr-x 1 root root 16K Mar 18 17:16 tokumx.environment
-rwxr-xr-x 1 root root 32K Mar 18 17:17 local_system_version_id__2_8_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 18 18:12 local_system_replset_id__a2_1_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 18 18:33 local_system_indexes__2_a_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 18 18:33 local_me_id__448_1_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 18 18:33 local_ns_2_7_19.tokumx
-rwxr-xr-x 1 root root 6 Mar 19 13:55 mongod.lock
-rwxr-xr-x 1 root root 32K Mar 19 13:56 local_startup_log_id__5_1_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 19 15:52 sudops_category_id__2b87_1_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 19 15:52 sudops_role_id__29cc_1_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 19 15:55 sudops_menu_id__2a15_1_19.tokumx
-rwxr-xr-x 1 root root 64K Mar 19 18:39 sudops_type_id__2c95_1_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 19 19:02 sudops_region_id__48de_1_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 20 19:07 sudops_system_indexes__2965_6_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 20 19:07 sudops_system_namespaces__2965_5_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 20 19:07 sudops_ns_2965_3_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 21 10:48 sudops_searchRecommend_id__3055_1_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 26 11:19 sudops_cp_id__2b19_1_19.tokumx
-rwxr-xr-x 1 root root 32K Mar 26 17:24 local_oplog_refs_p5_id__1905fa1_2_19.tokumx
-rwxr-xr-x 1 root root 32K Apr 8 18:21 sudops_user_id__2989_1_19.tokumx
-rwxr-xr-x 1 root root 96M Apr 8 18:43 local_oplog_rs_p20_id__1ff054b_1_19.tokumx
-rwxr-xr-x 1 root root 32K Apr 9 17:24 local_oplog_refs_meta_id__a1_3_19.tokumx
-rwxr-xr-x 1 root root 128M Apr 9 18:39 local_oplog_rs_p21_id__20774ee_1_19.tokumx
-rwxr-xr-x 1 root root 32K Apr 14 15:13 sudops_component_id__3019_1_19.tokumx
-rwxr-xr-x 1 root root 144M Apr 14 18:16 local_oplog_rs_p26_id__2338b07_1_19.tokumx
-rwxr-xr-x 1 root root 32K Apr 15 17:54 sudops_channel_id__2f15_1_19.tokumx
-rwxr-xr-x 1 root root 128K Apr 16 15:49 sudops_special_id__2fbb_1_19.tokumx
-rwxr-xr-x 1 root root 32K Apr 21 11:09 sudops_searchWord_id__3062_1_19.tokumx
-rwxr-xr-x 1 root root 64K Apr 21 16:44 sudops_assemble_id__2bd68_1_19.tokumx
-rwxr-xr-x 1 root root 64K Apr 21 16:49 sudops_poster_id__2f3e_1_19.tokumx
-rwxr-xr-x 1 root root 32K Apr 21 17:24 local_system_namespaces__2_9_19.tokumx
-rwxr-xr-x 1 root root 32K Apr 21 17:24 local_oplog_rs_meta_id__a1_1_19.tokumx
|
当初在选择TokuMX的时候我选择了 TokuMX enterprise subscription,号称其支持Hotbackup,不过还始终无法配置成功,还特意在在线咨询了TokuMX的brain polansky,他建议我使用community version。如果有什么问题的话,还是推荐大家加入TokuMX 的 Google Groups。
来源:http://www.sudops.com/tokumx-compression-data-save-90-percent-stoage.html
TokuMX vs. MongoDB 插入性能对比
TokuDB 的ft tree 用在MongoDB产品TokuMX已经发布。MongoDB 在大量数据(比如1亿条记录)后,插入性能急剧下降。
Tokutek数据
带索引插入性能对比。
http://www.tokutek.com/2013/06/iibench-benchmark-tokumx-vs-mongodb/
以上为Tokutek的测试数据,下面为我测试的数据:
笔者实际测试
生产数据2亿多条导入测试
先建集合,创建3个索引,包括_id共4个索引。
TokuMX 5个多小时导完数据,官方MongoDB 2.2.4版本竟然花了2天2夜多,近58个小时
使用mongostat统计,每分钟取值一个,纵坐标为inserts/s,横坐标为分钟。
局部放大图:
磁盘空间占用比较:
TokuMX 18G,MongoDB 80G
内存使用比较:
TokuMX,cacheSize设置为30G,开directio,内存使用完没有cache的。
total used free shared buffers cached
Mem: 31 31 0 0 0 0
-/+ buffers/cache: 30 0
Swap: 15 0 15
MongoDB,内存使用完,实际在cache里面
total used free shared buffers cached
Mem: 31 31 0 0 0 28
-/+ buffers/cache: 1 29
Swap: 15 0 15
cpu使用:
未详细记录,TokuMX要高10%左右。
io:
MongoDB io要高不少。
总结:TokuMX太让人激动了,没有不使用它的理由,不过目前有些不支持的功能,如geo索引。
Currently unsupported functionality
● dropDups option for unique indexes
● Background Indexing, the “background” option is ignored when creating indexes.
● Fulltext indexes
● Geospatial indexes
来源: http://www.tuicool.com/articles/22IVfi
我们为什么要从MongoDB迁移到TokuMX
http://nosqldb.org/topic/5354c77c3b3af7ad7f126ad4
MongoDB使用情况
作为最初使用MongoDB的用户之一,我们线上MongoDB版本从MongoDB 1.8到MongoDB 2.0到MongoDB 2.2再到MongoDB 2.4,我们经历了几乎所有使用MongoDB的用户会遇到的问题,也随着MongoDB版本更新,看到MongoDB这几年取得的改进。
近期随着MongoDB 2.6版本的发布,在国内外又掀起了一股热(tu)潮(cao),然后这一次我们可能不会立即升级或部署新的MongoDB 2.6版本,但我们会保持关注。
去年(2013)6月份我们开始对TokuMX 1.0版本进行测试,关注,一直进行了半年多的观察。在今年2月份在正式在生产环境迁移看了第一套TokuMX 版本1.4.0。为什么是1.4.0?因为之前的版本还不是很完善,不是很友好,也有一些bug没解决。
一直到近期,线上比较重要的系统已陆续迁移到TokuMX 1.4.1(主要使用工具mongosync),开始较大规模的开始使用,并且新上线的系统无特殊原因默认使用TokuMX。
为什么要迁移到TokuMX
尽管TokuMX宣称了很多很好的特性,真正使得我们迁移的原因是如下几种:
- 压缩。MongoDB BSON格式的带来的存储空间消耗实在是太大了,使用TokuMX 默认的zlib压缩可以减少大量的磁盘空间占用(1/3-1/20)。
- 更好的存储空间利用效率。MongoDB 空间释放是个麻烦的事情(需要drop 整个个数据库或者repair),TokuMX drop collect或者index即可释放空间。
- 更好的内存管理。MongoDB nmap简单,但是不方便分配固定内存。caching和 IO都交由操作系统去调度,时间长了,数据大了容易造成内存泄露。TokuMX 通过参数指定cacheSize分配固定大小的内存(多实例环境这个非常适用,虽然不推荐使用多实例)。
- 写优化。这个是TokuMX 最基础最根本的东西,在大数据量的情况下写入速度基本保持不变。MongoDB在超过1亿记录后或在数据比较大的情况下,写性能衰减得比较厉害,这一切归因于40年的B-tree索引,也正是TokuMX 分形树索引优化的地方。
- 其他的特性,如document 级别的锁,事务支持等,这些不是我们所重的,实际效果还需时间检验。
TokuMX目前带来的成本或缺点
尽快TokuMX解决了一系列的问题,但也并非是完美的方案。
- 增加运维成本。对于从MongoDB迁移过来,肯定是需要更多的学习成本和运维成本的,比如新的问题的产生,新的运维工具的开发与支持。从企业角度说,目前国内大多都没有购买原厂支持的情况下,这个可能并不那么突出。
- 查询性能?由于压缩或多或少影响查询性能,目前从我们使用看,没有影响。
- 目前部分功能不支持,如geo索引,全文索引。
TokuMX使用小计
最近因为工作的缘故,接触了 TokuMX ,尝试下来感觉不错,值得介绍给大家。
事情的起因是要解决MongoDB的问题。系统中需要保存程序输出的运行信息,这类信息比程序语言的log更高级,比明确的操作日志更低级,却是某些时候发现问题的关键证据,所以必须保存下来。因为其格式不规范,又需要方便检索,综合下来文档型NoSQL的MongoDB是比较好的选择。
但是选择MongoDB就必然会面对磁盘消耗的问题。我们拿到的数据大概是这样的:每天的数据量不到200万条,平均数据的大小不超过4k,但MongoDB存一个月的数据就需要接近40G,最近三个月的数据则需要接近100G。限于原有硬件环境,只能保存最近三个月的数据,但业务又需要保存至少一年的数据,所以必须另想办法。
最终我们选定的方案是TokuMX。它是一款开源的、高性能的MongoDB发布(distribution),在提供与MongoDB完全兼容的客户端、API的同时,号称可以减少90%的存储空间,同时提供20倍的性能提升。我也了解到,已经有一些生产系统在使用TokuMX,反馈不错。
经过我的测试,用MongoDB需要102G的数据,采用默认的zlib压缩方式导入TokuMX之后,只有481MB,同时,导入速度大大提高(至少有10倍的提高),而查询性能没有降低。这个对比是我不敢想像的,直接解决了现在的问题。
对着这份数据,我不免好奇TokuMX究竟使用了怎样的技术?就我现在的了解,减少磁盘空间占用主要是在存储层使用了压缩方式(TokuMX宣称,如果不使用压缩,TokuMX的磁盘占用也比MongoDB少10%左右)。这种思路不稀奇,5.x版本的MySQL,如果设定file_format为Barracuda,也可以直接对表做压缩,同时不影响外部操作;提高写入速度则值得一提,原来TokuMX的做法是使用 分形树索引(Fractal Tree Index) ,替代了所谓“已经有40年历史的B树索引”。
所谓“分形”,大略来说,指的是“事物的每一部分都近似整体缩小后的形状”。TokuMX的分形树索引,严格说起来更像“B树 + 批量写入”的技巧,与B树的不同在于,分形树的每个内部节点都带有自己的缓冲区,它存储尚未落实(pending)到叶子节点的数据,默认情况下写入只会到缓冲区,缓冲区填满之后会把所有的写操作刷(flush)下去。
我顺手翻译了TokuMX的一篇介绍文章,供大家参考。
参考资料: http://www.percona.com/live/london-2013/sessions/fractal-tree-indexes-theory-practice
延伸阅读:http://www.tuicool.com/topics/11030118