对MongoDB的一点认识

版本测试平台字长
1.5.432位

 

说明:由于手头没有合适的机器,所以本文只能反映MongoDB的1.5.432位 系统下的表现。

本文主要关注1.5.4具备的Alpha2版自动分区(sharding)功能。

 

MongoDB 是一个面向文档的数据库,支持高级查询、全文索引、自动分区、主从备份以及MapReduce。可说兼具Mysql和Bigtable的优点(至少它自己是这么说的)。MongoDB的开发小组用偶数表示正式发布的稳定版,奇数则用来表示开发版,所以1.5.4是一个不稳定的版本 ,问题也不少。1.6(1.5.5)的开发进度可以从Jira 跟进。

 

MongoDB在32位系统下有该死的2G限制,即一个mongod进程所能管理的数据不超过2G,所以预想的大数据量测试也完全无法实施。

 

这次搭建的测试集群包括以下服务:

名称数量作用
mongos1处理用户请求,平衡各分区
mongod configsvr1存储各分区的配置信息
mongod shardsrv7数据分区,数据存在这里

 

以上服务都是运行在同一台机器上的进程:

 

$ ps -Af|grep mongo
./bin/mongod -f conf/config27018.conf
./bin/mongod -f conf/shard27019.conf
./bin/mongod -f conf/shard27020.conf
./bin/mongod -f conf/shard27021.conf
./bin/mongod -f conf/shard27022.conf
./bin/mongod -f conf/shard27023.conf
./bin/mongod -f conf/shard27024.conf
./bin/mongod -f conf/shard27025.conf
./bin/mongos -f conf/mongos27017.conf


mongod和mongos的启动命令行参数可以看MongoDB的主页,参数不少,不过可以用配置文件管理

 

MongoDB的自动分区机制是range-based,插入的数据根据指定的分区id排序,id相邻的数据保存在一个小块(chunk)中,当一个小块写满(超过200M,可通过命令行限定)时,就会分裂成俩个,当一个分区服务器存储的小块超过一定数量时,mongos就会把小块迁往别的分区,至于小块数量达到多少才会发生迁移,从用户组 看来的数字是20个,实测是不到10个,这一块还不太清楚。

 

除了C++之外,MongoDB支持很多语言对其操作,如Python、Perl、Php、Java等,此外还有REST接口,这些都可以在其主页上"Drivers"一节找到,我们用Python来测试,所以用的是PyMongo

 

MongoDB也有一个shell,支持所有可进行的操作,以下是一些常用的命令:

 

1.列出数据库

> show dbs
admin
local
mydata
test


2.使用数据库

> use mydata

 

3.列出所有表

> show collections
news
system.indexes

 

4.查询/插入

> db.news.find()

> db.news.insert()

语法参见官方文档

 

5.分区操作,必须先use admin

> db.runCommand({addshard:"localhost:27025", allowLocal:1, maxSize:1200})

其中 allowLocal:1允许使用本地的其他进程做服务器,maxSize表示这个分区的容量,单位是M

 

> db.runCommand( { enablesharding : "mydata"} )

> db.runCommand( { shardcollection : "mydata.news"}, key : {_id : 1})

表示mydata数据库的news表将会被自动分区, 分区的key是_id,MongoDB分区的单位是表,但分区和不分区的表/库可以在同一个mongod下共存,完全由用户灵活调整。

_id是MongoDB数据表的主键,如果不自己指定,MongoDB也会帮你自动生成,还记的MongoDB的分区策略是“range based”吗?这个range就根据shardcollection命令指定的key来认定,不过如果key不够分散,可能会影响小块的分裂(如根据“性别”来分区可能就会嗝屁,因为小块必须保存一个key的所有值,而所有的女人对一个200M的小块来说可能就太多了)

 

> db.runCommand( { split : "mydata.news" , middle : {_id:"00001-00001-00000000000001400000"}})

这条命令将手动生成一个小块,以指定的middle值为界

 

> db.runCommand( { movechunk : "mydata.news", find:{_id:"00001-00001-00000000000000000003"}, to:"shard0"})

这条命令将find的结果涉及的小块统统搬移到shard0,利用split和movechunk两条指令可以对分区做灵活的调整,不过split这条命令目前还没有在官方文档中列出来,MongoDB的作者们还需要更卖力啊。

 

db.runCommand( { removeshard : "localhost:27025" } );

这条命令会“控干”指定的分区,将其中所有的小块都移动到别的分区,以后每次执行相同命令都会返回控干进度,完成数据搬移后,再执行一次此命令,就会把指定的分区完全删掉。

 

> db.runCommand({ listshards : 1});

这条命令将列出所有已经通过addshard加入集群的服务。

 

通过反复插入百万级的数据做了些简单测试,发现这个版本还不是太稳定,大概将遇过的问题列一下:

 

1.一个已知bug ,移动小块时如果被打断,日志不会被清空,后续的movechunk操作都无法启动。当所有的分区都写满以后(即超过2G),mongos会启动自动负载平衡,但移动小块的过程当然不能成功,这时即使加了新的shard,数据迁移也会失败。

 

2.写入稍一频繁便会遇到各种资源问题,如不能创建更多线程啦,不能接受更多连接啦,当然更多的还是由于超过2G数据导致mmap失败,线程和连接的限制也许可以通过ulimit解决?而且mongod启动时可以指定一个--maxConns参数,也许也有帮助。

mmap问题就只能换台64位机器了,MongoDB的作者目前还没有改进这一问题的打算。

 

3.在分区的maxSize设置得比较小的情况下,如500M,数据如果按顺序连续写入,即使一个shard已经写满,也不会自动写入下一个shard,而是一直把某个shard写爆为止,这个可能是由迁移数据的小块阈值引起的:maxSize的容量能存的chunk数量不足以引起mongos balancer的注意(注,新发布的1.5.5似乎已经修复了这个问题)

 

4.指定movechunk命令手动移动小块,然后Ctrl-C中断,会引起死锁,这时需要清空config.lock表的一些记录的状态。

 

5.即使通过db.news.ensureIndex()建立索引,查询速度还是及不上MySQL的一半,这也许是因为分区引起的,时间和空间必须放弃一样。

 

6.MapReduce没试,不过用户组里有人说很慢 , 当然这个帖子的内容我也没看。

 

8.还有一个比较严重的问题,PyMongo似乎无法判断是否插入失败,既不会抛异常,返回值也正常,虽然服务器那边的错误日志已经1个G了,我这边还快乐地以为事情进行得很正常,希望是我自己用的不对,毕竟也是比较粗心的家伙。

 

7.自动分区还有很多限制 ,不过这些都和我没啥关系

 

这些问题说明至少1.5.4的32位版本还不适用于生产环境,当然这一点mongod在启动的时候就自己说了,在64位机器下,1.6版本是否会有更好表现呢?至少不会再有一块200G的硬盘只能存2G数据的尴尬。

 

说说MongoDB的优点(个人观点):

1.不需要用户去山寨分区功能,虽然MongoDB自己的sharding也有很多问题,但它还是个年轻的产品,有的是成长空间。

2.支持MapReduce,对于经常需要做统计分析的用户来说无疑是一种福音。

3.schema-less,对拥有异构数据表,但又需要统一处理这些数据的用户来说是一种福音。

4.支持丰富的查询功能,可以在任一字段上建索引及查询,查询方式包括比较、正则、自定义函数等,这在其他NoSQL数据库中是很少见的,似乎也只有Hadoop的Hive了?仅知道Hypertable可以通过Hive扩展支持查询功能。

5.MongoDB的用户组也比较活跃,开发小组经常混迹其间,不过总给他们贴Log感觉不太爽。

6.开发比较活跃,从jira看出每天都有进展。

7.代码较少,似乎只有数万行。

8.提供商业服务,不过似乎价格不菲

 

感觉MongoDB还是很有想象力的一个东东,希望它能最终成长起来,成为MySQL之外的另一开发利器。

 

以上的内容只是对最近测试工作的一个总结,由于本人对MongoDB还不是特别了解,舛错在所难免,欢迎大家斧正。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值