Mongo低版本和高版本的sharding集群配置,细节不太一样。目前网上的配置文档大都是针对低版本的。本人在配置3.6.1版本的mongosharding集群的过程中,碰到不少问题,官方文档没有直观的示例,参考起来有点一头雾水。特整理记录下自己的测试环境sharding集群配置过程,供大家参考。
Mongo sharding集群由config server,mongos(路由)及shards服务器组成。他们的关系及扮演的角色,网上到处都是,不再详细介绍。
最开始,打算将config、mongos、shards等所有组件都部署到一台机器。部署的过程中碰到问题,启动不了,以为是不能部署到一台机器导致的,于是最后的方案是部署到4台机器。解决碰到的坑后,我觉得,部署到同一台机器也是可以的。那些碰到的问题,并不是部署到同一台机器引起的。
服务器规划如下:
一、 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,修复模式启动,然后正常启动。
请参考:
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 |
即完整命令参考上面步骤三。
配置文件启动的方式,还不明就里。有模板的同学,可分享一下。