第一部分
在搭建mongoDB之前,我們要考慮幾個小問題:
1、我們搭建集群的目的是什么?是多備份提高容錯和系統可用性還是橫向拓展存儲大規模數據還是兩者兼有?
如果是為了多備份那么選擇replication集群搭建即可,如果是為了處理大數據則需要搭建sharding集群,如果兩者兼有需要對每個shardsvr創建replica。
2、什么是sharding?和replication有什么不同?
簡單而言,replica是mongo提供服務的一個基本單位,單機系統和replication集群對用戶來講沒有區別,都只相當於一個服務節點,只不過replication集群有多備份,還有服務端選舉,安全性更加有保證。而sharding集群包含3個角色:mongos,configsvr,shardsvr,對於一個集群來說mongos相當於master,負責對外提供服務,shardsvr相當於slave,負責分片存儲數據,而configsvr相當於router,負責記錄分片元信息。這3種角色中的任何一個角色中的子節點都是一個replica。具體說明參考官方網站對sharding和replication的描述:
replication:https://docs.mongodb.com/manual/replication/
sharding:https://docs.mongodb.com/manual/sharding/
3、我們集群的架構又該是什么樣子?
如果對問題1和2有足夠的認知的話,那么根據本地硬件環境構建一個什么樣的集群大致也就清楚了,每個shardsvr的replication相當於一個slave,我們需要幾個子節點就需要創建多少個shardsvr,configsvr是router信息,我們可以將所有機器都組成一個configsvr的replication用以提供router服務,至於mongos,內部使用一個節點也可以,如果需要穩定運行的話也需要組一個小的mongos的replication。
第二部分
下面是實戰環節:
我這可以有5台服務器用來跑mongodb還有一批數據,當然,這5台機器上也跑着其他框架如spark,hadoop等等,由於spark和hadoop都是單點故障的(什么?多master?secondary?不存在的,老夫部署集群從來都是單點故障)所以mongos也是一台節點,數據端存放在5台機器上,又由於數據量較大,硬盤較小(別人組的raid5,加一起一台服務器也就1T多空間),所以肯定不考慮備份和穩定性了(2備份硬盤就沒多大地方了,hdfs還有其他數據要放),那么架構可以構建如下:
下面shardsvr每一個都是一個單獨的replica,開始部署:
1、創建配置文件:
a) configsvr
systemLog: destination: file path: "/home/cloud/platform/logs/mongodb/configsvr.log" logAppend: true storage: dbPath: "/home/cloud/platform/data/configData" journal: enabled: true setParameter: enableLocalhostAuthBypass: false processManagement: fork: true replication: replSetName: "configsvr0" sharding: clusterRole: "configsvr"
b) shardsvr
systemLog: destination: file path: "/home/cloud/platform/logs/mongodb/shardsvr.log" logAppend: true storage: dbPath: "/home/cloud/platform/data/shardData" journal: enabled: true setParameter: enableLocalhostAuthBypass: false processManagement: fork: true replication: replSetName: "shardsvr1" sharding: clusterRole: "shardsvr"
c) mongos
systemLog: destination: file path: "/home/cloud/platform/logs/mongodb/mongos.log" logAppend: true net: bindIp: 192.168.12.161 port: 27017 setParameter: enableLocalhostAuthBypass: false processManagement: fork: true sharding: configDB: "configsvr0/192.168.12.161:27019,192.168.12.162:27019,192.168.12.163:27019,192.168.12.164:27019,192.168.12.169:27019"
注意:每台機器上的配置都略有不同,簡易參考官方文檔進行修改,replSetName這個是replication的設置,每個角色的子replication應該有相同的值,不同的replication應該有不同的值
接下來是啟動腳本
a)shardsvr
#!/bin/bash # use this to initiate: rs.initiate({_id:"shardsvr1",members:[{_id:0,host:"192.168.12.161:27018"}]}) /home/cloud/platform/mongodb-3.4.5/bin/mongod --config /home/cloud/platform/mongodb-3.4.5/shardserver.conf
b)configsvr
#!/bin/bash #use this to initiate: rs.initiate({_id:"configsvr0",configsvr:true,members:[{_id:0,host:"192.168.12.161:27019"},{_id:1,host:"192.168.12.162:27019"},{_id:2,host:"192.168.12.163:27019"},{_id:3,host:"192.168.12.164:27019"},{_id:4,host:"192.168.12.169:27019"}]}) MONGO_HOME=/home/cloud/platform/mongodb-3.4.5/ ${MONGO_HOME}/bin/mongod --config ${MONGO_HOME}/configserver.conf
c)mongos
#!/bin/bash #mogos dont need to initiate, #sh.enableSharding("dbname") to create database #sh.shardCollection("dbname.tablename", {id: "hashed"}) to create a shard table split by id /home/cloud/platform/mongodb-3.4.5/bin/mongos --config /home/cloud/platform/mongodb-3.4.5/mongosserver.conf
2、啟動過程
a、將腳本和配置文件復制到每台機器上
b、啟動每個shardsvr,然后登錄到shardsvr上,執行初始化過程:
1、執行start-shardsvr.sh 2、執行bin/mongo --host ${hostIP} --port ${hostport} shardsvr的默認端口是27018 configsvr的默認端口是27019 mongos的默認端口是27017 在上面配置文件中未指定端口,一切都以默認為主 3、執行rs.initiate({_id:"shardsvr1",members:[{_id:0,host:"192.168.12.161:27018"}]}) 進行初始化工作 4、執行rs.status()查看shardsvr狀態,一個成功的例子如下:
c、啟動所有configsvr,並使用mongo --host --port命令登錄到任意一台configsvr的configsvr端口上(default:27019)。並執行初始化工作:
rs.initiate({_id:"configsvr0",configsvr:true,members:[{_id:0,host:"192.168.12.161:27019"},{_id:1,host:"192.168.12.162:27019"},{_id:2,host:"192.168.12.163:27019"},{_id:3,host:"192.168.12.164:27019"},{_id:4,host:"192.168.12.169:27019"}]})
d、啟動mongos,這時已經可以在mongos上執行我們的操作了。
//先添加shard分片,如果shardsvr1有多個節點也只用寫一個,畢竟一個replica相當於一個節點,使用時會自動找到primary的
sh.addShard("shardsvr1/192.168.12.161:27018"))
//把所有的都加進去之后
printShardingStatus()
然后就是正常的mongo shell操作了,可以把mongos當成一個普通的單機mongodb來使用,操作基本相同,除了創建sharding表
創建表如下:
sh.enableSharding("dbname") to create database sh.shardCollection("dbname.tablename", {"_id": "hashed"}) to create a shard table hashed by _id
需要注意的是,"_id"是mongo分片依據,不能重復,如果想以其他字段來進行hash,將命令中的"_id"改為字段名稱就可以了,但是mongo還是會自動創建一個_id列用來索引
添加索引:
db.collectionname.ensureIndex({"indexColumn":1})
第三部分
JavaAPI小tips
獲取連接:
lazy val mongo = new MongoClient("192.168.12.161", 27017) lazy val db = mongo.getDatabase("testdb") lazy val dbColl = db.getCollection("origin2")
插入數據:
var resList = new ArrayList[Document] var d = new Document d.append("path", x.getPath) d.append("name", x.getName) d.append("content", filterHtml(Source.fromFile(x, detector(x)).getLines().toArray).mkString("\n")) resList.add(d) dbColl.insertMany(resList, new InsertManyOptions().ordered(false))
在插入過程中,如果"_id"出現重復值,那么默認情況下會中止當前插入操作並throw一個exception,即之前的數據已經插入進去,后面的數據沒插入進表,在后面加入new InsertManyOptions().ordered(false)參數就可以將所有不重復的數據插入完成后再throw一個exception