楼主: jieforest

MongoDB集群的Sharding详解

[复制链接]
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
11#
 楼主| 发表于 2014-2-6 11:38 | 只看该作者
修改chunk size

这是一个全局的参数。 默认是64MB。

小的chunk会让不同的shard数据量更均衡。 但会导致更多的Migration。

大的chunk会减少migration。不同的shard数据量不均衡。

这样修改chunk size。先连接上任意mongos
  1. db.settings.save( { _id:"chunksize", value: <size> } )
复制代码
单位是MB

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
12#
 楼主| 发表于 2014-2-6 11:39 | 只看该作者
何时会自动balance

每个mongos进程都可能发动balance。

一次只会有一个balance跑。 这是因为需要竞争这个锁:

  1. db.locks.find( { _id : "balancer" } )
复制代码
balance一次只会迁移一个chunk。

只有chunk最多的shard的chunk数目减去chunk最少的shard的chunk数目超过treshhold时才开始migration。
  1. Number of Chunks        Migration Threshold
  2. Fewer than 20            2
  3. 21-80            4
  4. Greater than 80        8
复制代码
上面的treshhold从2.2版本开始生效。

一旦balancer开始行动起来,只有当任意两个shard的chunk数量小于2或者是migration失败才会停止。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
13#
 楼主| 发表于 2014-2-6 11:40 | 只看该作者
设置分片上最大的存储容量

有两种方式,第一种在添加分片时候用maxSize参数指定:
  1. db.runCommand( { addshard : "example.net:34008", maxSize : 125 } )
复制代码
第二种方式可以在运行中修改设定:
  1. use config
  2. db.shards.update( { _id : "shard0000" }, { $set : { maxSize : 250 } } )
复制代码

使用道具 举报

回复
论坛徽章:
46
凯迪拉克
日期:2013-08-22 10:00:10Jeep
日期:2013-08-10 07:21:13ITPUB社区12周年站庆徽章
日期:2013-10-08 14:57:28ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-01-04 11:49:54ITPUB 11周年纪念徽章
日期:2012-10-09 18:05:07奥运会纪念徽章:体操
日期:2008-10-24 13:08:31会员2007贡献徽章
日期:2007-09-26 18:42:10马上加薪
日期:2014-04-11 09:34:11秀才
日期:2015-09-06 10:19:32
14#
发表于 2014-2-6 21:03 | 只看该作者
打酱油,路过。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
15#
 楼主| 发表于 2014-2-7 15:03 | 只看该作者
删除分片

连接上任意一台mongos

STEP1 确认balancer已经打开。

STEP2 运行命令:
  1. db.runCommand( { removeShard: "mongodb0" } )
复制代码
mongodb0是需要删除的分片的名字。这时balancer进程会开始把要删除掉的分片上的数据往别的分片上迁移。

STEP3 查看是否删除完

还是运行上面那条removeShard命令

如果还未删除完数据则返回:
  1. { msg: "draining ongoing" , state: "ongoing" , remaining: { chunks: NumberLong(42), dbs : NumberLong(1) }, ok: 1 }
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
16#
 楼主| 发表于 2014-2-7 15:04 | 只看该作者
STEP4 删除unsharded data

有一些分片上保存上一些unsharded data, 需要迁移到其他分片上:

可以用sh.status()查看分片上是否有unsharded data。

如果有则显示:
  1. { "_id" : "products", "partitioned" : true, "primary" : "mongodb0" }
复制代码
用下面的命令迁移:
  1. db.runCommand( { movePrimary: "products", to: "mongodb1" })
复制代码
只有全部迁移完上面的命令才会返回:
  1. { "primary" : "mongodb1", "ok" : 1 }
复制代码
STEP5 最后运行命令
  1. db.runCommand( { removeShard: "mongodb0" } )
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
17#
 楼主| 发表于 2014-2-7 15:06 | 只看该作者
手动迁移分片

一般情况下你不需要这么做,只有当一些特殊情况发生时,比如:
1)预分配空的集合时
2)在balancing时间窗之外

手动迁移的方法:
  1. chunks:
  2.                                 shard0000       2
  3.                                 shard0001       2
  4.                         { "zipcode" : { "$minKey" : 1 } } -->> { "zipcode" : 10001 } on : shard0000 Timestamp(6, 0)
  5.                         { "zipcode" : 10001 } -->> { "zipcode" : 23772 } on : shard0001 Timestamp(6, 1)
  6.                         { "zipcode" : 23772 } -->> { "zipcode" : 588377 } on : shard0001 Timestamp(3, 2)
  7.                         { "zipcode" : 588377 } -->> { "zipcode" : { "$maxKey" : 1 } } on : shard0000 Timestamp(5, 1)
  8. mongos> db.adminCommand({moveChunk: "contact.people", find:{zipcode:10003}, to:"192.168.1.135:20002"})
  9. { "millis" : 2207, "ok" : 1 }
  10. mongos> sh.status()
  11. --- Sharding Status ---
  12.   sharding version: {
  13.         "_id" : 1,
  14.         "version" : 3,
  15.         "minCompatibleVersion" : 3,
  16.         "currentVersion" : 4,
  17.         "clusterId" : ObjectId("52ece49ae6ab22400d937891")
  18. }
  19.   shards:
  20.         {  "_id" : "shard0000",  "host" : "192.168.1.135:20002" }
  21.         {  "_id" : "shard0001",  "host" : "192.168.1.135:20003" }
  22.   databases:
  23.         {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
  24.         {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
  25.         {  "_id" : "contact",  "partitioned" : true,  "primary" : "shard0000" }
  26.                 contact.people
  27.                         shard key: { "zipcode" : 1 }
  28.                         chunks:
  29.                                 shard0000       3
  30.                                 shard0001       1
  31.                         { "zipcode" : { "$minKey" : 1 } } -->> { "zipcode" : 10001 } on : shard0000 Timestamp(6, 0)
  32.                         { "zipcode" : 10001 } -->> { "zipcode" : 23772 } on : shard0000 Timestamp(7, 0)
  33.                         { "zipcode" : 23772 } -->> { "zipcode" : 588377 } on : shard0001 Timestamp(7, 1)
  34.                         { "zipcode" : 588377 } -->> { "zipcode" : { "$maxKey" : 1 } } on : shard0000 Timestamp(5, 1)

  35. mongos>
复制代码

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
18#
 楼主| 发表于 2014-2-7 15:07 | 只看该作者
预分配空chunk

这是一种提高写效率的方法。相当于在写入真实数据之前,就分配好了数据桶,然后再对号入座。省去了创建chunk和split的时间。

实际上使用的是split命令:
  1. db.runCommand( { split : "myapp.users" , middle : { email : prefix } } );
复制代码
myapp.users 是 collection的名字。
middle参数是split的点。

split命令如下:
  1. db.adminCommand( { split: <database>.<collection>, <find|middle|bounds> } )
复制代码
find 表示查找到的记录进行分裂
bounds是指定[low, up]分裂
middle是指定分裂的点。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
19#
 楼主| 发表于 2014-2-7 15:09 | 只看该作者
一个预分配chunk的例子如下:
  1. for ( var x=97; x<97+26; x++ ){
  2.   for( var y=97; y<97+26; y+=6 ) {
  3.     var prefix = String.fromCharCode(x) + String.fromCharCode(y);
  4.     db.runCommand( { split : "myapp.users" , middle : { email : prefix } } );
  5.   }
  6. }
复制代码
这个预分配的目的是字母顺序有一定间隔的email, 分配到不同的chunk里。
例如aa-ag到一个chunk
ag-am到一个chunk

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
20#
 楼主| 发表于 2014-2-7 15:09 | 只看该作者
预分配的结果如下:
  1. { "email" : { "$minKey" : 1 } } -->> { "email" : "aa" } on : shard0001 Timestamp(2, 0)
  2. { "email" : "aa" } -->> { "email" : "ag" } on : shard0001 Timestamp(3, 0)
  3. { "email" : "ag" } -->> { "email" : "am" } on : shard0001 Timestamp(4, 0)
  4. { "email" : "am" } -->> { "email" : "as" } on : shard0001 Timestamp(5, 0)
  5. { "email" : "as" } -->> { "email" : "ay" } on : shard0001 Timestamp(6, 0)
  6. ...
  7. { "email" : "zm" } -->> { "email" : "zs" } on : shard0000 Timestamp(1, 257)
  8. { "email" : "zs" } -->> { "email" : "zy" } on : shard0000 Timestamp(1, 259)
  9. { "email" : "zy" } -->> { "email" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 260)
复制代码

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表