mongo除了單機部署,那么集群搭建可分為:可復制集、分片集群。
可復制集:每個master主后面都有N個slave備用節點。(生產環境推薦的部署模式)
分片集群:同時擁有多個可復制集,每個可復制集有自己的master和slave節點。
【可復制集】
讀寫分離,負載均衡,避免數據丟失,保障數據安全,提高系統安全性。
最少3節點,最大50節點。
自動化災備機制,主節點宕機后通過選舉產生新主機;提高系統健壯性;7個選舉節點上限
通過日志同步,保證master和slave的數據是統一的。
查詢會優先從master讀。
【可復制集搭建步驟】
第一步:配置mongodb.conf
storage:
#數據文件存放目錄
dbPath: "/Users/xxx/soft/mongodb-macos-x86_64-4.4.10/data"
systemLog:
#日志文件存放目錄
destination: file
path: "/Users/xxx/soft/mongodb-macos-x86_64-4.4.10/log"
net:
#本地監聽 IP,0.0.0.0 表示本地所有 IP,多個IP用逗號分隔。 #記住此處禁用localhost
bindIp: 0.0.0.0,192.168.2.100,127.0.0.1
# 端口,默認 27017,可以自定義
port: 27017
processManagement:
#以守護程序的方式啟用,即在后台運行
fork: true
setParameter:
#是否需要驗證權限登錄(用戶名和密碼)
enableLocalhostAuthBypass: false
replication:
#集群搭建的slave信息
relSetName: configRS #集群名稱
oplogSizeMB: 50 #oplog蓋子集合大小
記住這里的集群名稱叫 configRS。蓋子集合的概念請參考《mongodb-4.4.10版本SQL查詢進階,mongodb與mysql的select SQL大比拼》
node1的config文件參照上面配置,然后node2 node3的config文件也按照上面的配置復制,只需要更改端口號、log存放目錄、dbpath目錄就好了。
第二步:啟動mongo
依次啟動3個mongodb節點命令:
bin/mongod --config mongo_node1.conf
bin/mongod --config mongo_node2.conf
bin/mongod --config mongo_node3.conf
然后使用 ps -ef | grep mongo 命令查看是否成功啟動了3個mongodb
第三步:決定哪個節點為master主節點
假設3個節點的端口號是:27017、27018、27019
mongo --port 27017 連接上你選中做為主節點的節點
use admin 回到管理目錄
rs.initiate({ 創建集群命令,指定master節點到host參數
_id: "configRS", 這里的集合命名一定需與mongodb.conf的集群名字相同
version: 1,
members: [
{ _id: 0, host : "192.168.0.128:27017" }
]
});
rs.add("192.168.0.128:27018"); //第2個節點添加到集群
rs.add("192.168.0.128:27019"); //第3個節點添加到集群
rs.add... //第N個節點添加到集群
第一次rs.initiate命令如果成功了,會有結果反饋: { "ok":1 } 和其他一些cluster信息。然后你在命令行里的 “>” 會變成 "configRS:SECONDARY" 表示剛才那個命令開始了一個集群模式
第二次執行rs.add命令時,命令行里的 “>” 會變成 "configRS:PRIMARY" 表示你已經是一個集群模式里的master了
注意:在從節點里("configRS:SECONDARY")需要查看數據或集合時,需執行 rs.slaveOk()指令才可以,否則會報錯:"not master and slaveOk=false",即使該slave節點因為master節點掛掉當前已經通過選舉剛剛變成了master節點,也需要執行rs.slaveOk()指令才可以看見數據或者集合。
敲黑板:要保證大多數集群存活,才可以選舉出master,如果只剩一個節點,那就沒有master了,如果沒有master,將不能insert數據,不能做事務操作,即使rs.slaveOk()也不能。
第四步:集群驗證
ps -ef | grep mongo 列出所有mongodb節點
kill -9 xxx 干掉主節點
mongo --port 27018 連接到從節點上
configRS:PRIMARY> 此時從節點已經變成了主節點
第五步:springboot連接可復制集群demo
在springboot里注冊一個mongoClient:
@Bean(name="mongo")
public MongoClient mongoClient() {
// MongoCredential createCredential =
// MongoCredential.createCredential("lison", "lison", "lison".toCharArray());
WriteConcern wc = WriteConcern.W1.withJournal(true); //制定寫策略,就是在集群里怎么寫才算完成事務,參考《mongodb-4.4.10版本的存儲引擎與寫策略》
MongoClientOptions mco = MongoClientOptions.builder()
.writeConcern(wc)
.readPreference(ReadPreference.secondary()) // 配置讀策略:優先從slave讀
.connectionsPerHost(100) // 每台主機連接數100,默認連接數10
.threadsAllowedToBlockForConnectionMultiplier(5) // 線程隊列數,默認值5,與上面connectionsPerHost值相乘的結果就是線程隊列最大值。如果連接線程排滿了隊列就會拋出“Out of semaphores to get db”錯誤。
.maxWaitTime(120000)
.connectTimeout(10000)
.build();
List<ServerAddress> asList = Arrays.asList(
new ServerAddress("192.168.2.100", 27017));
MongoClient client = new MongoClient(asList, mco);
return client;
}
【分片集群】
分片集群和可復制集的不同點是:
可復制集:每個slave數據都是全部拷貝自master節點,就是master里的user集合有多少數據,slave里的user集合就有多少數據。
分片集群:更像是mysql里的分庫分表,一個user集合的數據通過hash算法分布式存儲到不同的分片上,然后為了數據的高可用,你可以在每個分片上做一個可復制集。
分片集群有3大組件概念:
分片:在集群中唯一存儲數據的位置,可以是單個mongo服務器,也可以是可復制集,每個分區上存儲部分數據;生產環境推薦使用可復制集
mongos路由:由於分片之存儲部分數據,需要mongos路由將讀寫操作路由到對應的分區上;mongos提供了單點連接集群的方式,輕量級、非持久化所以通常mongos和應用部署在同一台服務器上;
配置服務器:存儲集群的元數據,元數據包括:數據庫、集合、分片的范圍位置以及跨片數據分割和遷移的日志信息;mongos啟動時會從配置服務器讀取元數據信息在內存中;配置服務器最低3台;
分片集群搭建步驟:
第一步:搭建3個分片,也就是3套可復制集
按照上面可復制集的搭建步驟搭建3套可復制集,注意,每個可復制集的集群名稱必須不一樣。注意 mongodb.conf 配置文件里要加上分片配置信息:
sharding:
clusterRole: shardsvr #配置這個信息就表示當前集群是分片集群。 #注意這個值的不同,可以區分當前mongo節點是分片節點,還是配置節點,還是路由節點
假設:
【第一套可復制集】端口:27024、27025、27026,集群名稱:configRS
【第二套可復制集】端口:27027、27028、27029,集群名稱:configRS2
【第三套可復制集】端口:27030、27031、27032,集群名稱:configRS3
bin/mongod --config /soft/mongosplit/node27024/mongodb.conf
bin/mongod --config /soft/mongosplit/node27025/mongodb.conf
bin/mongod ... 以這種方式,分別啟動以上9個節點
ps -ef | grep mongo 查看是否9個節點都啟動成功
第二步:搭建3個配置服務器
在mongodb.conf 配置文件里要加上:
sharding:
clusterRole: configsvr #注意這個值的不同,可以區分當前mongo節點是分片節點,還是配置節點,還是路由節點
假設啟動的3個配置服務器端口是:27040、27041、27042
bin/mongod --config /soft/mongosplit/node27040/mongodb.conf
bin/mongod --config /soft/mongosplit/node27041/mongodb.conf
bin/mongod ... 以這種方式,分別啟動以上3個配置節點
ps -ef | grep mongo 查看是否12個節點都啟動成功(9個分片節點 + 3個配置節點)
第三步:搭建分片集群的路由
在mongodb.conf配置文件里要加上:
sharding:
configDB: editRS/192.168.2.100:27024,192.168.2.100:27027,192.168.2.100:27030 #僅配置每個分片里的可復制集里的master節點,這里共3個分片也就是3套可復制集,也就是3個master節點
#注意路由節點的conf配置文件里是沒有dbPath配置的,它的配置信息全都從配置服務器里取
bin/mongos --config /soft/mongosplit/node27050/mongodb.conf & 啟動路由命令。注意這里的啟動命令不是mongod了,而是mongos。此時用 ps -ef | grep mongo 命令就能查到13個節點了,其中一個是mongos節點
>mongo --port 27050 進入路由節點
mongos> 進入路由節點成功,因為在這里顯示mongos了
use admin 進入管理目錄
sh.addShard("configRS/192.168.2.100:27024,192.168.2.100:27025,192.168.2.100:27026"); 添加第1個分片
sh.addShard("configRS2/192.168.2.100:27027,192.168.2.100:27028,192.168.2.100:27029"); 添加第2個分片
sh.addShard("configRS3/192.168.2.100:27030,192.168.2.100:27031,192.168.2.100:27032"); 添加第3個分片
user lison 進入lison數據庫
sh.enableSharding("lisonSharding") 啟用一個名叫lisonSharding的分片
sh.shardCollection("lison.orders", {"useCode":"hashed"} ) 對lison數據庫的orders集合啟用分片,使用hash算法進行分片的分布式存儲。命令成功的話會返回{"ok":1}等信息
第四步:springboot連接分片集群demo
在springboot里注冊一個mongoClient:
@Bean(name="mongo")
public MongoClient mongoClient() {
WriteConcern wc = WriteConcern.W1.withJournal(true); //制定寫策略,就是在集群里怎么寫才算完成事務,參考《mongodb-4.4.10版本的存儲引擎與寫策略》
MongoClientOptions mco = MongoClientOptions.builder()
.writeConcern(wc)
.readPreference(ReadPreference.secondary()) // 配置讀策略:優先從slave讀
.connectionsPerHost(100) // 每台主機連接數100,默認連接數10
.threadsAllowedToBlockForConnectionMultiplier(5) // 線程隊列數,默認值5,與上面connectionsPerHost值相乘的結果就是線程隊列最大值。如果連接線程排滿了隊列就會拋出“Out of semaphores to get db”錯誤。
.maxWaitTime(120000)
.connectTimeout(10000)
.build();
List<ServerAddress> asList = Arrays.asList( new ServerAddress("192.168.2.100", 27050)); // 這里直接連接到路由節點即可
MongoClient client = new MongoClient(asList, mco);
return client;
}
事務支持版本
mongo4.0版本,只有可復制集是支持事務的,分片集群(replica sets)是不支持事務的。
而在最新的mongo4.2版本中,分片集群也可以支持事務了。
集群注意事項
生產環境中打開profile,便於優化系統性能
生產環境中打開auth模式,保障系統安全
end.