1 部署結構
1.1 集群結構
典型的三分片Mongo集群如下圖所示,包含三類組件:查詢路由、配置服務器、分片。其中查詢路由為mongos進程,配置服務器和分片都是mongod進程。配置服務器和分片都采取副本集(replica set)來確保可用性和健壯性,每個副本集最少包含三個節點。查詢路由都是單實例運行,沒有副本集機制,可根據需要增加實例數量,也可以在外部添加負載均衡。
上圖中每個方框僅代表功能集合,不代表物理位置。實際部署時,為了避免單點故障,同一個副本集中的成員,應該部署在不同主機上。比如分片1的三個mongod進程應該運行在三台不同的主機上。
1.2 部署方案
副本集方案1(一主二從)
副本集方案2(一主一從一仲裁)
如上圖所示,三成員的副本集方案有兩種:一主二從、一主一從一仲裁。
對於方案1來說,每個成員都是數據節點,應該各自獨占一台主機,這樣三分片集群至少需要9台服務器(配置服務器和查詢路由可以復用主機),之后每追加一個分片需要增加3台主機。具體部署情況如下圖所示(同顏色的為一組,查詢路由為MS,配置服務器為CS*):
對於方案2來說,有兩個成員是數據節點,兩外一個是投票節點(仲裁者),這樣三分片集群只需要6台服務器(配置服務器和查詢路由依舊復用主機,仲裁者與另一分片的數據節點部署在一台主機),之后每追加一個分片需要增加2台主機。具體部署情況如下圖所示(同顏色的為一組,*a表示仲裁者,如Aa、Ba):
可以看出,分片副本集采取一主一從一仲裁方案,更加節省機器資源。結合Mongo分片集群一期部署所能使用的服務器數量為6台,選擇第二種部署方案。
2 部署步驟
- 安裝MongoDB:在所有主機上安裝MongoDB
- 搭建分片集群:確定各組件節點分布,搭建分片集群
- 數據庫初始化:創建需要的分片數據庫和分片集合,並添加索引
- 數據遷移:將生產環境中的Mongo副本集的數據遷移到分片集群中
- 應用遷移:將相關應用從副本集遷移到分片集群
上述步驟的具體操作見后續章節
3 安裝MongoDB
操作系統為: 64位CentOS 7
Mongo版本:linux-x86_64-rhel70-3.4.5
注意:所有主機安裝的MongoDB版本應當一致。
3.1 檢查安裝環境
- 確定NUMA已關閉
執行grep -i numa /var/log/dmesg,如果輸出結果為:No NUMA configuration found,說明NUMA已禁用,否則通過BIOS將其關閉,或者使用numactl來啟動mongod進程(安裝方法見3.3)。
- 確定kernel版本不低於2.6.36
執行uname -r,查看返回的版本號
- 確定glibc版本不低於2.13
執行ldd --version(version前面兩個減號),查看返回的版本號
- 確定ulimit配置
執行ulimit -a,查看當前設置,官方推薦配置如下:
-f (file size): unlimited -t (cpu time): unlimited -v (virtual memory): unlimited -n (open files): 64000 -m (memory size): unlimited -u (processes/threads): 64000 |
主要需要確認的是最大文件數(-n),最大進程數(-u),調整方法如下:
- 將最大文件數(-n)修改為64000
編輯/etc/security/limits.conf,寫入以下兩行
* soft nofile 64000 * hard nofile 64000 |
b. 將最大進程數(-u)修改為64000
編輯/etc/security/limits.d/20-nproc.conf,寫入以下兩行
* soft nproc 64000 * hard nproc 64000 |
配置完成后,重新打開終端確認是否生效。
- 文件系統采取XFS
執行df -iT,確認主要分區為xfs。
- 禁用Transparent Huge Pages
執行以下命令查看狀態:
cat /sys/kernel/mm/transparent_hugepage/enabled cat /sys/kernel/mm/transparent_hugepage/defrag |
輸出信息中方括號選中的為當前狀態,如果為never表示禁用
如果不是never,通過執行以下命令禁用:
echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag |
上面的操作在系統重啟后失效,可以通過設置開機禁用,執行crontab -e添加以下內容:
@reboot echo never > /sys/kernel/mm/transparent_hugepage/enabled @reboot echo never > /sys/kernel/mm/transparent_hugepage/defrag |
- 數據庫文件目錄所在存儲卷關閉atime
執行cat /etc/fstab,查看內容,通常如下所示:
注意每行的第三個配置,默認為defaults,修改准備存放庫文件目錄的卷,在defaults后面添加“,noatime,nodiratime”,例如放在/home目錄下:
- 禁用SELinux
執行sestatus查看狀態,如果為disabled,或者permissive模式說明已禁用:
如果未禁用,可以執行setenforce 0來臨時禁用。
想要永久禁用,需要修改/etc/selinux/config,將SELINUX修改為disabled或者permissive,需要重啟系統生效。
如果不想關閉SELinux,可以用以下命令放行Mongo(運行在默認端口27017上):
semanage port -a -t mongod_port_t -p tcp 27017 |
- 關閉防火牆
執行service firewall status查看防火牆狀態,如果為inactive說明已關閉:
如果未關閉,執行service firewalld stop。
3.2 安裝Mongo
- 下載安裝包
訪問官網https://www.mongodb.com/download-center,下載對應版本安裝包(.tgz)
- 將安裝包拷貝服務器上,例如/tmp目錄下
- 打開終端進入安裝包所在目錄(/tmp),將其解壓,會在目錄下生成mongodb-***的目錄
tar zxf mongodb-linux-x86_64-rhel70-3.4.5.tgz |
- 將解壓后的目錄拷貝到安裝路徑(例如/opt/mongodb),執行命令:
mv mongodb-linux-x86_64-rhel70-3.4.5 /opt/mongodb |
- 在環境變量PATH中添加二進制文件路徑
MongoDB的二進制文件在Mongo安裝路徑的bin/目錄下。可以通過修改PATH變量。
編輯shell的rc文件:
vi ~/.bashrc |
在最后添加下面這行:
export PATH=/opt/mongodb/bin:$PATH |
注意:此環境變量與僅對當前用戶有效。
- 驗證安裝成功
重新打開中斷,輸入命令:
mongo --version |
如果顯示以下信息,說明安裝成功。
3.3 安裝numactl
對於啟用了NUMA的主機,如果無法通過BIOS關閉,可以安裝numactl工具。
- 下載rpm安裝包
https://centos.pkgs.org/7/centos-x86_64/numactl-2.0.9-6.el7_2.x86_64.rpm.html
- 將安裝包拷貝到需要運行Mongo的主機上,然后執行命令
rpm -ivh numactl-2.0.9-6.el7_2.x86_64.rpm |
顯示以下信息說明安裝成功。
3.4 安裝bwm-ng
bwm-ng是監控網絡帶寬和磁盤IO的工具。它的官網是:http://www.gropp.org/,當前最新下載地址為:https://www.gropp.org/bwm-ng/bwm-ng-0.6.1.tar.gz,安裝步驟如下:
- 下載安裝包
- 將安裝包拷貝到主機上(例如拷貝到/tmp/目錄下)
- 將安裝包解壓:
tar zxvf bwm-ng-0.6.tar.gz |
- 進入解壓后的目錄並編譯安裝:
cd bwm-ng-0.6.1 ./configure && make && make install |
- 檢查是否安裝成功,執行:
bwm-ng |
正常會顯示類似如下信息:
常用監控命令:
- 監控網絡帶寬
bwm-ng -u bits -d bwm-ng -u bytes -d |
- 監控磁盤IO
bwm-ng -u bytes -i disk |
4 搭建分片集群
注意:分片集群中所有實例的Mongo版本應當一致。
4.1 分片集群規划
4.1.1 節點分配
以三分片集群為例,它包含15個進程節點,3個路由(mongos)、1個配置服務器副本集(3個mongod組成)、3個分片副本集(每個由3個mongod組成)。因為實際環境有6台主機(140-145),所以每個主機上需要運行不止一個進程。
對資源消耗比較大的是分片中的數據節點(主節點或從節點),每台主機上最好只運行一個數據節點,這樣就只能有6個數據節點,平攤到每個分片有2個數據節點,所以每個分片采取1主(primary)1從(secondary)1仲裁(arbiter)的結構。
142、143、144服務器依次部署分片1、分片2、分片3的主節點;145、140、141服務器依次部署分片1、分片2、分片3的從節點。除了這六個節點,剩余3個路由節點、3個配置服務器節點和分片1-3的仲裁節點。
考慮到路由需要和配置服務器通信,所以路由和配置服務器兩兩部署在一起;另外路由與分片主節點通信也較多,所以就在每個分片主節點所在服務器上部署1個路由節點和1個配置服務器節點。這樣142服務器上有分片1的主節點、1個路由節點、1個配置服務器節點;143服務器上有分片2的主節點、1個路由節點、1個配置服務器節點;144服務器上有分片3、1個路由節點、1個配置服務器節點。
至此還剩分片1-3的仲裁節點沒有分配。考慮主機資源的均衡,將它們部署到從節點服務器上。同時為了避免單點故障(一個分片里同時掛掉兩個節點),每個仲裁節點不放在相同分片的從節點主機上。這樣145服務器上有分片1的從節點、分片3的仲裁節點;140服務器上有分片2的從節點、分片1個仲裁節點;142服務器上有分片3的從節點、分片2的仲裁節點。
這樣三分片集群節點在6台服務器上的分配情況如下:
序號 |
主機 |
組件 |
1 |
10.20.50.142 |
配置服務器-primary 分片1-primary 路由 |
2 |
10.20.50.143 |
配置服務器-secondary 分片2-primary 路由 |
3 |
10.20.50.144 |
配置服務器-secondary 分片3-primary 路由 |
4 |
10.20.50.145 |
分片1-secondary 分片3- arbiter |
5 |
10.20.50.140 |
分片2-secondary 分片1- arbiter |
6 |
10.20.50.141 |
分片3-secondary 分片2- arbiter |
4.1.2 端口、路徑和磁盤規划
- 端口規划
根據上一節的節點分配,每台服務器上運行不止一個節點,而每個節點都需要占用端口,所以需要對端口進行規划。
因為MongoDB的默認端口是27017,每台主機可以有一個實例使用該端口,考慮到集群搭建過程中的便利性(不需要指定端口),所以將27017端口分配給每台主機上的數據節點(分片的主節點或從節點)。145、140、141主機上還有的仲裁節點,分配相同的28017端口。142、143、144主機上還有配置服務器節點和路由節點,也考慮根據類型分別分配相同端口,配置服務器分配28018端口,路由分配29017端口。
至此端口分配完成
序號 |
主機 |
組件 |
1 |
10.20.50.142 |
分片1-primary(27017) 配置服務器-primary(28017) 路由(29017) |
2 |
10.20.50.143 |
分片2-primary(27017) 配置服務器-secondary(28017) 路由(29017) |
3 |
10.20.50.144 |
分片3-primary(27017) 配置服務器-secondary(28017) 路由(29017) |
4 |
10.20.50.145 |
分片1-secondary(27017) 分片3- arbiter(28017) |
5 |
10.20.50.140 |
分片2-secondary(27017) 分片1- arbiter(28017) |
6 |
10.20.50.141 |
分片3-secondary(27017) 分片2- arbiter(28017) |
- 路徑和磁盤規划
每個節點實際是mongod或mongos進程,需要有自己的運行目錄,所以需要對運行目錄的路徑進行規划。出於方便考慮,將每台主機的多個節點運行目錄放在同一個根路徑下,然后根路徑下各自占使用一個子目錄,子目錄以節點用途命名(例如路由的運行目錄為router、配置服務器的運行目錄為confsrv、分片1-3的運行目錄為shard1/shard2/shard3)
至於運行根目錄,考慮到數據節點需要使用大量磁盤資源,所以應該選擇磁盤容量最大的分區。例如,如果所有磁盤划分在根分區下(/),運行根目錄就選擇/var/mongodb/(var目錄一般用來存儲運行數據,如數據庫文件等),如果磁盤主要划分在home分區(/home),下就選擇/home/var/mongodb/。
以所有磁盤划分在根分區為例,配置服務器的運行目錄為/var/mongodb/confsrv/,路由的運行目錄為/var/mongodb/router/,分片的運行目錄為/var/mongodb/shard1/、/var/mongodb/shard2/、/var/mongodb/shard3/。每個節點的配置文件、日志文件、PID文件都輸出到運行目錄中。另外除了路由節點之外,其余節點都需要存儲數據,所以都在運行目錄下創建dbpath文件夾作為數據目錄。
至此各個節點的運行路徑就划分完成,如下表所示:
序號 |
組件 |
IP |
運行目錄 |
數據目錄 |
1 |
配置服務器 primary |
10.20.50.142 |
/var/mongodb/confsrv/ |
/var/mongodb/confsrv/dbpath/ |
2 |
配置服務器 secondary |
10.20.50.143 |
/var/mongodb/confsrv/ |
/var/mongodb/confsrv/dbpath/ |
3 |
配置服務器 secondary |
10.20.50.144 |
/var/mongodb/confsrv/ |
/var/mongodb/confsrv/dbpath/ |
4 |
分片1 primary |
10.20.50.142 |
/var/mongodb/shard1/ |
/var/mongodb/shard1/dbpath/ |
5 |
分片1 secondary |
10.20.50.145 |
/var/mongodb/shard1/ |
/var/mongodb/shard1/dbpath/ |
6 |
分片1 arbiter |
10.20.50.140 |
/var/mongodb/shard1/ |
/var/mongodb/shard1/dbpath/ |
7 |
分片2 primary |
10.20.50.143 |
/var/mongodb/shard2/ |
/var/mongodb/shard2/dbpath/ |
8 |
分片2 secondary |
10.20.50.140 |
/var/mongodb/shard2/ |
/var/mongodb/shard2/dbpath/ |
9 |
分片2 arbiter |
10.20.50.141 |
/var/mongodb/shard2/ |
/var/mongodb/shard2/dbpath/ |
10 |
分片3 primary |
10.20.50.144 |
/var/mongodb/shard3/ |
/var/mongodb/shard3/dbpath/ |
11 |
分片3 secondary |
10.20.50.141 |
/var/mongodb/shard3/ |
/var/mongodb/shard3/dbpath/ |
12 |
分片3 arbiter |
10.20.50.145 |
/var/mongodb/shard3/ |
/var/mongodb/shard3/dbpath/ |
13 |
路由 |
10.20.50.142 |
/var/mongodb/router/ |
無 |
14 |
路由 |
10.20.50.143 |
/var/mongodb/router/ |
無 |
15 |
路由 |
10.20.50.144 |
/var/mongodb/router/ |
無 |
4.1.3 集群規划清單
根據前兩節的分析,對集群中各組件的最終規划如下:
序號 |
組件 |
IP |
Port |
副本集名稱 |
進程 |
運行目錄 |
1 |
配置服務器 primary |
10.20.50.142 |
28017 |
confsrv |
mongod |
/var/mongodb/confsrv/ |
2 |
配置服務器 secondary |
10.20.50.143 |
28017 |
confsrv |
mongod |
/var/mongodb/confsrv/ |
3 |
配置服務器 secondary |
10.20.50.144 |
28017 |
confsrv |
mongod |
/var/mongodb/confsrv/ |
4 |
分片1 primary |
10.20.50.142 |
27017 |
shard1 |
mongod |
/var/mongodb/shard1/ |
5 |
分片1 secondary |
10.20.50.145 |
27017 |
shard1 |
mongod |
/var/mongodb/shard1/ |
6 |
分片1 arbiter |
10.20.50.140 |
28017 |
shard1 |
mongod |
/var/mongodb/shard1/ |
7 |
分片2 primary |
10.20.50.143 |
27017 |
shard2 |
mongod |
/var/mongodb/shard2/ |
8 |
分片2 secondary |
10.20.50.140 |
27017 |
shard2 |
mongod |
/var/mongodb/shard2/ |
9 |
分片2 arbiter |
10.20.50.141 |
28017 |
shard2 |
mongod |
/var/mongodb/shard2/ |
10 |
分片3 primary |
10.20.50.144 |
27017 |
shard3 |
mongod |
/var/mongodb/shard3/ |
11 |
分片3 secondary |
10.20.50.141 |
27017 |
shard3 |
mongod |
/var/mongodb/shard3/ |
12 |
分片3 arbiter |
10.20.50.145 |
28017 |
shard3 |
mongod |
/var/mongodb/shard3/ |
13 |
路由 |
10.20.50.142 |
29017 |
無 |
mongos |
/var/mongodb/router/ |
14 |
路由 |
10.20.50.143 |
29017 |
無 |
mongos |
/var/mongodb/router/ |
15 |
路由 |
10.20.50.144 |
29017 |
無 |
mongos |
/var/mongodb/router/ |
各台主機上部署的組件清單如下:
序號 |
主機 |
組件 |
1 |
10.20.50.142 |
配置服務器-primary(28017) 分片1-primary(27017) 路由(29017) |
2 |
10.20.50.143 |
配置服務器-secondary(28017) 分片2-primary(27017) 路由(29017) |
3 |
10.20.50.144 |
配置服務器-secondary(28017) 分片3-primary(27017) 路由(29017) |
4 |
10.20.50.145 |
分片1-secondary(27017) 分片3- arbiter(28017) |
5 |
10.20.50.140 |
分片2-secondary(27017) 分片1- arbiter(28017) |
6 |
10.20.50.141 |
分片3-secondary(27017) 分片2- arbiter(28017) |
組件規划確定后,下面就進入搭建集群的實操階段。
4.2 創建配置服務器
- 創建運行目錄
在142、143、144服務器上創建運行目錄(應該放磁盤容量最大的卷中),例如:
mkdir -p /var/mongodb/confsrv/dbpath/ |
- 創建配置文件
在運行目錄(/var/mongodb/confsrv/)中創建配置文件mongod-cs.cnf,內容如下:
sharding: clusterRole: configsvr replication: replSetName: confsrv oplogSizeMB: 10240 systemLog: destination: file path: /var/mongodb/confsrv/mongod-cs.log logAppend: true net: port: 28017 storage: dbPath: /var/mongodb/confsrv/dbpath/ directoryPerDB: true processManagement: fork: true pidFilePath: /var/mongodb/confsrv/mongod-cs.pid |
其中依次設置了:集群角色(configsrv)、副本集名稱(confsrv)、操作日志大小、日志設置、端口(28017)、存儲設置、后台運行(fork)、PID文件路徑。
更多配置見:https://docs.mongodb.com/manual/reference/configuration-options/
注意:配置中所有冒號后面必須增加空格
- 啟動mongod實例
mongod --config /var/mongodb/confsrv/mongod-cs.cnf |
注意:如果運行在啟用了NUMA的主機上,使用numactl來啟動:
numactl --interleave=all mongod --config /var/mongodb/confsrv/mongod-cs.cnf |
啟動之后,根據配置,日志文件、pid文件會寫入/var/mongodb/confsrv/,數據會寫入/var/mongodb/confsrv/dbpath/。
注意:確保在三個配置服務器節點上(142、143、144)均完成上述步驟。
- 連接並初始化
在142上使用mongo shell連接mongod實例,執行:
mongo --port 28017 |
在mongo shell中初始化副本集(注意_id要與配置文件中的replSetName一致,host中為主機IP或可解析域名+端口),執行:
rs.initiate( { _id: "confsrv", configsvr: true, members: [ { _id : 0, host : "10.20.50.142:28017" }, { _id : 1, host : "10.20.50.143:28017" }, { _id : 2, host : "10.20.50.144:28017" }
] } ) |
如果操作完成,會返回成功的提示信息({"ok" : 1.0}),否則會給出錯誤信息。
這樣一主二從的配置服務器副本集就搭建完成。
查看副本集配置,執行:
rs.conf() |
查看副本集狀態,執行:
rs.status() |
- 添加副本集成員(可選)
如果還要追加副本集成員,通過mongo shell連接配置服務器副本集主節點實例,然后執行:
rs.add("<host>:<port>") |
其中<host>、<port>替換為相應節點的主機名(ip或域名)和端口
詳細操作可以參考:https://docs.mongodb.com/manual/tutorial/expand-replica-set/
注:配置完成后優先確認網絡通暢,防火牆關閉或端口不被屏蔽,如果中間有操作錯誤,可以使用如下命令進行重新配置:
conf = { _id: "confsrv", configsvr: true, members: [ { _id : 0, host : "10.20.50.140:28017" }, { _id : 1, host : "10.20.50.141:28017" }, { _id : 2, host : "10.20.50.142:28017" }
] } 回車 rs.initiate(conf,{force:true}) //已經運行的系統此命令不建議使用 |
4.3 創建分片
- 創建運行目錄
以分片1為例,在142服務器上創建運行目錄(應該放在磁盤容量最大的卷中),例如:
mkdir -p /var/mongodb/shard1/dbpath/ |
- 創建配置文件
在運行目錄(/var/mongodb/shard1/)中創建配置文件mongod- sh.cnf,內容如下:
sharding: clusterRole: shardsvr replication: replSetName: shard1 oplogSizeMB: 10240 systemLog: destination: file path: /var/mongodb/shard1/mongod-sh.log logAppend: true net: port: 27017 storage: dbPath: /var/mongodb/shard1/dbpath/ directoryPerDB: true processManagement: fork: true pidFilePath: /var/mongodb/shard1/mongod-sh.pid |
其中依次設置了:集群角色(shardsvr)、副本集名稱(shard1)、操作日志大小、日志設置、端口(27017)、存儲設置、后台運行(fork)、PID文件路徑。
更多配置見:https://docs.mongodb.com/manual/reference/configuration-options/
- 啟動mongod實例
mongod --config /var/mongodb/shard1/mongod-sh.cnf |
注意:如果運行在啟用了NUMA的主機上,使用numactl來啟動:
numactl --interleave=all mongod --config /var/mongodb/shard1/mongod-sh.cnf |
啟動之后,根據配置,日志文件、pid文件會寫入/var/mongodb/shard1/,數據會寫入/var/mongodb/shard1/dbpath/。
在145服務器上完成以上步驟,在140服務器也完成以上步驟(注意:根據規划,需要將配置文件中的端口改為28017)
- 連接並初始化
在142上使用mongo shell連接mongod實例,執行:
mongo --port 27017 或者 mongo |
在mongo shell中初始化副本集(注意:_id要與配置文件中的replSetName一致,host中為主機IP或可解析域名+端口),執行:
rs.initiate( { _id: "shard1", members: [ { _id : 0, host : "10.20.50.142", priority: 10 }, { _id : 1, host : "10.20.50.145", priority:5 }
] } ) |
primary節點和secondary節點就加入分片副本集了,還需要添加arbiter節點,執行:
rs.addArb("10.20.50.140:28017") |
這樣一主一從一仲裁的分片集群就搭建完成。
查看副本集配置,執行:
rs.conf() |
查看副本集狀態,執行:
rs.status() |
- 添加副本集成員(可選)
如果還要追加副本集成員,通過mongo shell連接配置服務器副本集主節點實例,然后執行:
rs.add("<host>:<port>") |
其中<host>、<port>替換為相應節點的主機名(ip或域名)和端口
詳細操作可以參考:https://docs.mongodb.com/manual/tutorial/expand-replica-set/
- 按照1-5步,分別創建分片2副本集(143、140、141)和分片3副本集(144、141、145)
分片2、分片3的配置如下,僅僅是replSetName和運行目錄不同:
sharding: clusterRole: shardsvr replication: replSetName: shard2 oplogSizeMB: 10240 systemLog: destination: file path: /var/mongodb/shard2/mongod-sh.log logAppend: true net: port: 27017 storage: dbPath: /var/mongodb/shard2/dbpath/ directoryPerDB: true processManagement: fork: true pidFilePath: /var/mongodb/shard2/mongod-sh.pid |
sharding: clusterRole: shardsvr replication: replSetName: shard3 oplogSizeMB: 10240 systemLog: destination: file path: /var/mongodb/shard3/mongod-sh.log logAppend: true net: port: 27017 storage: dbPath: /var/mongodb/shard3/dbpath/ directoryPerDB: true processManagement: fork: true pidFilePath: /var/mongodb/shard3/mongod-sh.pid |
另外,在執行步驟4進行初始化時,注意對應修改_id和host。
4.4 創建查詢路由
- 創建運行目錄
在142服務器上創建運行目錄(應該放在磁盤容量最大的卷中),例如:
mkdir -p /var/mongodb/router/ |
- 創建配置文件
在運行目錄(/var/mongodb/router/)中創建配置文件mongos.cnf,內容如下:
sharding: configDB: confsrv/10.20.50.142:28017,10.20.50.143:28017,10.20.50.144:28017 systemLog: destination: file path: /var/mongodb/router/mongos.log logAppend: true net: port: 29017 processManagement: fork: true pidFilePath: /var/mongodb/router/mongos.pid |
其中依次設置了:配置服務器(configDB)、系統日志、端口(29017)、后台運行(fork)、PID文件路徑。
- 啟動mongos實例(注意:這里是mongos,而上面都是mongod)
mongos --config /var/mongodb/router/mongos.cnf |
啟動之后,根據配置,日志文件、pid文件會寫入/var/mongodb/router/。
- 在143、144上重復上述步驟
注意:當路由(mongos)成為性能瓶頸時,可以多配置幾個。
4.5 添加分片
在142上(143、144也行)使用mongo shell連接mongos實例,執行:
mongo --port 29017 |
然后將上面創建的三個分片依次添加進來,執行:
sh.addShard( "shard1/10.20.50.142:27017") sh.addShard( "shard2/10.20.50.143:27017") sh.addShard( "shard3/10.20.50.144:27017") |
操作完成后,可以查看分片集群狀態,執行:
sh.status() |
會發現每個分片除了添加的主節點外,從節點也自動加入了,后續分片副本集如果發生變化(增刪節點)也會自動識別出來。
shards: { "_id" : "shard1", "host" : "shard1/10.20.50.142:27017,10.20.50.145:27017", "state" : 1 } { "_id" : "shard2", "host" : "shard2/10.20.50.143:27017,10.20.50.140:27017", "state" : 1 } { "_id" : "shard3", "host" : "shard3/10.20.50.144:27017,10.20.50.141:27017", "state" : 1 } |
4.6 設置開機啟動
通過crontab將分片集群各組件設置為開機啟動,以142主機為例,具體操作如下:
- 編輯crontab,執行:
crontab -e |
- 在打開的crontab文件中末尾追加以下內容:
@reboot /opt/mongodb/bin/mongod --config /var/mongodb/confsrv/mongod-cs.cnf @reboot /opt/mongodb/bin/mongod --config /var/mongodb/shard1/mongod-sh.cnf @reboot /opt/mongodb/bin/mongos --config /var/mongodb/router/mongos.cnf |
對於143、144、145、140、141五台主機,crontab添加的內容如下(根據組件規划):
@reboot /opt/mongodb/bin/mongod --config /var/mongodb/confsrv/mongod-cs.cnf @reboot /opt/mongodb/bin/mongod --config /var/mongodb/shard2/mongod-sh.cnf @reboot /opt/mongodb/bin/mongos --config /var/mongodb/router/mongos.cnf |
@reboot /opt/mongodb/bin/mongod --config /var/mongodb/confsrv/mongod-cs.cnf @reboot /opt/mongodb/bin/mongod --config /var/mongodb/shard3/mongod-sh.cnf @reboot /opt/mongodb/bin/mongos --config /var/mongodb/router/mongos.cnf |
@reboot /opt/mongodb/bin/mongod --config /var/mongodb/shard1/mongod-sh.cnf @reboot /opt/mongodb/bin/mongod --config /var/mongodb/shard3/mongod-sh.cnf |
@reboot /opt/mongodb/bin/mongod --config /var/mongodb/shard2/mongod-sh.cnf @reboot /opt/mongodb/bin/mongod --config /var/mongodb/shard1/mongod-sh.cnf |
@reboot /opt/mongodb/bin/mongod --config /var/mongodb/shard3/mongod-sh.cnf @reboot /opt/mongodb/bin/mongod --config /var/mongodb/shard2/mongod-sh.cnf |
5 數據庫初始化
根據目前需求,過人過車數據存放在o2m數據庫中。相關集合如下表所示:
序號 |
集合名稱 |
所存數據 |
1 |
passPerson1 |
客運站過人 |
2 |
passPerson2 |
火車站過人 |
3 |
passPerson3 |
機場過人 |
4 |
passPerson4 |
檢查站過人 |
5 |
passPerson5 |
酒店過人 |
6 |
passPerson7 |
二手車交易過人 |
7 |
passPerson99 |
社會化過人 |
8 |
visitorPerson |
訪客機過人 |
9 |
vehicle |
檢查站過車 |
其中客運站過人、火車站過人、機場過人、檢查站過人需要進行分片處理,所以先o2m數據庫啟用分片,然后再將上述四個集合分片。
- 連接到mongos,執行:
mongo --host 10.20.50.142 --port 29017 |
2. 對o2m數據庫啟用分片,執行:
sh.enableSharding("o2m") |
3. 將相關集合分片(這里采取stationNo+passTime的組合片鍵),執行:
sh.shardCollection("o2m.passPerson1", { stationNo:1, passTime:1 } ) sh.shardCollection("o2m.passPerson2", { stationNo:1, passTime:1 } ) sh.shardCollection("o2m.passPerson3", { stationNo:1, passTime:1 } ) sh.shardCollection("o2m.passPerson4", { stationNo:1, passTime:1 } ) |
注:片鍵后面的方向只能是升序(即1)
4. 查詢分片集合的數據分布情況(例如passPerson1),執行:
db.passPerson1.stats() |
返回結果的shards節點中包含有各分片情況:
- 添加索引
db.passPerson1.createIndex( { passTime:1, stationNo:1, nationCode:1, genderCode:1, cardNoPrefix6:1 } ) db.passPerson1.createIndex( { cardNo:1 } ) |
注:因為o2m數據庫已經啟用分片,其中未分片的集合會存儲在某個單一分片上,之后某個集合需要分片,參考步驟3執行即可。
6 數據遷移
- 導出原始數據
例如,從原副本集(運行在27017端口)中導出o2m數據庫,執行:
mongodump --host 10.20.50.135 --db o2m -o /tmp/mongodump/ |
數據會導出到/tmp/mongodump/下的o2m目錄中
- 導入分片集群
數據導入需要通過mongos,使用-h參數指定mongos實例的IP和端口,使用-d參數指定數據庫,試用-c參數指定集合,例如導入火車站過人數據,執行:
mongorestore -h 10.20.50.140:29017 -d o2m -c passPerson2 /tmp/mongodump/test/railwayPerson.bson |
導入過程中,會顯示進度信息。
7 應用遷移
分片集群對於客戶端應用來說是透明的,客戶端應用只需將分片集群視為單個mongod實例,所有客戶端請求都連接分片集群中的路由(mongos)。
應用只需將原有Mongo配置指向路由即可(例如10.20.50.140:29017),如果想要使用多個路由,可以將多個路由地址用逗號連接,類似副本集的配置(192.168.30.139:29017,192.168.30.141:29017,192.168.30.145:29017)