Why shard?
在传统架构中, 当数据量庞大到一台机器或单个 db 实例无法容纳的时候,我们会对数据进行横向或纵向切割, 例如 分表 或分库,这样做是为了把压力分摊到多个数据节点上.但缺点也很明显,分离后的数据没有完整性,查询起来比较麻烦, 可能还需要开发数据库中间件.
mongo shard 帮我们解决这一问题, 当数据写入时, mongos 会根据 shard key 自动将请求 router 其中一台 Slave 上
组建简单的 mongodb 集群
首先,我们需要这三样东西:
名称 | 作用 |
---|---|
config Server | 配置节点,保存整个集群的元数据,非常重要,如果元数据丢失则,整个集群便无法使用 |
mongos | 路由节点,其本身并不储存数据,他的工作主要是路由请求到指定 shard 上 |
shard | 片节点, 真正储存数据的节点,但每个片节点上只保存一部分数据 |
简单来说,就是一个请求需要先 route 到 mongos 节点
,其根据 config 节点
的配置将其发送到某一台 shard 节点
上
1.启动 config 服务器:
我们启动 3 台 config 节点
mongod
--configsvr
--dbpath "./config1/data"
--port 21001
--keyFile "../mongo.key"
--logpath "./log1/config.log"
--auth
mongod
--configsvr
--dbpath "./config2/data"
--port 21002
--keyFile "../mongo.key"
--logpath "./log2/config.log"
--auth
mongod
--configsvr
--dbpath "./config3/data"
--port 21003
--keyFile "../mongo.key"
--logpath "./log3/config.log"
--auth
keyFile 是多台服务器间通信的认证凭据
注意当指定 --keyFile 后 --auth 会默认生效,这时你就不能在使用匿名账号登录了.
2.启动 mongos 路由:
我们启动 2 台 mongos 路由节点
mongos
--port 20001
--configdb domain.com:21001,domain.com:21002,domain.com:21003
--keyFile "../mongo.key"
--logpath "./log/mongos1.log"
mongos
--port 20002
--configdb domain.com:21001,domain.com:21002,domain.com:21003
--keyFile "../mongo.key"
--logpath "../log/mongos2.log"
3.启动 shard 节点:
shard 是真正储存数据的节点. 同样,我们启动 3 台 shard 节点.
mongod
--shardsvr
--port 22001
--dbpath "./shard1/data"
--keyFile "../mongo.key"
--logpath "./log/shard1.log"
mongod
--shardsvr
--port 22002
--dbpath "./shard2/data"
--keyFile "../mongo.key"
--logpath "./log/shard2.log"
mongod
--shardsvr
--port 22003
--dbpath "./shard3/data"
--keyFile "../mongo.key"
--logpath "./log/shard3.log"
4.注册 shard 节点:
完成上述启动后,我们还需要向集群注册我们的 shard 节点, 以把这些节点串起来.
db.runCommand({addshard:"domain.com",allowLocal:true })
db.runCommand({addshard:"domain.com",allowLocal:true })
db.runCommand({addshard:"domain.com",allowLocal:true })
注册后登录任意一台 mongos 节点,指定那些库,和集合需要使用 shard
db.runCommand( { enablesharding :"myShardDB"});
db.runCommand( { shardcollection : "myShardDB.collection1",key : {"createTime":1,"_id": 1} } )
db.runCommand( { shardcollection : "myShardDB.collection2",key : {"createTime":1,"_id": 1} } )
这样一个最基本的集群就完成了. 今后如果我们需要向集群中再添加节点时
再次运行 db.runCommand({addshard:"domain.com",allowLocal:true }) 即可.
原则上shard 最好不要删除. 但必要时我们可以使用 removeshard 命令来移除.
进入 config 库,我们可以查看目前的分片情况.
use config
db.shards.find()
> { "_id" : "shard0000", "host" : "domain.com:22001" }
> { "_id" : "shard0001", "host" : "domain.com:22002" }
> { "_id" : "shard0002", "host" : "domain.com:22003" }