引述
在Mongodb里面存在另一种集群,就是分片技术,可以满足MongoDB数据量大量增长的需求。
当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
结构
分片集群结构图:
- Shard: 用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障
- Config Server: mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。
- Query Routers: 前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。
实例
别名 | 类型 | 地址 |
---|---|---|
shard1 | Shard Server | 192.168.0.114:29011 |
shard2 | Shard Server | 192.168.0.114:29012 |
shard3 | Shard Server | 192.168.0.114:29013 |
config | Config Server | 192.168.0.114:29014 |
router | Router Server | 192.168.0.114:29015 |
由于本例是配置文件启动的,所以贴出配置文件,仅仅是把命令放到配置文件中而已.
配置文件
shard:
举例为shard1的conf,除了路径和端口不同,其他shard同理.
dbpath=D:\mongoShard\shard1\data #数据库路径
logpath=D:\mongoShard\shard1\logs\mongodb.log #日志输出文件路径
logappend=true #错误日志采用追加模式,配置这个选项后mongodb的日志会追加到现有的日志文件,而不是从新创建一个新文件
journal=true #启用日志文件,默认启用
quiet=false #这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
port=29011 #端口号
maxConns=20000
auth=false #开启验证
rest = false #禁止rest接口
nohttpinterface = true #禁止HTTP状态接口
config:
dbpath=D:\mongoShard\shardConfig\data #数据库路径
logpath=D:\mongoShard\shardConfig\logs\mongodb.log #日志输出文件路径
logappend=true #错误日志采用追加模式,配置这个选项后mongodb的日志会追加到现有的日志文件,而不是从新创建一个新文件
journal=true #启用日志文件,默认启用
quiet=false #这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
port=29014 #端口号
configsvr=true
router:
注意这里不需要dbpath等等
logpath=D:\mongoShard\route\logs\mongodb.log #日志输出文件路径
logappend=true #错误日志采用追加模式,配置这个选项后mongodb的日志会追加到现有的日志文件,而不是从新创建一个新文件
port=29015 #端口号
configdb=192.168.0.114:29014
chunkSize=500#这一项是用来指定chunk的大小的,单位是MB,默认大小为200MB.
###启动
就像启动普通mongodb一样
mongod -config=D:\mongoShard\shard1\conf\mongodb.conf
mongod -config=D:\mongoShard\shard2\conf\mongodb.conf
mongod -config=D:\mongoShard\shard3\conf\mongodb.conf
mongod --config=D:\mongoShard\shardConfig\conf\mongodb.conf
mongos -config=D:\mongoShard\route\conf\mongodb.conf
全部启动完之后,看下日志,如果没有什么异常,就可以继续干了,反之查看错误,根据错误进行修改呗.
添加shard
主要分为以下几步:
- 连接Router Server
- 切换到admin db
- 添加shard
- 设置分片存储的数据库
- 设置表对应的片键
- 测试
//第一步
C:\Users\Administrator>mongo --port 29015
MongoDB shell version: 3.0.6
connecting to: 127.0.0.1:29015/test
mongos> db.runCommand({addshard:"192.168.0.114:29011"})
//出现这个错误,懵逼了,查了下,要在admin下进行,所以要切换到admin下面,use admin 即可
2017-02-23T14:03:25.595+0800 E QUERY Error: error: {
"$err" : "error creating initial database config information :: caused by :: can't find a shard to put new db on",
"code" : 10185
}
at Error (<anonymous>)
at DBQuery.next (src/mongo/shell/query.js:259:15)
at DBCollection.findOne (src/mongo/shell/collection.js:189:22)
at DB.runCommand (src/mongo/shell/db.js:58:41)
at (shell):1:4 at src/mongo/shell/query.js:259
//第二步
mongos> use admin
switched to db admin
//第三步
mongos> db.runCommand({addshard:"192.168.0.114:29012"})
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> db.runCommand({addshard:"192.168.0.114:29011"})
{ "shardAdded" : "shard0001", "ok" : 1 }
mongos> db.runCommand({addshard:"192.168.0.114:29013"})
{ "shardAdded" : "shard0002", "ok" : 1 }
//第四步
mongos> db.runCommand({ enablesharding:"testshard" })
{ "ok" : 1 }
//第五步
mongos> db.runCommand({ shardcollection: "testshard.log", key: { id:1,time:1}})
{ "collectionsharded" : "testshard.log", "ok" : 1 }
mongos> use testshard
switched to db testshard
//第六步
mongos> for(i=0;i<500000;i++){ db.bar.insert({"uid":i,"description":"this is a very long description for " + i,"Date":new Date()}); }
WriteResult({ "nInserted" : 1 })
//查看配置文件状态
mongos> printShardingStatus(db.getSisterDB("config"),1)
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("58ae7971d29e949c15747b8d")
}
shards:
{ "_id" : "shard0000", "host" : "192.168.0.114:29012" }
{ "_id" : "shard0001", "host" : "192.168.0.114:29011" }
{ "_id" : "shard0002", "host" : "192.168.0.114:29013" }
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "testshard", "partitioned" : true, "primary" : "shard0001" }
testshard.log
shard key: { "id" : 1, "time" : 1 }
chunks:
shard0001 1
{ "id" : { "$minKey" : 1 }, "time" : { "$minKey" : 1 } } -->> { "id" : { "$maxKey" : 1 }, "time" : { "$maxKey" : 1 } } on : shard0001 Timestamp(1, 0)
//查看表状态
mongos> db.bar.stats()
{
"sharded" : false,
"primary" : "shard0001",
"ns" : "testshard.bar",
"count" : 0,
"size" : 0,
"numExtents" : 10,
"storageSize" : 86310912,
"lastExtentSize" : 27869184,
"paddingFactor" : 1,
"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.",
"userFlags" : 1,
"capped" : false,
"nindexes" : 1,
"totalIndexSize" : 8176,
"indexSizes" : {
"_id_" : 8176
},
"ok" : 1
}
mongos> show dbs
admin (empty)
config 0.016GB
testshard 0.203GB
片键
一个好的片键应该具备良好的数据局部性,但又不会因为太局部而导致热点出现.
本人还没有太深奥的去研究过,没有实战机会.可以参考下这个MongoDB分片中片键的选择,以后研究研究再专门发表一篇好了
还望各路大神多多指导