转自:http://www.itpub.net/thread-1843459-1-1.html
为何需要水平分片 1)减少单机请求数,将单机负载,提高总负载 2)减少单机的存储空间,提高总存空间。 下图一目了然: |

简单注解:
1)mongos路由进程,应用程序接入mongos再查询到具体分片。
2)config server路由表服务。每一台都具有全部chunk的路由信息。
3)shard为数据存储分片。每一片都可以是复制集(replica set)。
如何部署分片集群step 1:启动config server
- mkdir
- /data/configdb
- mongod
- --configsvr --dbpath /data/configdb --port 27019
正式生产环境一般启动3个config server。 启动3个是为了做热备。
step 2:启动mongos
- mongos
- --configdb cfg0.example.net:27019,cfg1.example.net:27019,cfg2.example.net:27019
分片就是普通的mongod
- mongod
- --dbpath <path> --port <port>
用mongo 连接上mongos, 然后通过Mongo命令行输入:
添加非replica set作为分片:
- sh.addShard(
- "mongodb0.example.net:27017" )
添加replica set作为分片:
- sh.addShard(
- "rs1/mongodb0.example.net:27017" )
- sh.enableSharding("<database>")
这里只是标识这个数据库可以启用分片,但实际上并没有进行分片。
step6:对collection进行分片
分片时需要指定分片的key,语法为
- sh.shardCollection("<database>.<collection>",
- shard-key-pattern)
例子为:
- sh.shardCollection("records.people",
- { "zipcode": 1, "name": 1 } )
- sh.shardCollection("people.addresses",
- { "state": 1, "_id": 1 } )
- sh.shardCollection("assets.chairs",
- { "type": 1, "_id": 1 } )
- db.alerts.ensureIndex(
- { _id : "hashed" } )
- sh.shardCollection("events.alerts",
- { "_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})
- Sharding Status ---
- sharding version: { "_id" : 1, "version" : 3 }
- shards:
- { "_id" : "shard0000", "host" : "m0.example.net:30001" }
- { "_id" : "shard0001", "host" : "m3.example2.net:50000" }
- databases:
- { "_id" : "admin", "partitioned" : false, "primary" : "config" }
- { "_id" : "contacts", "partitioned" : true, "primary" : "shard0000" }
- foo.contacts
- shard key: { "zip" : 1 }
- chunks:
- shard0001 2
- shard0002 3
- shard0000 2
- { "zip" : { "$minKey" : 1 } } -->> { "zip" : 56000 } on : shard0001 { "t" : 2, "i" : 0 }
- { "zip" : 56000 } -->> { "zip" : 56800 } on : shard0002 { "t" : 3, "i" : 4 }
- { "zip" : 56800 } -->> { "zip" : 57088 } on : shard0002 { "t" : 4, "i" : 2 }
- { "zip" : 57088 } -->> { "zip" : 57500 } on : shard0002 { "t" : 4, "i" : 3 }
- { "zip" : 57500 } -->> { "zip" : 58140 } on : shard0001 { "t" : 4, "i" : 0 }
- { "zip" : 58140 } -->> { "zip" : 59000 } on : shard0000 { "t" : 4, "i" : 1 }
- { "zip" : 59000 } -->> { "zip" : { "$maxKey" : 1 } } on : shard0000 { "t" : 3, "i" : 3 }
- { "_id" : "test", "partitioned" : false, "primary" : "shard0000" }
备份cluster meta information
Step1:disable balance process. 连接上Mongos
- sh.setBalancerState(false)
Step3:备份数据文件夹
Step4:重启config server
Step5:enable balance process.
- sh.setBalancerState(false)
查看balance 状态
可以通过下面的命令来查看当前的balance进程状态。先连接到任意一台mongos
- use config
- db.locks.find( { _id : "balancer" } ).pretty()
- { "_id" : "balancer",
- "process" : "mongos0.example.net:1292810611:1804289383",
- "state" : 2,
- "ts" : ObjectId("4d0f872630c42d1978be8a2e"),
- "when" : "Mon Dec 20 2010 11:41:10 GMT-0500 (EST)",
- "who" : "mongos0.example.net:1292810611:1804289383:Balancer:846930886",
- "why" : "doing balance round" }
配置balance时间窗口
可以通过balance时间窗口指定在一天之内的某段时间之内可以进行balance, 其他时间不得进行balance。
先连接到任意一台mongos
- use config
- db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "23:00", stop :"6:00" } } }, true )
也可以取消时间窗口设置:
- use config
- db.settings.update({ _id : "balancer" }, { $unset : { activeWindow : true } })