接着上一篇,本文来记录下mongodb 的自动分片功能。
Mongodb支持自动分片和划分架构,可以利用它构建一个水平扩展的数据库集群系统,将数据库分表存储在各个sharding节点上。本文接着上一篇的例子,来简单尝试一下这个”auto sharding”功能。在开始之前,先简要介绍下Sharding ,下面对sharding的介绍基本来自官网的文档http://www.mongodb.org/display/DOCS/Sharding+Introduction:
Sharding就是将数据按照一定顺序的分割、分片存储到不同机器的一种方式。举例来说:我们想把users集合根据其所在的州进行分片存储到三台机器上,那么这三台机器作为shard server,users集合可能会根据机器分为:
这样,每个机器都会根据users所在的州来存储大量的user数据块。MongoDb会均衡的将这些数据块分布存储在这三台机器上。这种分块的机制,只有在数据量达到sharding 设置的量时候才会起作用。
通过这种分片之后,应用程序可以通过mongos进程与shard集群交互。Mongos是一个mongodb server的一个进程,它能够将应用程序对数据库的操作路由到适当的shard机器上。从应用程序角度看,它只是跟一个单一的数据库链接。
那么何时分片呢?一般机器磁盘不够用时,或者单个mongod已经无法满足写数据的性能时,或者想将大量数据放到内存中提高性能时,可以考虑分片了。
Mongodb分片有三部分组成:
1) 片:Shard Server,用来存储片数据,生产环境一个分片服务会由多台服务器组成一个副本集,避免单点故障(这里先不考虑这个);
2) 配置服务器:Config Server,用来存储集群的元数据,数据和片的对应关系;
3) Routing Server,即Mongos进程,它本身不存储数据,只是用来路由所有请求,并把结果聚合。
下面开始分片操作,这里只用一个机器来做所有操作,旨在学习:
1) 启动两个片:
mongod –shardsvr –port 10000 –dbpath c:\mongodata\shard0 –logpath c:\mongodata\log\shard0.log
mongod –shardsvr –port 10001 –dbpath c:\mongodata\shard1 –logpath c:\mongodata\log\shard1.log
我这是window系统,命令就不解释了。
2) 启动配置服务:
mongod --configsvr --port:20000 –dbpath c:\mongodata\config –logpath c:\mongodata\log\config.log
3) 启动路由(mongos)进程:
mongos –configdb localhost:20000 –logpath c:\mongodata\log\server.log –chunkSize 1
指定chunk大小为1M,当数据大于1M时候就会开始分片存储了。
现在可以通过客户端连接到路由进程:mongo –port 27017 (由上一篇可知,这是默认端口),添加分片命令:
db.runCommand({addshard:”localhost:10000”})
db.runCommand({addshard:”localhost:10001”})
db.runCommand({“enablesharding”:”testDB”})
db.runCommand({shardcollection:”testDB.stores”,key:{“_id”:1}}) //以_id为键对stores集合进行分片
接下来测试,还是使用上一篇的demo所用的程序,当为stores集合添加了2000条数据时,查询,发现所有数据都在第一片(shard0)里,当我添加了100 00 条数据时候,再次查看:
貌似不太均匀,其实这时正常的,再继续添加数据时,两边的比例会变动,这和片键的选择有关系。应用程序查找和插入几乎不受影响。但是查找***地最近的***店时,报了异常,提示说用geoNear command 来代替$near查询,我以为是morphia或者mongodb java 驱动的一个issue,但是在shell端查找也报错了,郁闷哦!详细是这样的:
假如我链接到任意一个片,查找离[23,25]最近的两个stores,结果是可行的:
假如我是链接到路由进程,这样查找就会报错:
我通过geoNear 命令运行貌似结果也不对!目前我没弄清是什么原因。