Mongo分片+副本集叢集搭建
一. 概念簡單描述
1. MongoDB分片叢集包含元件: mongos,configserver,shardding分片
2. Mongos:路由服務是Sharded cluster的訪問入口,本身不儲存資料
(1) 負載處理客戶端連線;
(2) 負責叢集資料的分片
3. Configserver: 配置伺服器,儲存所有資料庫元資訊(路由、分片)的配置。mongos本身沒有物理儲存分片伺服器和資料路由資訊,只是快取在記憶體裡,配置伺服器則實際儲存這些資料。mongos第一次啟動或者關掉重啟就會從 config server 載入配置資訊,以後如果配置伺服器資訊變化會通知到所有的 mongos 更新自己的狀態, 這樣mongos 就能繼續準確路由。在生產環境通常有多個 config server 配置伺服器,因為它儲存了分片路由的元資料,防止資料丟失.
4. 分片(sharding)是指將資料庫拆分,將其分散在不同的機器上的過程。將資料分散到不同的機器上,不需要功能強大的伺服器就可以儲存更多的資料和處理更大的負載,基本思想就是將集合切成小塊,這些塊分散到若干片裡,每個片只負責總資料的一部分,最後通過一個均衡器來對各個分片進行均衡(資料遷移)
(1) 分片節點可以是一個例項,也可以說一個副本集叢集
(2) 副本集叢集中的仲裁節點(Arbiter),只負責在主節點宕機時,將從節點選舉為主節點
二.MongoDB分片+副本集叢集部署環境
1.伺服器資訊(實際伺服器配置,看需求,根據自身情況決定)
2.服務埠
3.軟體版本
(1)系統: Centos7.4
(2)Mongo: Percona mongo 3.4
(3)supervisord : 3.3.4
二. 叢集部署
1. 安裝mongo
(1) 下載軟體包
#所有伺服器操作
mkdir -p /opt/upload/mongo_packge cd /opt/upload/mongo_packge wget 'https://www.percona.com/downloads/percona-server-mongodb-3.4/percona-server-mongodb-3.4.14-2.12/binary/redhat/7/x86_64/percona-server-mongodb-3.4.14-2.12-r28ff075-el7-x86_64-bundle.tar'
(2)解壓軟體包並安裝mongo
# 所有節點操作
mkdir -p rpm tar -xf percona-server-mongodb-3.4.14-2.12-r28ff075-el7-x86_64-bundle.tar -C rpm/ cd rpm yum -y install ./*.rpm
2. 部署configserver
(1) 建立configserver相關目錄
# mongos-01, mongos-02, mongos-03操作
mkdir -p /opt/configserver/configserver_conf mkdir -p /opt/configserver/configserver_data mkdir -p /opt/configserver/configserver_key mkdir -p /opt/configserver/configserver_log
(2) 建立配置檔案
# mongos-01, mongos-02, mongos-03操作
cat <<EOF> /opt/configserver/configserver_conf/configserver.conf dbpath=/opt/configserver/configserver_data directoryperdb=true logpath=/opt/configserver/configserver_log/config.log bind_ip = 0.0.0.0 port=21000 maxConns=10000 replSet=configs configsvr=true logappend=true fork=true httpinterface=true #auth=true #keyFile=/opt/configserver/configserver_key/mongo_keyfile EOF chown -R mongod:mongod /opt/configserver
(3) 啟動configserver
# mongos-01, mongos-02, mongos-03操作
/usr/bin/mongod -f /opt/configserver/configserver_conf/configserver.conf
(4) 建立configserver副本集
# mongos-01, mongos-02, mongos-03中任意節點操作
mongo --port 21000 #登陸mongo config = {_id : "configs",members : [{_id : 0, host : "172.18.6.87:21000" },{_id : 1, host : "172.18.6.86:21000" },{_id : 2, host : "172.18.6.85:21000" }]} #配置副本整合員節點 rs.initiate(config) #初始化副本集
3. 部署sharding01分片副本集(本次部署兩組副本集,每組副本集作為一個分片節點)
(1) 建立程式相關目錄 #操作伺服器shardding01_arbitration-01, shardding01_mongodb-01, shardding01_mongodb-02 mkdir -p /opt/mongodb/mongodb_data mkdir -p /opt/mongodb/mongodb_keyfile mkdir -p /opt/mongodb/ mongodb_log chow -R mongod:mongod /opt/mongodb/ mongodb_log (2) 修改配置檔案(shardding01_arbitration-01節點的cacheSizeGB引數,調整為2G) #操作伺服器shardding01_arbitration-01, shardding01_mongodb-01, shardding01_mongodb-02 cat <<EOF >/etc/mongod.conf # mongod.conf, Percona Server for MongoDB # for documentation of all options, see: # http://docs.mongo.org/manual/reference/configuration-options/ # Where and how to store data. storage: dbPath: /opt/mongodb/mongodb_data directoryPerDB: true journal: enabled: true # engine: mmapv1 # engine: rocksdb engine: wiredTiger # engine: inMemory # Storage engine various options # More info for mmapv1: https://docs.mongo.com/v3.4/reference/configuration-options/#storage-mmapv1-options # mmapv1: # preallocDataFiles: true # nsSize: 16 # quota: # enforced: false # maxFilesPerDB: 8 # smallFiles: false # More info for wiredTiger: https://docs.mongo.com/v3.4/reference/configuration-options/#storage-wiredtiger-options wiredTiger: engineConfig: cacheSizeGB: 20 # checkpointSizeMB: 1000 # statisticsLogDelaySecs: 0 # journalCompressor: snappy # directoryForIndexes: false # collectionConfig: # blockCompressor: snappy # indexConfig: # prefixCompression: true # More info for rocksdb: https://github.com/mongo-partners/mongo-rocks/wiki#configuration # rocksdb: # cacheSizeGB: 1 # compression: snappy # maxWriteMBPerSec: 1024 # crashSafeCounters: false # counters: true # singleDeleteIndex: false # More info for inMemory: https://www.percona.com/doc/percona-server-for-mongo/3.4/inmemory.html#configuring-percona-memory-engine # inMemory: # engineConfig: # inMemorySizeGB: 1 # statisticsLogDelaySecs: 0 # Two options below can be used for wiredTiger and inMemory storage engines #setParameter: # wiredTigerConcurrentReadTransactions: 128 # wiredTigerConcurrentWriteTransactions: 128 # where to write logging data. systemLog: destination: file logAppend: true path: /opt/mongodb/mongodb_log/mongod.log processManagement: fork: true pidFilePath: /opt/mongodb/mongodb_log/mongod.pid # network interfaces net: port: 22000 bindIp: 0.0.0.0 maxIncomingConnections: 100000 wireObjectCheck : true http: JSONPEnabled: false RESTInterfaceEnabled: false #security: # authorization: enabled # keyFile: /opt/mongodb/mongodb_keyfile/mongo_keyfile #operationProfiling: replication: replSetName: "sharding01" sharding: clusterRole: shardsvr archiveMovedChunks: true ## Enterprise-Only Options: #auditLog: #snmp: EOF (3) 修改systemd mongo的管理程式檔案 #操作伺服器shardding01_arbitration-01, shardding01_mongodb-01, shardding01_mongodb-02 sed -i 's#64000#100000#g' /usr/lib/systemd/system/mongod.service #修改程式開啟檔案數 sed -i 's#/var/run/mongod.pid#/opt/mongodb/mongodb_log/mongod.pid#g' /usr/lib/systemd/system/mongod.service #修改pid檔案的位置 systemctl daemon-reload (3) 啟動monod #操作伺服器shardding01_arbitration-01, shardding01_mongodb-01, shardding01_mongodb-02 systemctl restart mongod systemctl enable mongod (4) 配置副本集 mongo --port 22000 config = {_id : "sharding01",members : [{_id : 0, host : "172.18.6.89:22000" },{_id : 1, host : "172.18.6.88:22000" },{_id : 2, host : "172.18.6.92:22000",arbiterOnly:true}]} #配置副本集節點, arbiterOnly:true 表示為仲裁節點 rs.initiate(config) #初始化副本集 (5) 檢視副本集狀態 sharding01:SECONDARY> rs.status() { "set" : "sharding01", "date" : ISODate("2018-11-02T16:05:37.648Z"), "myState" : 2, "term" : NumberLong(17), "syncingTo" : "172.18.6.89:22000", "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1541174730, 1127), "t" : NumberLong(17) }, "appliedOpTime" : { "ts" : Timestamp(1541174730, 1127), "t" : NumberLong(17) }, "durableOpTime" : { "ts" : Timestamp(1541174730, 1127), "t" : NumberLong(17) } }, "members" : [ { "_id" : 0, "name" : "172.18.6.89:22000", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 27141, "optime" : { "ts" : Timestamp(1541174730, 1127), "t" : NumberLong(17) }, "optimeDurable" : { "ts" : Timestamp(1541174730, 1127), "t" : NumberLong(17) }, "optimeDate" : ISODate("2018-11-02T16:05:30Z"), "optimeDurableDate" : ISODate("2018-11-02T16:05:30Z"), "lastHeartbeat" : ISODate("2018-11-02T16:05:35.909Z"), "lastHeartbeatRecv" : ISODate("2018-11-02T16:05:37.428Z"), "pingMs" : NumberLong(0), "electionTime" : Timestamp(1541147605, 1), "electionDate" : ISODate("2018-11-02T08:33:25Z"), "configVersion" : 1 }, { "_id" : 1, "name" : "172.18.6.88:22000", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 27142, "optime" : { "ts" : Timestamp(1541174730, 1127), "t" : NumberLong(17) }, "optimeDate" : ISODate("2018-11-02T16:05:30Z"), "syncingTo" : "172.18.6.89:22000", "configVersion" : 1, "self" : true }, { "_id" : 2, "name" : "172.18.6.92:22000", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 27141, "lastHeartbeat" : ISODate("2018-11-02T16:05:35.909Z"), "lastHeartbeatRecv" : ISODate("2018-11-02T16:05:33.315Z"), "pingMs" : NumberLong(0), "configVersion" : 1 } ], "ok" : 1 }
4. 部署sharding02分片副本集(本次部署兩組副本集,每組副本集作為一個分片節點)
參考 sharding01
5. 配置mongos
# mongos-01, mongos-02, mongos-03操作 (1) 建立程式相關目錄 mkdir -p /opt/mongos/mongos_conf mkdir -p /opt/mongos/mongos_data mkdir -p /opt/mongos/mongos_key mkdir -p /opt/mongos/mongos_log (2) 建立配置檔案 # mongos-01, mongos-02, mongos-03操作 cat <<EOF> /opt/mongos/mongos_conf/mongos.conf logpath=/opt/mongos/mongos_log/mongos.log logappend=true bind_ip = 0.0.0.0 port=20000 configdb=configs/172.18.6.87:21000,172.18.6.86:21000,172.18.6.85:21000 #配置分片伺服器叢集地址 fork=frue #keyFile=/opt/mongos/mongos_key/mongo_keyfile EOF (3) 啟動mongos # mongos-01, mongos-02, mongos-03操作 /usr/bin/mongos -f /opt/mongos/mongos_conf/mongos.conf (4) 配置分片 # mongos-01, mongos-02, mongos-03任意節點操作 mongo –port use admin db.runCommand( { addshard : "sharding01/172.18.6.89:22000,172.18.6.88:22000,172.18.6.92:22000"}); #新增分片節點1 db.runCommand( { addshard : "sharding02/172.18.6.91:22000,172.18.6.90:22000,172.18.6.93:22000"}); #新增分片節點2 (5) 檢視叢集狀態 mongos> db.runCommand( { listshards : 1 } ) { "shards" : [ { "_id" : "sharding01", "host" : "sharding01/172.18.6.88:22000,172.18.6.89:22000", "state" : 1 }, { "_id" : "sharding02", "host" : "sharding02/172.18.6.90:22000,172.18.6.91:22000", "state" : 1 } ], "ok" : 1 }
6. 配置片鍵(本次根據業務場景使用hash分片)
Mongo分片需要為有分片需求的資料庫開啟分片,併為庫內需要分片的集合設定片鍵 (1) 為分片庫開啟分片 #mongos任意節點操作 mongo --port 20000 use admin db.runCommand( { enablesharding :"dingkai"}); #為指定庫開啟分片(dingkai 是庫名) use dingkai #進入dingkai 庫 db.dingkaitable.createIndex({dingkaifields: "hashed"}); #為作為片鍵的欄位建立hash索引,dingkaitable是需要分片的集合, dingkaifields是作為片鍵的欄位 use admin #建立片鍵,需要在admin庫執行 db.runCommand({shardcollection : "dingkai. dingkaitable",key:{dingkaifields: "hashed"} }) #建立片鍵(hashed表示使用hash分片,使用範圍分片則把hashed改為 1)
三. 開啟認證
1. 在各個叢集中建立賬號(建議開始只建立root許可權的使用者,後續需要其他使用者,可以通過root賬號建立)
(1) configserver叢集 #主節點操作 mongo --port 21000 use admin db.createUser({user:"root", pwd:"Dingkai.123", roles:[{role: "root", db:"admin" }]}) #root賬號(超級管理員) use admin db.createUser({user:"admin", pwd:"Dingkai.123", roles:[{role: "userAdminAnyDatabase", db:"admin" }]}) #管理員賬號 use admin db.createUser({user:"clusteradmin", pwd:"Dingkai.123", roles:[{role: "clusterAdmin", db:"admin" }]}) #叢集管理賬號 (2) sharding叢集的主節點(sharding節點設定,主要用於單獨登陸分片節點的副本集叢集時使用,業務庫的賬號,在mongos上建立即可) mongo --port 21000 use admin db.createUser({user:"root", pwd:"Dingkai.123", roles:[{role: "root", db:"admin" }]}) #root賬號(超級管理員) use admin db.createUser({user:"admin", pwd:"Dingkai.123", roles:[{role: "userAdminAnyDatabase", db:"admin" }]}) #管理員賬號 use admin db.createUser({user:"clusteradmin", pwd:"Dingkai.123", roles:[{role: "clusterAdmin", db:"admin" }]}) #叢集管理賬號
2. 建立叢集認證檔案
openssl rand -base64 64 > mongo_keyfile
3. 將認證檔案分發至各個節點中配置檔案制定的位置
(1) configserver叢集節點(mongos-01, mongos-02, mongos-03)配置檔案中
keyfile制定目錄為: keyFile=/opt/configserver/configserver_key/mongo_keyfile
(2) sharding節點叢集中各個節點配置檔案指定目錄:
keyFile: /opt/mongodb/mongodb_keyfile/mongo_keyfile
(3) mongos 各個節點(mongos-01, mongos-02, mongos-03)配置檔案指定目錄:
keyFile=/opt/mongos/mongos_key/mongo_keyfile
(4)分發完成後, 認證檔案 mongo_keyfile 許可權設定為 600, 屬主屬組為mongod
chmod 600
chown mongod:mongod
4. 修改各個節點配置檔案中認證相關配置
(1) Sharding個節點(shardding01_arbitration-01, shardding01_mongodb-01, shardding01_mongodb-02, shardding02_arbitration-01, shardding02_mongodb-01, shardding02_mongodb-02)
開啟配置檔案中:
security:
authorization: enabled
keyFile: /opt/mongodb/mongodb_keyfile/mongo_keyfile
(2)configserver個節點(mongos-01, mongos-02, mongos-03)
keyFile=/opt/mongos/mongos_key/mongo_keyfile
5. 重啟所有節點
(1) 重啟shardding分片各個節點
(2) 重啟configserver各節點
(3) 重啟mongos各節點
6. 驗證
(1)不認證無法執行命令檢視叢集狀態
mongos -port 20000 use admin db.runCommand( { listshards : 1 } ) { "ok" : 0, "errmsg" : "not authorized on admin to execute command { listshards: 1.0 }", "code" : 13, "codeName" : "Unauthorized"
(2) 使用叢集管理賬號認證
mongos> use admin switched to db admin mongos> db.auth("clusteradmin","Dingkai.123") 1 mongos> db.runCommand( { listshards : 1 } ) { "shards" : [ { "_id" : "sharding01", "host" : "sharding01/172.18.6.88:22000,172.18.6.89:22000", "state" : 1 }, { "_id" : "sharding02", "host" : "sharding02/172.18.6.90:22000,172.18.6.91:22000", "state" : 1 } ], "ok" : 1 }
四. 常用命令
(1)叢集管理
db.runCommand( { listshards : 1 } ) #檢視叢集狀態
db.printShardingStatus() #給出整個分片系統的一些狀態資訊
db.表名.stats() #查看錶的儲存狀態
(2)使用者管理
Read:允許使用者讀取指定資料庫
readWrite:允許使用者讀寫指定資料庫
dbAdmin:允許使用者在指定資料庫中執行管理函式,如索引建立、刪除,檢視統計或訪問system.profile
userAdmin:允許使用者向system.users集合寫入,可以找指定資料庫裡建立、刪除和管理使用者
clusterAdmin:只在admin資料庫中可用,賦予使用者所有分片和複製集相關函式的管理許可權。
readAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的讀許可權
readWriteAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的讀寫許可權
userAdminAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的userAdmin許可權
dbAdminAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的dbAdmin許可權。
root:只在admin資料庫中可用。超級賬號,超級許可權
######建立使用者######
db.createUser({user:"XXX",pwd:"XXX",roles:[{role:"readWrite", db:"myTest"}]})
######檢視使用者######
(1)檢視所有使用者
use admin
db.system.users.find()
(2)檢視當前庫的使用者
use 庫名
show users
######刪除使用者######
(1)刪除當前庫使用者
use 庫名
db.dropUser('使用者名稱')