MongoDBv4.0.18 replica set 高可用集群搭建 (CentOS7.6)全网独有


单节点mongodb软件安装配置:
配置环境: 
[root@node250 ~]# uname -a 
Linux node250 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux 
[root@node250 ~]# cat /etc/redhat-release 
CentOS Linux release 7.6.1810 (Core) 
节点功能清单: 
功能节点       主机名:          IP              端口 
Replica Set          node250    172.16.1.250     27017          
Replica Set          node251    172.16.1.251     27017 
Replica Set           node252    172.16.1.252     27017 
  
  
安装步骤: 
note: 以下步骤以root用户身份来执行 
yum install lrzsz lsof vim nmap -y 


1.配置MongoDB的yum源 
  vi /etc/yum.repos.d/mongodb-org-4.0.repo 
[mongodb-org-4.0] 
name=MongoDB Repository 
baseurl=https://repo.mongodb.org/yum/redhat/7Server/mongodb-org/4.0/x86_64/ 
gpgcheck=1 
enabled=1 
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc 


这里可以修改 gpgcheck=0, 省去gpg验证。 


# yum makecache 


关闭防火墙: 
systemctl stop firewalld 
systemctl disable firewalld 
systemctl mask firewalld 
 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux 
setenforce 0 


2.安装MongoDB 


# yum install -y mongodb-org 


安装完毕后,看看都装到哪里去了。 
# rpm -ql mongodb-org-server 




3.  配置MongoDB【单机版】 
修改配置文件。 


注意 


1. 把bindIP设置为0.0.0.0(表示监听所有的网口地址),缺省是只监听127.0.0.1 


2.注意修改数据的存放目录。 


# vi /etc/mongod.conf 
# mongod.conf 


# for documentation of all options, see: 
#   http://docs.mongodb.org/manual/reference/configuration-options/ 


# where to write logging data. 
systemLog: 
  destination: file 
  logAppend: true 
  path: /var/log/mongodb/mongod.log 


# Where and how to store data. 
storage: 
  dbPath: /var/lib/mongo 
  journal: 
    enabled: true 
#  engine: 
#  mmapv1: 
#  wiredTiger: 


# how the process runs 
processManagement: 
  fork: true  # fork and run in background 
  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile 
  timeZoneInfo: /usr/share/zoneinfo 
setParameter: 
  enableLocalhostAuthBypass: false 
# network interfaces 
net: 
  port: 27017 
  bindIp: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting. 




#security: 
#security: 
#  clusterAuthMode: keyFile 
#  keyFile: /var/lib/mongo/key/repl_set.key 
#  authorization: enabled 
#operationProfiling: 


replication: 
  replSetName: rs0 
#sharding: 


## Enterprise-Only Options 


#auditLog: 


#snmp: 


注意:上面是按mong db replica set来配置的,这里设置了replica 副本名字,以及server之间认证的key file 


增加安全认证机制KeyFile: 
集群之间的安全认证
集群之间的复制增加keyFile认证: 
如何产生这个key ?按如下方式产生即可 
#mkdir -p /var/lib/mongo/key 
#cd /var/lib/mongo/ 
#chown mongod.mongod key -R 
# openssl rand -base64 522 >/var/lib/mongo/key/repl_set.key 
# chmod 400 /var/lib/mongo/key/repl_set.key 
#chown mongod.mongod ./repl_set.key  
将这个keyfile复制到所有的部署节点上的/var/lib/mongo/key/repl_set.key下面,并设置400权限。 
将该key放到集群中机器的每一台上,记住必须保持一致,权限设置成400; 




另外,mongod server是以mongod用户启动mongd的,注意它必须对访问的目录有权限 
cat  /usr/lib/systemd/system/mongod.service 
User=mongod 
Group=mongod 


4.启动MongoDB 
systemctl enable mongod 
systemctl start mongod 
systemctl status mongod 


查看端口是否正常: 
 nmap -p 27017 172.16.1.250 
 nmap -p 27017 172.16.1.251 
 nmap -p 27017 172.16.1.252 


5.如何连接到mongodb 
用mongodb自己带的client命令行工具 mongo 就行了. 


# /usr/bin/mongo  


MongoDB replica set :安装配置 


A replica set in MongoDB is a group of mongod processes that maintain the same data set. Replica sets provide redundancy and high availability, and are the basis for all production deployments. 


简单的说,复制集有多个MongoDB服务器,它们有相同的数据库,如果一个服务器因为网络故障或者停电DOWN了,其他服务器可以继续提供服务,这样可以提高数据源的可靠性和健壮性。详情见这里。 


MongoDB复制集包括一个PRIMARY,其他的都是SECONDARY,只有PRIMARY才能接受读写操作。PRIMARY会记录那些写的操作到一个日志当中,oplog,其他SECONDARY会按照这个日志,去操作他们的数据库来保持数据库的一致。 


本文适合于CentOS机器,用yum install来安装MongoDB v4.x。 
 1. 在集群中每个机器上安装MongodDB 
   在集群的每台机器(Centos)上用 yum来安装MongoDB4.0, 详见文章最开头 


注意: 1:先别启动mongDB。 


          2:  把第一台机器生成的 repl_set.key 同步到集群中所有的mongod节点上。注意本文启动mongod的用户是mongod,它必须对key有400的权限!否则mongo server起不来。 


2.  集群配置
每台服务器上添加: 
echo "rs.slaveOk()">>/root/.mongorc.js 


在每个机器上去编辑下面的配置文件。
vi /etc/mongod.conf
配置如下内容: 
# mongod.conf 


# for documentation of all options, see: 
#   http://docs.mongodb.org/manual/reference/configuration-options/ 


# where to write logging data. 
systemLog: 
  destination: file 
  logAppend: true 
  path: /var/log/mongodb/mongod.log 


# Where and how to store data. 
storage: 
  dbPath: /var/lib/mongo 
  journal: 
    enabled: true 
#  engine: 
#  mmapv1: 
#  wiredTiger: 


# how the process runs 
processManagement: 
  fork: true  # fork and run in background 
  pidFilePath: /var/run/mongodb/mongod.pid  # location of pidfile 
  timeZoneInfo: /usr/share/zoneinfo 


# network interfaces 
net: 
  port: 27017 
  bindIp: 0.0.0.0  # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting. 
setParameter: 
  enableLocalhostAuthBypass: false 


#security: 
#  clusterAuthMode: keyFile  #集群服务器节点之间验证的类型,集群配置完成后再加 
#  keyFile: /var/lib/mongo/key/repl_set.key  #集群服务器节点之间的认证,集群配置完成后再加 
#  authorization: enabled  #集群配置完成后再加授权功能 
#operationProfiling: 


replication: 
  replSetName: rs0  #名称 
  oplogSizeMB: 2048 
#sharding: 


## Enterprise-Only Options 


#auditLog: 


#snmp: 
注意:security.authorization:enabled注释掉了,这样进去才可以进行复制集初始化、新建用户等操作。 


4.启动复制集所有成员的mongod进程 


systemctl enable mongod 
systemctl start  mongod 


5.连接其中一个mongod,设置复制集的成员信息 
 下图添加了3台主机信息(如集群里有更多的主机,则依次按下面的格式加入即可) 
> config={_id: "rs0", members:[{_id:0,host:"172.16.1.250:27017"},{_id:1,host:"172.16.1.251:27017"},{_id:2,host:"172.16.1.252:27017"}]} 

        "_id" : "rs0", 
        "members" : [ 
                { 
                        "_id" : 0, 
                        "host" : "172.16.1.250:27017" 
                }, 
                { 
                        "_id" : 1, 
                        "host" : "172.16.1.251:27017" 
                }, 
                { 
                        "_id" : 2, 
                        "host" : "172.16.1.252:27017" 
                } 
        ] 

> rs.initiate(config) 

        "ok" : 1, 
        "operationTime" : Timestamp(1587997292, 1), 
        "$clusterTime" : { 
                "clusterTime" : Timestamp(1587997292, 1), 
                "signature" : { 
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), 
                        "keyId" : NumberLong(0) 
                } 
        } 

rs0:PRIMARY> rs.status();  #查看集群的状态 




重新登录,RS将自动显示primary和SECONDARY 
172.16.1.250 
rs0:PRIMARY> 


172.16.1.251 
rs0:SECONDARY> 


主库配置用户 
也可后面配置,开启keyfile认证就默认开启了auth认证了,为了保证后面可以登录,我提前创建了用户: 
6.创建相关用户 (必须在上面第5这步完成后才能做)在PRIMARY上面操作: 
use admin 
db.createUser({user:"admin",pwd:"admin123.",roles:[{role:"userAdminAnyDatabase",db:"admin"}]}) 
db.createUser({user:"root",pwd:"root123.",roles:[{role:"root",db:"admin"}]}) 
修改:
rs0:PRIMARY> db.updateUser("admin",{roles:[{role:"userAdminAnyDatabase",db:"admin"}]}) 
MongoDB规定,创建的第一个用户一定要是在admin数据库、并且角色是userAdminAnyDatabase。 
创建完第一个角色,用这个角色登录来创建其他角色。 


use admin 
db.auth("admin","admin123.") 
db.createUser({user:"clusterAdmin",pwd:"clusterAdmin123.",roles:[{role:"clusterAdmin",db:"admin"}]}) 
 member:PRIMARY> db.grantRolesToUser("admin", ["clusterAdmin"]) 
#这个角色可以进行复制集的管理(添加成员、查看状态等等)。 
  
7.最后 


把集群中所有主机的配置文件的security.authorization:true注释去掉,重启复制集。 


systemctl restart mongod 
现在要登录才能查看复制集状态了。 


登录查看集群状态: 
mongo 127.0.0.1:27017/admin -uadmin -padmin123. 
> rs.status(); 
> db.serverStatus().repl.primary  


关闭顺序注意下,mongodb集群有自动切换主库功能,如果先关主库,主库就切换到其它上面去了,这里预防主库变更,从库关闭后再关闭主库。 
  


测试: 
 创建用户和用户数据库 
启动认证 
开启了安全认证就可以开始对每个数据库进行安全认证了,首先给用户创建一个数据库: 


test_set:PRIMARY> use user_test 


switched to db user_test 


mongodb创建数据库直接use即可,此时show dbs是看不到该库的,需要插入一条数据才会现实出来,这里不演示; 


创建用户数据库的用户: 


rs0:PRIMARY> db.createUser({user:"user_test",pwd:"user_test123",roles:[{role:"readWrite",db:"user_test"}]}) 
Successfully added user: { 
        "user" : "user_test", 
        "roles" : [ 
                { 
                        "role" : "readWrite", 
                        "db" : "user_test" 
                } 
        ] 



创建完成会显示成功,可以用db.system.users.find()查看所有用户验证用户是否存在; 


5.2 验证用户登录 


#client操作 


mongo 127.0.0.1:27017/user_test �Cu user_test �Cp 


插入一条数据: 


> post={"title":"Myblogpost","content":"Here's my blog post","date":new Date()} 

        "title" : "Myblogpost", 
        "content" : "Here's my blog post", 
        "date" : ISODate("2020-04-27T02:35:27.209Z") 

rs0:PRIMARY> db.user_test.person.insert(post) 
WriteResult({ "nInserted" : 1 }) 
rs0:PRIMARY> db.user_test.person.find() 
{ "_id" : ObjectId("5ea797ebae86e88a86916091"), "title" : "Myblogpost", "content" : "Here's my blog post", "date" : ISODate("2020-04-28T02:41:35.673Z") } 


在其它SECONDARY库上查询验证: 
在172.16.1.251上面验证: 
rs0:SECONDARY> use user_test 
switched to db user_test 
rs0:SECONDARY> db.auth('user_test','user_test123') 

rs0:SECONDARY> db.user_test.person.find(); 
{ "_id" : ObjectId("5ea797ebae86e88a86916091"), "title" : "Myblogpost", "content" : "Here's my blog post", "date" : ISODate("2020-04-28T02:41:35.673Z") } 
rs0:SECONDARY> 
  
在172.16.1.252上面验证: 
rs0:SECONDARY> use user_test 
switched to db user_test 
rs0:SECONDARY> db.auth('user_test','user_test123') 

rs0:SECONDARY> db.user_test.person.find(); 
{ "_id" : ObjectId("5ea797ebae86e88a86916091"), "title" : "Myblogpost", "content" : "Here's my blog post", "date" : ISODate("2020-04-28T02:41:35.673Z") } 


 ========================================================================================= 
FAQ: 
使用mongodb时,出现“not master and slaveok=false”错误,原因是secondary不允许读写。 
因为系统中mongodb做了主备,主备切换了,也可能导致这个问题。 
问题说明:
首先这是正常的,因为SECONDARY是不允许读写的, 在写多读少的应用中,使用Replica Sets来实现读写分离。通过在连接时指定或者在主库指定slaveOk,由Secondary来分担读的压力,Primary只承担写操作。 
对于replica set 中的secondary 节点默认是不可读的, 
有两种方法实现从机的查询:
第一种方法:版db.getMongo().setSlaveOk();
第二种方法:rs.slaveOk();
但是这种方式有一个缺点就是,下次再通过mongo进入实例的时候,查询仍然会报错,为此可以通过下列方式
vi ~/.mongorc.js
增加一行rs.slaveOk();


echo "rs.slaveOk()">>/root/.mongorc.js


这样的话以后每次通过mongo命令进入都可以查权询了 


分割线
感谢打赏
江西数库信息技术有限公司
YWSOS.COM 平台代运维解决方案
 评论
 发表评论
姓   名:

Powered by AKCMS