最早使用mongodb的时候贪省事,就起一个单节点的就好了。后来,公司要用,为了可用性就搭了一个replica set集群,似乎也挺好的。后来出了点问题,发现mongo集群并发上不去。后来查了下,replica set只能做到主备,每个进程的数据是一样的,同时为了保证一致性,事务是多进程间同步等待的。这样无论是对写性能,还是大数据量都是很大的瓶颈。而网上盛传的高并发高性能,似乎都是shared cluster,似乎是因为分片的存在,导致各种粒度都变细了。而且,鉴于之前领导写mongo监听事件时,发现单例是无法响应事件的,所以,还是趁早搭建一个最终形态的集群开发用吧,尽管可能自己用不着,但是至少这个环境会和最终的生产环境相同,没啥坏处嘛。下面我们来搭建吧。
主要参考: https://www.cnblogs.com/xybaby/p/6832296.html
说实话,mongo的sharded cluster需要的进程有点多,我也不可能每个进程开个虚拟机。鉴于买了新笔记本,资源比较阔绰(32G内存,哇嘎嘎噶),我开了两个1核3G的虚拟机用来搭建本机的开发环境。目前这两个环境都是干净的,centos7。就用这两台机器吧。我下载的是3.6.4版本的安装包,没用最新的4.0,毕竟文档较少,也搞不清楚究竟该了啥,先把老版本搞通吧。解压到/opt/mongodb目录,配置文件放在/etc/mongodb,数据放在/home/mongo_sharded_cluster_data
懒得扣官网了,就找了个帖子,讲得挺好的(https://www.cnblogs.com/xybaby/p/6832296.html) 看我能不能搭出来吧。我们来总结下大体思路吧,也明确下我们接下来要做的事情。首先,sharded cluster是建立在多个replica set的基础之上的,所以,我们将会搭建两个三节点的replica set(master、secondary、arbiter),然后在此之上需要的最小集,三个config server,一个router。这就是集群所需要的全部节点了。事实上,这个集群搭建完成之后还是不能完成sharded功能,还需要手动配置需要分片的数据库及分片规则。这就是本次的实验范围了,至于后续的更具体的控制,待我探明了后面的文章再整理吧。
我的计划是,在我的每个虚拟机里都搭建一个完整的replica set集群,虽然会使其可用性变得没啥用,但是,好管理,以后不会忘了。创建一下三个文件:
/etc/mongodb/mongo_repica_data1.cnf
/etc/mongodb/mongo_repica_data2.cnf
/etc/mongodb/mongo_repica_data3.cnf
每个文件的内容如下:
/etc/mongodb/mongo_repica_data1.cnf
dbpath=/home/mongo_sharded_cluster_data/data1 # 数据存储的路径
logpath=/home/mongo_sharded_cluster_data/data1/log/mongo.log # 日志的存储路径
logappend=true # 日志是否总是在后面附加
fork=true # 是否后台启动
pidfilepath=/home/mongo_sharded_cluster_data/data1/mongo.pid # pid文件地址
port=27001 # 监听端口
bind_ip=0.0.0.0 # 绑定Ip,这个是所有的ip都可以访问该进程
replSet=repl99 # replSet名称,要相同才能进入同一个replSet
smallfiles=true # 使用一种很小的格式的文件记录数据
journal=true # 开启日志,似乎默认就是开启的
/etc/mongodb/mongo_repica_data2.cnf
dbpath=/home/mongo_sharded_cluster_data/data2
logpath=/home/mongo_sharded_cluster_data/data2/log/mongo.log
logappend=true
fork=true
pidfilepath=/home/mongo_sharded_cluster_data/data2/mongo.pid
port=27002
bind_ip=0.0.0.0
replSet=repl99
smallfiles=true
journal=true
/etc/mongodb/mongo_repica_data3.cnf
dbpath=/home/mongo_sharded_cluster_data/data3
logpath=/home/mongo_sharded_cluster_data/data3/log/mongo.log
logappend=true
fork=true
pidfilepath=/home/mongo_sharded_cluster_data/data3/mongo.pid
port=27003
bind_ip=0.0.0.0
replSet=repl99
smallfiles=true
journal=true
我们可以看到三个节点的配置几乎一模一样,只有日志、数据、pid文件位置以及监听端口不一样。是的,没错的,就是这样。需要注意的是,里面涉及到的所有的文件夹都需要自己先创建,mongo并不会自动创建。然后启动三个进程,命令分别如下:
/opt/mongodb/bin/mongod -f /etc/mongodb/mongo_repica_data1.cnf
/opt/mongodb/bin/mongod -f /etc/mongodb/mongo_repica_data2.cnf
/opt/mongodb/bin/mongod -f /etc/mongodb/mongo_repica_data3.cnf
这里有一个遗留问题。查看官网可以看到,https://docs.mongodb.com/v3.6/reference/configuration-options/ 这个才是真正的配置文件说明,但是,这里的属性配置是要报错的,我的属性是使用/opt/mongodb/bin/mongo --help 查的。这个我还没想通,有知道的还麻烦跟我说下。
启动之后,还是没完成的,我们需要对mongo进行配置,具体过程如下:
/opt/mongodb/bin/mongo 127.0.0.1:27001 //进入mongo的命令行
rs.status() //这个执行后,结果如下
{
"info" : "run rs.initiate(...) if not yet done for the set",
"ok" : 0,
"errmsg" : "no replset config has been received",
"code" : 94,
"codeName" : "NotYetInitialized"
}
可以看到,它提示我们需要初始化它。
repl99cfg={
"_id" : "repl99",
"members" : [
{
"_id" : 0,
"host" : "192.168.137.99:27001"
},
{
"_id" : 1,
"host" : "192.168.137.99:27002"
},
{
"_id" : 2,
"host" : "192.168.137.99:27003",
"arbiterOnly" : true
}
]
}
这类为了方便展示,其实,上面的内容需要在一行输入。repl99cfg,就是个变量名。
顶层的_id是replSet名称,标志了arbiterOnly的,是我们指定的仲裁者节点。
这里似乎还可以配置优先级,这次就不测试了。
rs.initiate(repl99cfg)
然后我们就成功了,这是再使用rs.status()查看状态,就可以看到replSet的状态了。
测试了下,这个状态,重启进程是不需要
接下来我们在192.168.137.98上配置另一个replSet,名字为repl98
根据建议,我这里配置了三个config节点,配置文件分别如下:
/etc/mongodb/mongo_config1.cnf
port=27011
dbpath=/home/mongo_sharded_cluster_data/config1
fork=true
logpath=/home/mongo_sharded_cluster_data/config1/log/mongo.log
pidfilepath=/home/mongo_sharded_cluster_data/config1/mongo.pid
configsvr=true
bind_ip=0.0.0.0
smallfiles=true
journal=true
/etc/mongodb/mongo_config2.cnf
port=27012
dbpath=/home/mongo_sharded_cluster_data/config2
fork=true
logpath=/home/mongo_sharded_cluster_data/config2/log/mongo.log
pidfilepath=/home/mongo_sharded_cluster_data/config2/mongo.pid
configsvr=true
bind_ip=0.0.0.0
smallfiles=true
journal=true
/etc/mongodb/mongo_config3.cnf
port=27013
dbpath=/home/mongo_sharded_cluster_data/config3
fork=true
logpath=/home/mongo_sharded_cluster_data/config3/log/mongo.log
pidfilepath=/home/mongo_sharded_cluster_data/config3/mongo.pid
configsvr=true
bind_ip=0.0.0.0
smallfiles=true
journal=true
最后进入mongo命令进行配置,如下(请一行输入):
rs.initiate({
_id:"cfgrepl",
configsvr:true,
version:1,
members:
[
{_id:0,host:"192.168.137.98:27011"},
{_id:1,host:"192.168.137.98:27012"},
{_id:2,host:"192.168.137.99:27013"}
]})
启动和之前差不多,这里就不写了,我是把config1和config2放在98上,config3放在99上,你放在哪个机器上无所谓,反正是搭着来开发的。release环境或者性能测试环境再好好琢磨吧。
这里有这么几个注意点,mongo3.4以后,config也需要被配置成replicaset了,具体的参照说明在官网(https://docs.mongodb.com/v3.4/tutorial/upgrade-config-servers-to-replica-set/) 。如上的配置也很清楚,比正常的replicaset也就多了一个configsvr=true,这是必须的,否则后面那个命令执行不成功。
本着高可用的出发呢,router应该不止一个节点,奈何看的博客里也只有一个节点,而且十二点多了,不想折腾了,回头再说吧,先搭通。我们就在99上搭建router吧。
/etc/mongodb/mongo_router.cnf
port=27101
configdb=cfgrepl/192.168.137.98:27011,192.168.137.98:27012,192.168.137.99:27013
fork=true
logpath=/home/mongo_sharded_cluster_data/route/log/mongo.log
pidfilepath=/home/mongo_sharded_cluster_data/route/mongo.pid
bind_ip=0.0.0.0
需要注意的是,启动命令变了,
/opt/mongodb/bin/mongos -f /etc/mongodb/mongo_router.cnf
这样就启动起来了,但是,具体的分片还需要具体配置,我们后续介绍。