Mongo 3.6.1版本Sharding叢集配置
Mongo低版本和高版本的sharding叢集配置,細節不太一樣。目前網上的配置文件大都是針對低版本的。本人在配置3.6.1版本的mongosharding叢集的過程中,碰到不少問題,官方文件沒有直觀的示例,參考起來有點一頭霧水。特整理記錄下自己的測試環境sharding叢集配置過程,供大家參考。
Mongo sharding叢集由config server,mongos(路由)及shards伺服器組成。他們的關係及扮演的角色,網上到處都是,不再詳細介紹。
最開始,打算將config、mongos、shards等所有元件都部署到一臺機器。部署的過程中碰到問題,啟動不了,以為是不能部署到一臺機器導致的,於是最後的方案是部署到4臺機器。解決碰到的坑後,我覺得,部署到同一臺機器也是可以的。那些碰到的問題,並不是部署到同一臺機器引起的。
伺服器規劃如下:
機器 |
服務 |
Dbpath |
logpath |
port |
120 |
Config Server |
data/config/data |
data/config/log/config.log |
30000 |
121 |
||||
131 |
||||
100 |
mongos |
null |
data/mongos/log/ mongos.log |
27017 |
120 |
Shard1 |
data/shard1/data/set1data/shard1/data/set2data/shard1/data/set3 |
data/shard1/logs/set1.logdata/shard1/logs/set2.log
data/shard1/logs/set3.log |
270172701827019 |
121 |
Shard2 |
data/shard2/data/set1data/shard2/data/set2data/shard2/data/set3 |
data/shard2/logs/set1.logdata/shard2/logs/set2.logdata/shard2/logs/set3.log |
270172701827019 |
一、 Mongo下載及安裝
從mongo官網下載mongodb-linux-x86_64-rhel62-3.6.1.tgz,上傳到每臺伺服器的/app/mongo目錄。
執行:tar -xvzf mongodb-linux-x86_64-rhel62-3.6.1.tgz解壓即可。
二、 Config Server配置
高版本的mongo要求config server必須是叢集模式,不能單點,包括配置和訪問都會涉及這點,與舊版不同。
每臺伺服器上執行:
mkdir -p /app/mongo/data/config/data mkdir -p /app/mongo/data/config/log ./mongod --dbpath=/app/mongo/data/config/data --logpath=/app/mongo/data/config/log/config.log --port=30000 --fork --bind_ip_all --configsvr --replSet=conf |
進入其中任意一臺伺服器,執行如下步驟:
cd /app/mongo/mongodb-linux-x86_64-rhel62-3.6.1/bin ./mongo --port 30000 config = {_id:"conf", members:[ {_id:0, host:"10.100.31.120:30000"}, {_id:1, host:"10.100.31.121:30000"}, {_id:2, host:"10.100.31.131:30000"} ] }; rs.initiate(config); |
Config server就配置完成了。
三、 路由Mongos的配置
登入10.100.31.100機器:
mkdir -p /app/mongo/data/mongos/log ./mongos --logpath=/app/mongo/data/mongos/log/mongos.log --port=27017 --fork --bind_ip_all --configdb=conf/10.100.31.120:30000,10.100.31.121:30000,10.100.31.131:30000 |
看起來是不是很簡單?但網上沒有這樣的示例。也是探索出來的。後面“碰到的問題”,會提一下。
四、 Shard伺服器配置
Shard伺服器的配置沒碰到大問題,注意別筆誤就行。Shard1還是shard2,寫準了,多餘的空格要留心,會有影響。我是幾個筆誤磕巴了一下。
10.100.31.120伺服器:
mkdir -p /app/mongo/data/shard1/app/mongo/data/set1 mkdir -p /app/mongo/data/shard1/app/mongo/data/set2 mkdir -p /app/mongo/data/shard1/app/mongo/data/set3 mkdir -p /app/mongo/data/shard1/logs ./mongod --dbpath=/app/mongo/data/shard1/app/mongo/data/set1 --logpath=/app/mongo/data/shard1/logs/set1.log --port=27017 --fork --bind_ip_all --shardsvr --replSet=shard1 ./mongod --dbpath=/app/mongo/data/shard1/app/mongo/data/set2 --logpath=/app/mongo/data/shard1/logs/set2.log --port=27018 --fork --bind_ip_all --shardsvr --replSet=shard1 ./mongod --dbpath=/app/mongo/data/shard1/app/mongo/data/set3 --logpath=/app/mongo/data/shard1/logs/set3.log --port=27019 --fork --bind_ip_all --shardsvr --replSet=shard1 |
通過mongoshell進入任意一個示例,此處我們選擇27017示例,配置副本集並初始化:
./mongo 10.100.31.120:27017/admin > cnf = {_id:"shard1", members:[ {_id:1, host:"10.100.31.120:27017"}, {_id:2, host:"10.100.31.120:27018"}, {_id:3, host:"10.100.31.120:27019"}, ] } > rs.initiate(cnf); { "ok" : 1 } |
可以檢查一下副本集狀態
> rs.status()
10.100.31.121伺服器一樣:
mkdir -p /app/mongo/data/shard2/app/mongo/data/set1 mkdir -p /app/mongo/data/shard2/app/mongo/data/set2 mkdir -p /app/mongo/data/shard2/app/mongo/data/set3 mkdir -p /app/mongo/data/shard2/logs ./mongod --dbpath=/app/mongo/data/shard2/app/mongo/data/set1 --logpath=/app/mongo/data/shard2/logs/set1.log --port=27017 --fork --bind_ip_all --shardsvr --replSet=shard2 ./mongod --dbpath=/app/mongo/data/shard2/app/mongo/data/set2 --logpath=/app/mongo/data/shard2/logs/set2.log --port=27018 --fork --bind_ip_all --shardsvr --replSet=shard2 ./mongod --dbpath=/app/mongo/data/shard2/app/mongo/data/set3 --logpath=/app/mongo/data/shard2/logs/set3.log --port=27019 --fork --bind_ip_all --shardsvr --replSet=shard2 ./mongo 10.100.31.121:27017/admin > cnf = {_id:"shard2", members:[ {_id:1, host:"10.100.31.121:27017"}, {_id:2, host:"10.100.31.121:27018"}, {_id:3, host:"10.100.31.121:27019"}, ] } > rs.initiate(cnf); { "ok" : 1 } |
五、 Mongos上新增shard節點
進入mongos所在伺服器的mongoshell,通過addshard來加入shard節點,多個副本集用逗號分隔:
./mongo 10.100.31.100:27017/admin mongos> db.runCommand( {addshard : "shard1/10.100.31.120:27017,10.100.31.120:27018,10.100.31.120:27019"}); mongos> db.runCommand( { addshard : "shard2/10.100.31.121:27017,10.100.31.121:27018,10.100.31.121:27019"}); mongos> db.runCommand( { listshards : 1 } ); |
至此,mongo3.6.1版本sharding叢集搭建完畢。
六、 Mongo3.6.1版本sharding叢集搭建碰到的問題
上面的步驟看起來是不是很清爽?很簡單?很容易?但在沒有前人完整示例的情況下,自己探索,處處踩坑處處碰壁,還是很痛苦的。下面把搭建過程中需要注意的方面和碰到的問題跟大家分享一下。
首先,配置configserver時,碰到no route to host,connect refused等。看起來似乎和網路、防火牆及埠有關。實際上,蹚完坑的結果是,非也,非也,和mongo自己的一個配置有關。Mongo裡有個bind ip的概念。網上很多地方,及官方都提到了,但說得雲裡霧裡,不太明白。我搭建的過程中,這個問題困擾我了很長時間。網友這篇文章及其中提到的另一篇文章講到了這個問題,但講得並不是很透,不過可以看看,有助於更好地瞭解這個問題:https://www.cnblogs.com/chy1000/p/3260215.html。網上屢屢出現繫結127.0.0.1或/及localhost的說法,不明白。繫結127.0.0.1或/及localhost,叢集跨機訪問能行?顯然不科學啊。Linux下,埠繫結ip,如果不想限制ip的話,通常指定為0.0.0.0。感覺應該走這樣的套路才可以。研究了一下mongo的help,發現裡面有個引數:--bind_ip_all。眼睛一亮。這個應該好使!
說說我的經歷:
首先,配置configserver的時候,我在三臺機器分別部署了mongo,具體步驟見前面。
最後一步執行rs.initiate(config); 的時候,出錯,大概錯誤是訪問不到指定mongo。
telnet 10.100.31.131 30000
報:No route to host
執行:sudo iptables –F
No route的問題解決了。
但是再次執行rs.initiate(config); 還是失敗。
這次是報connect refused。
根據網上的提示,這是埠未開放訪問的原因,需要開放伺服器相關埠。
但後來瞭解到我的遭遇根本不是這個問題。因為我們測試環境的機器,iptables是關閉、未開啟的。也就是任何埠,隨意訪問,隨便用。
但為了方便伺服器啟用了iptables策略的同學,這裡還是把遇到connect refused時,iptables開放埠的配置辦法給大家分享下:
Linux開放埠的步驟:
vi /etc/sysconfig/iptables |
新增你需要的埠,比如:
#mongo ports -A INPUT -m state --state NEW -m tcp -p tcp --dport 30000 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 27017 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 27018 -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 27019 -j ACCEPT |
注意:這裡有個坑,新增的位置必須在 |
儲存修改後,執行:
service iptables restart |
就可以了。
剛才說到,我的測試伺服器埠是ok的。可我的mongo為何死活不通呢?這和mongo bind ip配置項有關。加上啟動引數--bind_ip_all就好了。
具體命令見前面步驟。
不過,實際配置過程中,我加上--bind_ip_all後,又碰到問題。
報錯:
ERROR: child process failed, exited with error number 100 |
調研了一下,這是因為之前啟動mongo,未正常關閉導致的問題。比如用kill -9 23245殺掉了mongo程序。Mongo強烈不建議用kill命令來殺程序。如果實在要用,也不要用kill -9 <pid>,有網友說可考慮kill -2 <pid>。但是,以我的親身實踐,kill-2也不好。還是要老老實實用官方推薦的shutdown辦法:
./mongo Use admin db.shutdownServer(); |
沒殺乾淨怎麼辦?
主要是rm /app/mongo/data/config/data/mongod.lock,修復模式啟動,然後正常啟動。
請參考:
網友的啟動方式是用配置檔案。命令列修復模式啟動,其實就是加個--repair引數。
我照網友的說法,repair方式啟動,接著正常啟動,好像還是有問題,不過報錯變了:
ERROR: child process failed, exited with error number 48 |
結果碼由100變成了48。
看了下mongo啟動日誌:Address already in use
netstat –lp 檢查。發現mongo已經起起來了,不知道是其中哪一次啟動成功的。
試了下可以用。
看來是根據網友的說法,修復啟動後,已經成功啟動mongo了。
照貓畫虎部署131伺服器的config server,又碰到新問題,報錯如下:
2018-01-04T10:56:39.936+0800 E STORAGE [initandlisten] WiredTiger error (1) [1515034599:936145][6277:0x7f76fc3e6a80], file:WiredTiger.wt, connec tion: /app/mongo/data/config/data/WiredTiger.wt: handle-open: open: Operation not permitted |
查了一下,可能和之前用root使用者啟動過mongo有關,導致普通使用者起不了。
怎麼破?
Rm –R /app/mongo/data 用root使用者賦權:chmod 777 mongo 切換到app使用者:mkdir data 然後依次建立 config的data和log目錄: mkdir -p /app/mongo/data/config/data mkdir -p /app/mongo/data/config/log 然後app使用者啟動mongo,沒問題。 |
以上是配在config server的時候碰到的問題,配mongos(路由器)的時候,碰到兩個問題,其中一個仍然是bind ip的問題,像config server配置一樣,加上--bind_ip_all啟動引數即可。另一個問題,則是“複製集”的概念。高版本的mongo,強調複製集的概念,很多地方多強制要求配置複製集,訪問也用複製集方式的連線串。例如:配置mongos(路由器)的時候,網上的啟動示例如下:
./mongos --logpath=/app/mongo/data/mongos/log/mongos.log --port=27017 --fork --configdb=10.100.31.120:30000 |
3.6.1版本這樣是不行的。會報錯:BadValue:configdb supports only replica set connection string。configdb引數強制必須用複製集連線串。格式類似:
conf/10.100.31.120:30000,10.100.31.121:30000,10.100.31.131:30000 |
即完整命令參考上面步驟三。
配置檔案啟動的方式,還不明就裡。有模板的同學,可分享一下。