結合我們的生產需求,本次詳細整理了最新版本 MonogoDB 7.0 叢集的規劃及部署過程,具有較大的參考價值,基本可照搬使用。
適應資料規模為T級的場景,由於設計了分片支撐,後續如有大資料量需求,可分片橫向擴充套件。
■■■ 分片叢集規劃
■ Configure hostname、hosts file、ip address
vim /etc/hosts
7.7.7.11 node1
7.7.7.12 node2
7.7.7.13 node3
注:規劃、實施、運維均採用host解析的方式判定各個節點,因此需確保該配置檔案需正確解析node1、node2、node3.
■ 節點的角色及埠分配
┌────node1────┬────node2────┬────node3────┬port─┐
│mongos server│mongos server│mongos server│20000│
├─────────────┼─────────────┼─────────────┼─────┤
│config server│config server│config server│21000│
│(Primary) │(Secondary) │(Secondary) │ │
├─────────────┼─────────────┼─────────────┼─────┤
│shard server1│shard server1│shard server1│27001│
│(Primary) │(Secondary) │(Secondary) │ │
└─────────────┴─────────────┴─────────────┴─────┘
■■■ Pre-task preparation
■ 依賴包
yum install -y libcurl openssl [3.6.23]
yum install -y xz-libs [6.0.0另需]
■ 使用者及使用者組
groupadd mongod
groupadd mongodb
useradd -g mongod -G mongodb mongod
echo "passwd"|passwd mongod --stdin
■ mongodb 下載、安裝
官方所有介質均從這個入口下載:
https://www.mongodb.com/try/download
#20230911 最新版本,選擇合適的平臺介質
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-7.0.1.tgz
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-7.0.1.tgz
mkdir -p /u01
KDR=/u01
cd ${KDR}
TGZ=mongodb-linux-x86_64-rhel70-7.0.1
#cp_unzip_chown_ln:
cp /u01/nfs/MongoDB/${TGZ}.tgz .
tar zxvf ${TGZ}.tgz
chown -R mongod:mongod ${TGZ}
ln -s ${KDR}/${TGZ}/bin/* /usr/local/bin/
■ database-tools 下載、安裝
6.0版本開始,將資料庫相關的工具單獨管理,以利於實時升級、釋出
wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel70-x86_64-100.8.0.tgz
wget https://fastdl.mongodb.org/tools/db/mongodb-database-tools-rhel80-x86_64-100.8.0.tgz
KDR=/u01
cd ${KDR}
TGZ=mongodb-database-tools-rhel70-x86_64-100.8.0
【後續步驟同上】
#cp_unzip_chown_ln:
■ mongosh 下載、安裝
https://downloads.mongodb.com/compass/mongosh-2.0.0-linux-x64.tgz
KDR=/u01
cd ${KDR}
#TGZ=mongosh-1.10.6-linux-x64
TGZ=mongosh-2.0.0-linux-x64
【後續步驟同上】
#cp_unzip_chown_ln:
■ chronyd
配置時間同步
■ selinux
關閉selinux
■ firewalld
配置防火牆,確保放行這幾個埠
firewall-cmd --add-port=20000/tcp --permanent
firewall-cmd --add-port=21000/tcp --permanent
firewall-cmd --add-port=27001-27003/tcp --permanent
firewall-cmd --reload
■ 3個節點建立mongodb資料庫檔案目錄
MongoDir=/u01/mongodb
mkdir -p ${MongoDir}
chown -R mongod:mongod ${MongoDir}
cat >> /etc/profile << EOF
export MongoDir=${MongoDir}
EOF
■ 以下均用mongod使用者操作
su - mongod
echo ${MongoDir}
■ 3個節點均建立6個目錄:conf、mongos、config、shard1、shard2、shard3
mkdir -p ${MongoDir}/conf
mkdir -p ${MongoDir}/mongos/log
mkdir -p ${MongoDir}/config/data
mkdir -p ${MongoDir}/config/log
mkdir -p ${MongoDir}/shard1/data
mkdir -p ${MongoDir}/shard1/log
mkdir -p ${MongoDir}/shard2/data
mkdir -p ${MongoDir}/shard2/log
mkdir -p ${MongoDir}/shard3/data
mkdir -p ${MongoDir}/shard3/log
■ 檢查目錄結構
tree ${MongoDir} -L 2 --dirsfirst
├── conf
│ ├── config.conf
│ ├── mongos.conf
│ ├── shard1.conf
│ ├── shard2.conf
│ └── shard3.conf
├── config
│ ├── data
│ └── log
├── mongos
│ └── log
├── shard1
│ ├── data
│ └── log
├── shard2
│ ├── data
│ └── log
└── shard3
├── data
└── log
■■■ config server
mongodb3.4以後要求配置伺服器也建立副本集,不然叢集搭建不成功
■ 配置檔案
【3個節點執行】
cat > ${MongoDir}/conf/config.conf << EOF
processManagement:
fork: true
pidFilePath: ${MongoDir}/config/log/configsvr.pid
net:
bindIpAll: true
port: 21000
ipv6: true
maxIncomingConnections: 20000
storage:
dbPath: ${MongoDir}/config/data
wiredTiger:
engineConfig:
cacheSizeGB: 1
systemLog:
destination: file
path: ${MongoDir}/config/log/configsvr.log
logAppend: true
sharding:
clusterRole: configsvr
replication:
replSetName: configs
setParameter:
connPoolMaxConnsPerHost: 20000
EOF
■ 啟動3個 config server
mongod -f ${MongoDir}/conf/config.conf
■ 登入任意一臺配置伺服器,初始化配置副本集
mongosh node1:21000
定義config變數:
config = {_id: "configs", members: [
{_id: 0, host: "node1:21000"},
{_id: 1, host: "node2:21000"},
{_id: 2, host: "node3:21000"} ]
}
其中,_id: "configs"應與配置檔案中的配置一致,"members" 中的 "host" 為三個節點的 ip 和 port
初始化副本集:
rs.initiate(config)
檢視此時狀態:
rs.status()
■■■ shard server
■ shard server1
【3個節點執行】
【注意】如果資料量並不大,分片需求不明顯,可以先只建立shard server1,另外的分片2、分片3先不建立,後續根據實際需求可隨時建立。
cat > ${MongoDir}/conf/shard1.conf << EOF
processManagement:
fork: true
pidFilePath: ${MongoDir}/shard1/log/shard1.pid
net:
bindIpAll: true
port: 27001
ipv6: true
maxIncomingConnections: 20000
storage:
dbPath: ${MongoDir}/shard1/data
wiredTiger:
engineConfig:
cacheSizeGB: 5
systemLog:
destination: file
path: ${MongoDir}/shard1/log/shard1.log
logAppend: true
sharding:
clusterRole: shardsvr
replication:
replSetName: shard1
security:
keyFile: ${MongoDir}/conf/mongo.keyfile
setParameter:
connPoolMaxConnsPerHost: 20000
maxNumActiveUserIndexBuilds: 6
EOF
啟動3個 shard1 server:
mongod -f ${MongoDir}/conf/shard1.conf
登陸任意節點,初始化副本集:
注:初始化副本集的操作不能在仲裁節點上執行!在哪個節點初始化,則哪個節點預設是副本集的主節點。
mongosh --port 27001
使用admin資料庫,定義副本集配置,"arbiterOnly":true 代表其為仲裁節點:
use admin
#模式選擇 P/S/S
config = {_id: "shard1", members: [
{_id: 0, host: "node1:27001"},
{_id: 1, host: "node2:27001"},
{_id: 2, host: "node3:27001"}
]
}
#模式選擇 P/S/A
config = {_id: "shard1", members: [
{_id: 0, host: "node1:27001"},
{_id: 1, host: "node2:27001"},
{_id: 2, host: "node3:27001", arbiterOnly:true}
]
}
rs.initiate(config);
rs.status()
■ shard server2 【備用,暫不執行】
■ shard server3 【備用,暫不執行】
■■■ mongos server
【3個節點執行】
注:需先啟動 config server 和 shard server, 後啟動 mongos server (3個節點)
cat > ${MongoDir}/conf/mongos.conf << EOF
processManagement:
fork: true
pidFilePath: ${MongoDir}/mongos/log/mongos.pid
net:
bindIpAll: true
port: 20000
ipv6: true
maxIncomingConnections: 20000
systemLog:
destination: file
path: ${MongoDir}/mongos/log/mongos.log
logAppend: true
sharding:
configDB: configs/node1:21000,node2:21000,node3:21000
EOF
啟動3個 mongos server:
mongos -f ${MongoDir}/conf/mongos.conf
■■■ 啟用分片機制
以上配置過程可見,mongos server 只有 configsvr 配置資訊,並無 shardsvr 的資訊,因此還需設定使分片可用,否則是無法使用分片的,就是說:shardsvr 無法直接操作,只能透過 mongos server 啟用分片機制後,才能操作
問題:如果只有一個分片,還需要設定嗎?答案是:需要,原因見上。
■ 3.6.23 / 7.0.0
登陸任一 mongos server, 使用 admin 資料庫,串聯路由伺服器與分配副本集:
mongosh node1:20000
use admin
sh.addShard("shard1/node1:27001,node2:27001,node3:27001")
檢視叢集狀態:
sh.status()
sh.removeShard("shard2")
■■■ 使用分片機制
暫不涉及,後續可視需要再配置。
■■■ 使用者許可權配置
對於搭建好的mongodb分片叢集,為了安全,需啟動安全認證,使用賬號密碼登入。
預設的mongodb是不設定認證的。只要ip和埠正確就能連線,這樣是很不安全的。
mongodb官網聲稱,為了能保障mongodb的安全可以做以下幾個步驟:
1、使用新的埠,預設的27017埠如果一旦知道了ip就能連線上,不太安全
2、設定mongodb的網路環境,最好將mongodb部署到公司伺服器內網,這樣外網是訪問不到的。公司內部訪問使用vpn等
3、開啟安全認證。認證要同時設定伺服器之間的內部認證方式,同時要設定客戶端連線到叢集的賬號密碼認證方式
以下詳細描述如何配置安全認證。
■ node1 建立副本集認證的key檔案
用openssl生成密碼檔案,然後使用chmod來更改檔案許可權,僅為檔案所有者提供讀取許可權
cd ${MongoDir}/conf
openssl rand -out mongo.keyfile -base64 90
chmod 600 mongo.keyfile
ll mongo.keyfile
-r-------- 1 mongod mongod 122 Aug 4 08:33 mongo.keyfile
提示:所有副本集節點都必須要用同一份keyfile,一般是在一臺機器上生成,然後複製到其他機器上,且必須有讀的許可權,否則將來會報錯:
permissions on ${MongoDir}/conf/mongo.keyfile are too open
■ node1 修改配置檔案指定keyfile
編輯配置檔案,新增如下內容:
for FILE in ${MongoDir}/conf/{config,shard1,mongos}.conf
do
cat >> ${FILE} << EOF
security:
keyFile: /u01/mongodb/conf/mongo.keyfile
EOF
done
■ node1 將修改後的配置檔案和key檔案複製到 node2、node3
scp ${MongoDir}/conf/{config.conf,shard[1-3].conf,mongos.conf,mongo.keyfile} node2:${MongoDir}/conf
scp ${MongoDir}/conf/{config.conf,shard[1-3].conf,mongos.conf,mongo.keyfile} node3:${MongoDir}/conf
■ 重新啟動節點
依次啟動配置節點、分片節點、路由節點
■ 建立帳號和認證
客戶端mongosh,透過localhost或127.0.0.1登入任意一個mongos路由,可以執行建立操作
提示:此時相當於一個後門,只能在 admin 下新增使用者
提示:透過mongos新增的賬號資訊,只會儲存到配置節點的服務中,具體的資料節點不儲存賬號資訊,因此分片中的賬號資訊不涉及到同步問題
建議:先建立超管使用者和普通使用者,然後再開啟安全配置
建立管理員帳號:
use admin
db.createUser({user: "admin", pwd: "passwd!2#", roles: ["root"]})
db.createUser({user: "inspur", pwd: "passwd!2#", roles: ["userAdminAnyDatabase"]})
db.dropUser("inspur")
鑑權操作:
db.auth("admin", "passwd!2#")
db.auth("inspur", "passwd!2#")
建立一個普通許可權帳號:
use testdb
db.createUser({user: "liking", pwd: "passwd!2#", roles: ["readWrite"]})
db.auth("liking", "passwd!2#")
■ 用管理員帳號可檢視整體的分片情況
use admin
db.auth("admin", "passwd!2#")
sh.status()
■ 用普通帳號訪問資料
use testdb
db.auth("liking", "passwd!2#")
■ 客戶端連線多個mongos的標準格式
mongosh mongodb://'admin':'passwd%212%23'@node1:20000,node2:20000,node3:20000/testdb?authSource=admin