Nosql Mongodb之旅(27)—MongoDB Sharding分片

这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在sharding 的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式MongoDB 集群。
MongoDB 的数据分块称为 chunk。每个 chunk 都是 Collection 中一段连续的数据记录,通常最大尺寸是 200MB,超出则生成新的数据块。要构建一个 MongoDB Sharding Cluster,需要三种角色:
 Shard Server
即存储实际数据的分片,每个Shard 可以是一个mongod 实例,也可以是一组mongod 实例
构成的Replica Set。为了实现每个Shard 内部的auto-failover,MongoDB 官方建议每个Shard
为一组Replica Set。
 Config Server
为了将一个特定的collection 存储在多个shard 中,需要为该collection 指定一个shard key,例如{age: 1} ,shard key 可以决定该条记录属于哪个chunk。Config Servers 就是用来存储:所有shard 节点的配置信息、每个chunk 的shard key 范围、chunk 在各shard 的分布情况、该集群中所有DB 和collection 的sharding 配置信息。
Route Process
这是一个前端路由,客户端由此接入,然后询问Config Servers 需要到哪个Shard 上查询或保存记录,再连接相应的Shard 进行操作,最后将结果返回给客户端。客户端只需要将原本发给mongod 的查询或更新请求原封不动地发给Routing Process,而不必关心所操作的记录存储在哪个Shard 上。
下面我们在同一台物理机器上构建一个简单的 Sharding Cluster:

架构图如下:


 Shard Server 1:20000
 Shard Server 2:20001
 Config Server :30000
 Route Process:40000

(1)启动三服务

启动Shard Server

[plain] view plain copy
  1. mkdir-p/data/shard/s0--创建数据目录
  2. mkdir-p/data/shard/s1
  3. mkdir-p/data/shard/log--创建日志目录
  4. /Apps/mongo/bin/mongod--shardsvr--port20000--dbpath/data/shard/s0--fork--logpath
  5. /data/shard/log/s0.log--directoryperdb--启动ShardServer实例1
  6. /Apps/mongo/bin/mongod--shardsvr--port20001--dbpath/data/shard/s1--fork--logpath
  7. /data/shard/log/s1.log--directoryperdb--启动ShardServer实例2
启动Config Server
    mkdir-p/data/shard/config--创建数据目录
  1. /Apps/mongo/bin/mongod--configsvr--port30000--dbpath/data/shard/config--fork--logpath
  2. /data/shard/log/config.log--directoryperdb--启动ConfigServer实例
启动Route Process
    /Apps/mongo/bin/mongos--port40000--configdblocalhost:30000--fork--logpath
  1. /data/shard/log/route.log--chunkSize1--启动RouteServer实例
mongos 启动参数中,chunkSize 这一项是用来指定chunk 的大小的,单位是MB,默认大小为200MB,为了方便测试Sharding 效果,我们把chunkSize 指定为 1MB。
(2)配置Sharding

接下来,我们使用MongoDB Shell 登录到mongos,添加Shard 节点

    [root@localhost~]#/Apps/mongo/bin/mongoadmin--port40000--此操作需要连接admin库
  1. MongoDBshellversion:1.8.1
  2. connectingto:127.0.0.1:40000/admin
  3. >db.runCommand({addshard:"localhost:20000"})--添加ShardServer
  4. {"shardAdded":"shard0000","ok":1}
  5. >db.runCommand({addshard:"localhost:20001"})
  6. {"shardAdded":"shard0001",248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> >db.runCommand({enablesharding:"test"})--设置分片存储的数据库
  7. {"ok":1}
  8. >db.runCommand({shardcollection:"test.users",key:{_id:1}})--设置分片的集合名称,且必
  9. 须指定ShardKey,系统会自动创建索引
  10. {"collectionsharded":"test.users","ok":1}
  11. >
(3)验证Sharding正常工作
我们已经对test.users 表进行了分片的设置,下面我们们插入一些数据看一下结果
    >usetest
  1. switchedtodbtest
  2. >for(vari=1;i<=500000;i++)db.users.insert({age:i,name:"wangwenlong",addr:"Beijing",
  3. country:"China"})
  4. >db.users.stats()
  5. {
  6. "sharded":true,--说明此表已被shard
  7. "ns":"test.users",
  8. "count":500000,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "size":48000000,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "avgObjSize":96,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "storageSize":66655232,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "nindexes":1,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "nchunks":43,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "shards":{
  9. "shard0000":{--在此分片实例上约有24.5M数据
  10. "ns":"test.users",248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "count":254889,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "size":24469344,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "avgObjSize":96,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "storageSize":33327616,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "numExtents":8,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "lastExtentSize":12079360,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "paddingFactor":1,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "flags":1,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "totalIndexSize":11468800,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "indexSizes":{
  11. "_id_":11468800
  12. },108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "ok":1
  13. "shard0001":{--在此分片实例上约有23.5M数据
  14. "count":245111,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "size":23530656,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "storageSize":33327616,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "numExtents":8,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "nindexes":1,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "lastExtentSize":12079360,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "paddingFactor":1,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "flags":1,248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "totalIndexSize":10649600,108); list-style:decimal-leading-zero outside; color:inherit; line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "indexSizes":{
  15. "_id_":10649600
  16. },248); line-height:21px; margin:0px!important; padding:0px 3px 0px 10px!important"> "ok":1
  17. }
  18. }
  19. >
我们看一下磁盘上的物理文件情况
    [root@localhostbin]#ll/data/shard/s0/test--此分片实例上有数据产生
  1. 总计262420
  2. -rw-------1rootroot1677721606-0315:21test.0
  3. -rw-------1rootroot3355443206-0315:21test.1
  4. -rw-------1rootroot6710886406-0315:22test.2
  5. -rw-------1rootroot13421772806-0315:24test.3
  6. -rw-------1rootroot1677721606-0315:21test.ns
  7. [root@localhostbin]#ll/data/shard/s1/test--此分片实例上有数据产生
  8. 总计262420
  9. -rw-------1rootroot1677721606-0315:21test.0
  10. -rw-------1rootroot3355443206-0315:21test.1
  11. -rw-------1rootroot6710886406-0315:22test.2
  12. -rw-------1rootroot13421772806-0315:23test.3
  13. -rw-------1rootroot1677721606-0315:21test.ns
  14. [root@localhostbin]#
看上述结果,表明test.users 集合已经被分片处理了,但是通过mongos 路由,我们并感觉不到是数据存放在哪个shard 的chunk 上的,这就是MongoDB 用户体验上的一个优势,即对用户是透明的。

相关文章

一、引言 学习redis 也有一段时间了,该接触的也差不多了。后来有一天,以前的同事问我,如何向redis中...
一、引言 上一篇文章,我介绍了如何在Linux系统上安装和配置MongoDB,其实都不是很难,不需要安装和编译...
一、介绍 Redis客户端使用RESP(Redis的序列化协议)协议与Redis的服务器端进行通信。 虽然该协议是专门...
一、引言 redis学了一段时间了,基本的东西都没问题了。从今天开始讲写一些redis和lua脚本的相关的东西...
一、介绍 今天继续redis-cli使用的介绍,上一篇文章写了一部分,写到第9个小节,今天就来完成第二部分。...
一、引言 上一篇文章我们已经介绍了MongoDB数据库的查询操作,但是并没有介绍全,随着自己的学习的深入...