MongoDB集群的Sharding详解

转自:http://www.itpub.net/thread-1843459-1-1.html

为何需要水平分片

1)减少单机请求数,将单机负载,提高总负载

2)减少单机的存储空间,提高总存空间。

下图一目了然:

MongoDB, 集群

mongodb sharding 服务器架构


简单注解:
1)mongos路由进程,应用程序接入mongos再查询到具体分片。
2)config server路由表服务。每一台都具有全部chunk的路由信息。
3)shard为数据存储分片。每一片都可以是复制集(replica set)。

如何部署分片集群step 1:启动config server

  1. mkdir
  2. /data/configdb

  3. mongod
  4. --configsvr --dbpath /data/configdb --port 27019
复制代码

正式生产环境一般启动3config server 启动3个是为了做热备。

step 2:启动mongos

  1. mongos
  2. --configdb cfg0.example.net:27019,cfg1.example.net:27019,cfg2.example.net:27019
复制代码

step3:启动分片mongod

分片就是普通的mongod

  1. mongod
  2. --dbpath --port
复制代码

step4:在mongos添加分片

mongo 连接上mongos 然后通过Mongo命令行输入:

添加非replica set作为分片:

  1. sh.addShard(
  2. "mongodb0.example.net:27017" )
复制代码

添加replica set作为分片:

  1. sh.addShard(
  2. "rs1/mongodb0.example.net:27017" )
复制代码

step5:对某个数据库启用分片

  1. sh.enableSharding("")
复制代码

这里只是标识这个数据库可以启用分片,但实际上并没有进行分片。

step6:对collection进行分片


分片时需要指定分片的key语法为

  1. sh.shardCollection(".",
  2. shard-key-pattern)
复制代码

例子为:

  1. sh.shardCollection("records.people",
  2. { "zipcode": 1, "name": 1 } )

  3. sh.shardCollection("people.addresses",
  4. { "state": 1, "_id": 1 } )

  5. sh.shardCollection("assets.chairs",
  6. { "type": 1, "_id": 1 } )



  7. db.alerts.ensureIndex(
  8. { _id : "hashed" } )

  9. sh.shardCollection("events.alerts",
  10. { "_id": "hashed" } )
复制代码

最后一个为hash sharded key hash sharded key是为了解决某些情况下shardedkey write scaling的问题。


如何选择shard key

1)shard key需要有高的cardinality 。 也就是shard key需要拥有很多不同的值。 便于数据的切分和迁移。

2)尽量与应用程序融合。让mongos面对查询时可以直接定位到某个shard。

3)具有随机性。这是为了不会让某段时间内的insert请求全部集中到某个单独的分片上,造成单片的写速度成为整个集群的瓶颈。用objectId作为shard key时会发生随机性差情况。 ObjectId实际上由进程ID+TIMESTAMP + 其他因素组成, 所以一段时间内的timestamp会相对集中。

不过随机性高会有一个副作用,就是query isolation性比较差。

可用hash key增加随机性。

如何查看shard信息

登上mongos
sh.status()或者需要看详细一点
sh.status({verbose:true})

  1. Sharding Status ---
  2.   sharding version: { "_id" : 1, "version" : 3 }
  3.   shards:
  4.     {  "_id" : "shard0000",  "host" : "m0.example.net:30001" }
  5.     {  "_id" : "shard0001",  "host" : "m3.example2.net:50000" }
  6.   databases:
  7.     {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
  8.     {  "_id" : "contacts",  "partitioned" : true,  "primary" : "shard0000" }
  9.         foo.contacts
  10.             shard key: { "zip" : 1 }
  11.             chunks:
  12.                 shard0001    2
  13.                 shard0002    3
  14.                 shard0000    2
  15.             { "zip" : { "$minKey" : 1 } } -->> { "zip" : 56000 } on : shard0001 { "t" : 2, "i" : 0 }
  16.             { "zip" : 56000 } -->> { "zip" : 56800 } on : shard0002 { "t" : 3, "i" : 4 }
  17.             { "zip" : 56800 } -->> { "zip" : 57088 } on : shard0002 { "t" : 4, "i" : 2 }
  18.             { "zip" : 57088 } -->> { "zip" : 57500 } on : shard0002 { "t" : 4, "i" : 3 }
  19.             { "zip" : 57500 } -->> { "zip" : 58140 } on : shard0001 { "t" : 4, "i" : 0 }
  20.             { "zip" : 58140 } -->> { "zip" : 59000 } on : shard0000 { "t" : 4, "i" : 1 }
  21.             { "zip" : 59000 } -->> { "zip" : { "$maxKey" : 1 } } on : shard0000 { "t" : 3, "i" : 3 }
  22.     {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0000" }
复制代码

备份cluster meta information

Step1:disable balance process. 连接上Mongos

  1. sh.setBalancerState(false)
复制代码
Step2:关闭config server

Step3:备份数据文件夹

Step4:重启config server

Step5:enable balance process.
  1. sh.setBalancerState(false)
复制代码

查看balance 状态

可以通过下面的命令来查看当前的balance进程状态。先连接到任意一台mongos

  1. use config
  2. db.locks.find( { _id : "balancer" } ).pretty()
  3. {   "_id" : "balancer",
  4. "process" : "mongos0.example.net:1292810611:1804289383",
  5.   "state" : 2,
  6.      "ts" : ObjectId("4d0f872630c42d1978be8a2e"),
  7.    "when" : "Mon Dec 20 2010 11:41:10 GMT-0500 (EST)",
  8.     "who" : "mongos0.example.net:1292810611:1804289383:Balancer:846930886",
  9.     "why" : "doing balance round" }
复制代码
state=2 表示正在进行balance, 在2.0版本之前这个值是1

配置balance时间窗口

可以通过balance时间窗口指定在一天之内的某段时间之内可以进行balance, 其他时间不得进行balance。

先连接到任意一台mongos

  1. use config
  2. db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "23:00", stop :"6:00" } } }, true )
复制代码
这个设置让只有从23:00到6:00之间可以进行balance。

也可以取消时间窗口设置:
  1. use config
  2. db.settings.update({ _id : "balancer" }, { $unset : { activeWindow : true } })
复制代码


你可能感兴趣的:(MongoDB集群的Sharding详解)