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/set1

data/shard1/data/set2

data/shard1/data/set3

data/shard1/logs/set1.log

data/shard1/logs/set2.log

data/shard1/logs/set3.log

27017

27018

27019

121

Shard2

data/shard2/data/set1

data/shard2/data/set2

data/shard2/data/set3

data/shard2/logs/set1.log

data/shard2/logs/set2.log

data/shard2/logs/set3.log

27017

27018

27019

一、  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

 

 

注意:這裏有個坑,添加的位置必須在
    -A INPUT -j REJECT --reject-with icmp-host-prohibited  
    -A FORWARD -j REJECT --reject-with icmp-host-prohibited  
上方

保存修改後,執行:

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,修復模式啓動,然後正常啓動。

請參考:

https://www.cnblogs.com/joshua317/articles/5190385.html

https://www.cnblogs.com/qiuer/p/5488588.html

網友的啓動方式是用配置文件。命令行修復模式啓動,其實就是加個--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

即完整命令參考上面步驟三。

 

配置文件啓動的方式,還不明就裏。有模板的同學,可分享一下。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章