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

来源:互联网 发布:电脑网络与共享打不开 编辑:程序博客网 时间:2024/05/05 15:51
    这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在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 plaincopy在CODE上查看代码片派生到我的代码片
  1. mkdir -p /data/shard/s0 --创建数据目录  
  2. mkdir -p /data/shard/s1  
  3. mkdir -p /data/shard/log --创建日志目录  
  4. /Apps/mongo/bin/mongod --shardsvr --port 20000 --dbpath /data/shard/s0 --fork --logpath  
  5. /data/shard/log/s0.log --directoryperdb --启动Shard Server 实例1  
  6. /Apps/mongo/bin/mongod --shardsvr --port 20001 --dbpath /data/shard/s1 --fork --logpath  
  7. /data/shard/log/s1.log --directoryperdb --启动Shard Server 实例2  
    启动Config Server
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. mkdir -p /data/shard/config --创建数据目录  
  2. /Apps/mongo/bin/mongod --configsvr --port 30000 --dbpath /data/shard/config --fork --logpath  
  3. /data/shard/log/config.log --directoryperdb --启动Config Server 实例  
    启动Route Process
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /Apps/mongo/bin/mongos --port 40000 --configdb localhost:30000 --fork --logpath  
  2. /data/shard/log/route.log --chunkSize 1 --启动Route Server 实例  
    mongos 启动参数中,chunkSize 这一项是用来指定chunk 的大小的,单位是MB,默认大小为200MB,为了方便测试Sharding 效果,我们把chunkSize 指定为 1MB。
    (2)配置Sharding

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

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@localhost ~]# /Apps/mongo/bin/mongo admin --port 40000 --此操作需要连接admin 库  
  2. MongoDB shell version: 1.8.1  
  3. connecting to: 127.0.0.1:40000/admin  
  4. > db.runCommand({ addshard:"localhost:20000" }) --添加 Shard Server  
  5. { "shardAdded" : "shard0000", "ok" : 1 }  
  6. > db.runCommand({ addshard:"localhost:20001" })  
  7. { "shardAdded" : "shard0001", "ok" : 1 }  
  8. > db.runCommand({ enablesharding:"test" }) --设置分片存储的数据库  
  9. { "ok" : 1 }  
  10. > db.runCommand({ shardcollection: "test.users", key: { _id:1 }}) --设置分片的集合名称,且必  
  11. 须指定Shard Key,系统会自动创建索引  
  12. { "collectionsharded" : "test.users", "ok" : 1 }  
  13. >  
    (3)验证Sharding正常工作
    我们已经对test.users 表进行了分片的设置,下面我们们插入一些数据看一下结果
[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. > use test  
  2. switched to db test  
  3. > for (var i = 1; i <= 500000; i++) db.users.insert({age:i, name:"wangwenlong", addr:"Beijing",  
  4. country:"China"})  
  5. > db.users.stats()  
  6. {  
  7. "sharded" : true, --说明此表已被shard  
  8. "ns" : "test.users",  
  9. "count" : 500000,  
  10. "size" : 48000000,  
  11. "avgObjSize" : 96,  
  12. "storageSize" : 66655232,  
  13. "nindexes" : 1,  
  14. "nchunks" : 43,  
  15. "shards" : {  
  16. "shard0000" : { --在此分片实例上约有24.5M 数据  
  17. "ns" : "test.users",  
  18. "count" : 254889,  
  19. "size" : 24469344,  
  20. "avgObjSize" : 96,  
  21. "storageSize" : 33327616,  
  22. "numExtents" : 8,  
  23. "nindexes" : 1,  
  24. "lastExtentSize" : 12079360,  
  25. "paddingFactor" : 1,  
  26. "flags" : 1,  
  27. "totalIndexSize" : 11468800,  
  28. "indexSizes" : {  
  29. "_id_" : 11468800  
  30. },  
  31. "ok" : 1  
  32. },  
  33. "shard0001" : { --在此分片实例上约有23.5M 数据  
  34. "ns" : "test.users",  
  35. "count" : 245111,  
  36. "size" : 23530656,  
  37. "avgObjSize" : 96,  
  38. "storageSize" : 33327616,  
  39. "numExtents" : 8,  
  40. "nindexes" : 1,  
  41. "lastExtentSize" : 12079360,  
  42. "paddingFactor" : 1,  
  43. "flags" : 1,  
  44. "totalIndexSize" : 10649600,  
  45. "indexSizes" : {  
  46. "_id_" : 10649600  
  47. },  
  48. "ok" : 1  
  49. }  
  50. },  
  51. "ok" : 1  
  52. }  
  53. >  
    我们看一下磁盘上的物理文件情况

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
  1. [root@localhost bin]# ll /data/shard/s0/test --此分片实例上有数据产生  
  2. 总计 262420  
  3. -rw------- 1 root root 16777216 06-03 15:21 test.0  
  4. -rw------- 1 root root 33554432 06-03 15:21 test.1  
  5. -rw------- 1 root root 67108864 06-03 15:22 test.2  
  6. -rw------- 1 root root 134217728 06-03 15:24 test.3  
  7. -rw------- 1 root root 16777216 06-03 15:21 test.ns  
  8. [root@localhost bin]# ll /data/shard/s1/test --此分片实例上有数据产生  
  9. 总计 262420  
  10. -rw------- 1 root root 16777216 06-03 15:21 test.0  
  11. -rw------- 1 root root 33554432 06-03 15:21 test.1  
  12. -rw------- 1 root root 67108864 06-03 15:22 test.2  
  13. -rw------- 1 root root 134217728 06-03 15:23 test.3  
  14. -rw------- 1 root root 16777216 06-03 15:21 test.ns  
  15. [root@localhost bin]#  
    看上述结果,表明test.users 集合已经被分片处理了,但是通过mongos 路由,我们并感觉不到是数据存放在哪个shard 的chunk 上的,这就是MongoDB 用户体验上的一个优势,即对用户是透明的。

0 0
原创粉丝点击