Mongodb高可用架构
健壮方案
1. 多个配置服务器
2. 多个mongos服务器
3. 每个片都是副本集
4. 正确配置w
阻塞复制
开发者可以用gerLastError的"w"参数来确保数据的同步性.这里运行gerLastError会进入阻塞状态,知道n个
服务器复制了嘴型的写入操作为止
db.runCommand({"gerLastError":1,w:N})
如果没有N,或者小于2命令就会立刻返回,如果N等于2,主节点要等到至少一个从节点复制了上个操作才会响应命令
主节点本身也包括在N里面.主节点使用local.slaves中存放的"syncedTo"信息跟踪从节点的更新情况.
指定"w"选项后,还可以使用"wtimeout"选项,表示以毫秒为单位的超时,gerLastError就能在上一个操作复制到N个
节点超时返回错误(默认情况下没有超时)
阻塞复制会导致写操作变慢,尤其"w"的值比较大时.实际上,对重要操作将其值设为2或3就能效率和安全兼备了.
健壮的配置
设置多个配置服务器是很简单的.
设置多个配置服务器和设置一个配置服务器一样
mongod --dbpath"F:\mongo\dbs\config" --port 20000 --logpath"F:\mongo\logs\config\MongoDB.txt" --rest
mongod --dbpath"F:\mongo\dbs\config1" --port 20001 --logpath"F:\mongo\logs\config1\MongoDB.txt" --rest
mongod --dbpath"F:\mongo\dbs\config2" --port 20002 --logpath"F:\mongo\logs\config2\MongoDB.txt" --rest
启动mongos的时候应将其连接到3个配置服务器上:
mongos --port 30000--configdb 127.0.0.1:20000,127.0.0.1:20001,127.0.0.1:20002 --logpath"F:\mongo\logs\mongos\MongoDB.txt"
配置服务器使用的是两步提交机制,而不是普通的MongoDB的异步复制,来维护集群配置的不同副本.这样能保证集群的状态
的一致性.这意味着,某台配置服务器宕机后,集群的配置信息是只读的.客户端还是能够读写,但是只有所有配置服务器备份了
以后才能重新均衡数据.
多个mongos
mongos的数量不受限制,建议针对一个应用服务器只运行一个mongos进程.这样每个应用服务器就可以与mongos进行
本地回话,如果服务器不工作了,就不会有应用试图与不存的mongos通话了
健壮的片
生产环境中,每个片都应是副本集,这样单个服务器坏了,就不会导致整个片失效.用addshard命令就可以将副本集作为片添加,
添加时,只要指定副本集的名称和种子就行了.
如要添加副本集refactor,其中包含一个服务器127.0.0.1:10000(还有别的服务器),就可以用下列命令将其添加到集群中:
db.runCommand({"addshard":"refactor/127.0.0.1:10000"})
如果127.0.0.1:10000服务器挂了,mongos会知道它所连接的是一个副本集,并会使用新的主节点.
物理服务器
貌似需要太多机器了:3个配置服务器,每片最少两个mongod,还有若干mongos进程。但是这些不一定都需要单独的服务器。重要的是不把所有的鸡蛋放在同一个篮子里。好比不把所有3个配置服务器放到一台机器上,不把所有mongos放到一台机器上,不把这个副本集放到一台服务器上。但是可以把一个配置服务器、一些mongos进程和副本集的一个节点放到一个服务器上。
实例健壮架构
每个分片3服务器,前期采用三台,日后服务器的增加考虑灾备,服务增加的基数最少为两台。
实际的一个线上配置:
类型 | 服务器 | 用途 | 系统 | 说明 |
存储/数据 | Server1 | Shard1/Shard2/Shard3 | Linux 64位 | Shard1:10001;Shard2:10002,Shard3:10003; |
Server2 | Shard1/Shard2/Shard3 | Linux 64位 | Shard1:10001;Shard2:10002,Shard3:10003; | |
Server3 | Shard1/Shard2/Shard3 | Linux 64位 | Shard1:10001;Shard2:10002,Shard3:10003; | |
配置 | Server1 | Config1 | Linux 64位 | Config1:20000; |
Server2 | Config2 | Linux 64位 | Config2:20000; | |
Serve3 | Config3 | Linux 64位 | Config3:20000; | |
路由 | Server1 | Mongos1 | Linux 64位 | Mongos:30000 |
Server2 | Mongos2 | Linux 64位 | Mongos:30000 | |
Server3 | Mongos3 | Linux 64位 | Mongos:30000 |
(表:一)
实例
1.准备:创建目录
[root@localhost node3]# mkdir -p./data/shard1/
[root@localhost node3]# mkdir -p./data/shard2/
[root@localhost node3]# mkdir -p./data/shard3/
[root@localhost node3]# mkdir -p./data/log/
[root@localhost node3]# mkdir -p./data/config/
启动mongod服务
启动shard1服务
bin/mongod -shardsvr -port 10001 -dbpath=./data/shard1/ -logpath=./data/log/shard1.log --fork |
启动shard2服务:
bin/mongod -shardsvr -port 10002 -dbpath=./data/shard2/ -logpath=./data/log/shard2.log --fork |
启动shard3服务:
bin/mongod -shardsvr -port 10003 -dbpath=./data/shard3/ -logpath=./data/log/shard3.log --fork |
查看一下mongod进程:
构建config:
bin/mongod -configsvr -dbpath=./data/config -port 20000 -logpath=./data/log/config.log --fork |
创建shard1副本集:
80:
./bin/mongod --dbpath ./data/shard1 --logpath ./data/log/shard1.log --port 10001 --replSet ymongo/192.168.192.75:10001 |
75:
./bin/mongod --dbpath ./data/shard1 --logpath ./data/log/shard1.log --port 10001 --replSet ymongo/192.168.229.80:10001 |
68:
./bin/mongod --dbpath ./data/shard1 --logpath ./data/log/shard1.log --port 10001 --replSet mymongo/192.168.192.75:10001,192.168.229.80:10001 |
初始化shard1副本集:
db.runCommand({ "replSetInitiate":{ "_id":"mymongo", "members":[ { "_id":1, "host":"192.168.229.80:10001", "priority":3 }, { "_id":2, "host":"192.168.192.75:10001", "priority":2 }, { "_id":3, "host":"192.168.192.68:10001", "priority":1 } ] } }); |
创建shard2副本集:
80:
./bin/mongod --dbpath ./data/shard2 --logpath ./data/log/shard2.log --port 10002 --replSet mymongo2/192.168.192.75:10002 |
75:
./bin/mongod --dbpath ./data/shard2 --logpath ./data/log/shard2.log --port 10002 --replSet mymongo2/192.168.229.80:10002 |
68:
./bin/mongod --dbpath ./data/shard2 --logpath ./data/log/shard2.log --port 10002 --replSet mymongo2/192.168.192.75:10002,192.168.229.80:10002 |
初始化shard2副本集:
db.runCommand({ "replSetInitiate":{ "_id":"mymongo2", "members":[ { "_id":1, "host":"192.168.229.80:10002", "priority":3 }, { "_id":2, "host":"192.168.192.75:10002", "priority":2 }, { "_id":3, "host":"192.168.192.68:10002", "priority":1 } ] } }); |
创建shard3副本集:
80:
./bin/mongod --dbpath ./data/shard3 --logpath ./data/log/shard3.log --port 10003 --replSet mymongo3/192.168.192.75:10003 |
75:
./bin/mongod --dbpath ./data/shard3 --logpath ./data/log/shard3.log --port 10003 --replSet mymongo3/192.168.229.80:10003 |
68:
./bin/mongod --dbpath ./data/shard3 --logpath ./data/log/shard3.log --port 10003 --replSet mymongo3/192.168.192.75:10003,192.168.229.80:10003 |
初始化shard3副本集:
db.runCommand({ "replSetInitiate":{ "_id":"mymongo3", "members":[ { "_id":1, "host":"192.168.229.80:10003", "priority":3 }, { "_id":2, "host":"192.168.192.75:10003", "priority":2 }, { "_id":3, "host":"192.168.192.68:10003", "priority":1 } ] } }); |
配置mongos:
启动mongos进程:
bin/mongos -configdb 192.168.229.80:20000,192.168.192.75:20000,192.168.192.68:20000 -port 30000 -chunkSize 1 -logpath=./data/mongos.log --fork |
链接mongos:
./bin/mongo192.168.192.75:30000/admin
添加片:
db.runCommand({"addshard":"mymongo/192.168.229.80:10001,192.168.192.75:10001,192.168.192.68:10001","name":"mymongo"}); db.runCommand({"addshard":"mymongo2/192.168.229.80:10002,192.168.192.75:10002,192.168.192.68:10002","name":"mymongo2"}); db.runCommand({"addshard":"mymongo3/192.168.229.80:10003,192.168.192.75:10003,192.168.192.68:10003","name":"s1"}); |
验证是否ok:
db.runCommand({ listshards : 1 } )
如果列出了以上二个你加的shards,表示shards已经配置成功
激活分片设置
mongos> db.runCommand({"enablesharding": "mydb"}) { "ok" : 1 } |
通过执行以上命令,可以让数据库跨shard,如果不执行这步,数据库只会存放在一个shard,一旦激活数据库分片,数据库中不同的collection将被存放在不同的shard上,但一个collection仍旧存放在同一个shard上,要使单个collection也分片,还需单独对 collection作些操作
激活分键设置:
mongos> db.runCommand({"shardcollection":"mydb.user", "key":{"_id":1}}) { "collectionsharded" : "mydb.user", "ok" : 1 } |
验证结果
查看现在三台服务器的进程:
查看mongos进程: