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

即完整命令参考上面步骤三。

 

配置文件启动的方式,还不明就里。有模板的同学,可分享一下。

 

posted @ 2018-03-20 14:10  鸾舞春秋  阅读(263)  评论(0编辑  收藏  举报