这里主要介绍MongoDB在Linux服务器上的安装配置。

下载安装

第一种方法

到官方网站找到对应平台的下载安装包:https://www.mongodb.com/try/download/community

1
2
3
4
5
6
7
8
rpm -ivh mongodb-org-server-4.4.3-1.suse12.x86_64.rpm
mongod --version

# 注意,可能需要安装openssl低版本
zypper in openssl-1_0_0
# 否则可能报下面的错误
libcrypto.so.1.0.0()(64bit) is needed by mongodb-org-server-4.4.6-1.suse12.x86_64
libssl.so.1.0.0()(64bit) is needed by mongodb-org-server-4.4.6-1.suse12.x86_64

一般安装完之后会提示你用systemctl也能管理服务。我们这里暂时禁用此功能。

1
2
systemctl status mongod.service 
systemctl disable mongod.service

第二种方法

上面的方式只安装 Server,没有Shell命令,可以从下面的地方下载Mongo之后直接解压得到可执行文件,直接用这些命令即可。

https://www.mongodb.org/dl/linux

详细过程参考:https://www.cnblogs.com/pfnie/articles/6759105.html

注意事项

内核打开文件数限制

**一般服务器默认open files过小,生产系统极容易达到上线导致Mongo崩溃。切记!!!**请做好下面的配置。

MongoDB的工作原理是一个集合一个文件,一个索引一个文件。所以一共有多少集合,至少就会有集合数量x2个打开文件(以1集合文件+1索引文件计算)被占用。再考虑到网络连接数量,要保证足够大的open files值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 1. 查看系统总共最大打开文件数
cat /proc/sys/fs/file-max
# 上面的值太小就修改下面的配置文件,然后执行 sysctl -p
# vi /etc/sysctl.conf
fs.file-max = 6553560

# 2. 像装Oracle一样,单数设置mongo的文件句柄打开数量
# vi /etc/security/limits.conf 比如下面的配置
* soft nofile 1048576
* hard nofile 1048576
mongod soft nofile 1048576
mongod soft nproc 1048576
#  * 代表针对所有用户,noproc 是代表最大进程数,nofile 是代表最大文件打开数,
# "mongod soft nofile 1048576" 简单点理解就是mongod用户能打开的最大文件数量是 1048576

工具包

4.4版本之后安装包中不含有一些实用工具了,需要自己下载解压放到安装目录。

https://www.mongodb.com/try/download/database-tools

高可用

MongoDB集群有三种模式,主从模式,副本集模式、sharding分片模式。主从模式官网也不再推荐上生产环境,主要是安全性太低。副本集和sharding模式目前是用的最广的方案,通常这2种方案的选择通过数据量和并发数来权衡。在GB级别的基本上副本集方案可满足,TB级别或以上采用sharding模式,解决单机容量和单机并发能力。这两种既有自己的优势也有自己的缺点,比如sharding模式分片越多,性能自然下降越多。

MongoDB可以很容易集群部署,实现数据库的高可用方案。和其它数据库高可用法案类似,都是通过复制日志的方式实现。

这里我们主要讲最常见的副本集模式。先看看下面的关系图:

image-20210207142456961

MongoDB的复制集

MongoDB的复制集由至少一主两从构成,集群节点之间依靠监控投票机制(Raft)进行高可用。如果主库宕机,复制集群内部会进行投票选举出一个新的主库替代原主库,同时复制集群会告知客户端主库发生切换,类似Redis的哨兵。各节点之间的数据依靠oplog来实现数据同步,oplog类似于binlog,但是它存在于一张表里。

Mongodb复制集由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点。Mongodb Driver(客户端)的所有数据都写入Primary,Secondary从Primary同步写入的数据,以保持复制集内所有成员存储相同的数据集,实现数据的高可用。

这种方案作用:

  • 数据冗余,用做故障恢复使用,当发生硬件故障或者其它原因造成的宕机时,可以使用副本进行恢复。
  • 读写分离,读的请求分流到副本上,减轻主节点的读压力。

角色介绍

主节点(Primary)

接收所有的写请求,然后把修改同步到所有Secondary。一个Replica Set只能有一个Primary节点,当Primary挂掉后,其他Secondary或者Arbiter节点会重新选举出来一个主节点。 默认读请求也是发到Primary节点处理的,可以通过修改客户端连接配置以支持读取Secondary节点。

副本节点(Secondary)

与主节点保持同样的数据集。当主节点挂掉的时候,参与选主。

仲裁者(Arbiter)

不保有数据,不参与选主,只进行选主投票。使用Arbiter可以减轻数据存储的硬件需求,Arbiter几乎没什么大的硬件资源需求,但重要的一点是,在生产环境下它和其他数据节点不要部署在同一台机器上。

注意:

在PSS典型架构中(Replica Set)节点数必须为奇数,目的是选主投票的时候要出现大多数才能进行选主决策。在PSA架构中,需要偶数个数据节点,加一个Arbiter构成的Replica Set

副本集相关知识参考:

https://blog.csdn.net/u011134399/article/details/131270334

配置部署

我们在同一台物理机部署三个不同的节点来试验MongoDB的高可用方案部署;用到三个端口45301、45302、45303来配置;下面给出其中一个配置,其它两个改相应的目录和端口就好了:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# where to write logging data.
systemLog:
  destination: file
  logAppend: true
  path: /home/mqs/mongo_tst/45301/mongod.log

# Where and how to store data.
storage:
  dbPath: /home/mqs/mongo_tst/45301/data
  journal:
    enabled: true
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 2 # 限制内存占用GB

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

# network interfaces
net:
  port: 45301
  bindIp: 10.10.200.142
  maxIncomingConnections: 20000
  
replication:
  # binlog size
  oplogSizeMB: 1024
  # replication name
  replSetName: sdx

#security:
#  authorization: enabled
#  keyFile: /home/mqs/mongo_tst/45301/conf/keyfile
#  clusterAuthMode: keyFile

警告:上面的 security段在首次配置集群的时候一定不能打开,否则需要登录操作,很麻烦。当集群建立之后再打开这个配置重启所有的Mongo实例。

依靠上面的三个配置文件分别启动三个MongoDB进程:

sudo /usr/local/mongodb/bin/mongod -f mongodb.conf

启动成功之后找一个端口作为主数据库,进入控制台进行设置:

/usr/local/mongodb/bin/mongo 10.10.200.142:45301

在控制台下面设置下面复制集的配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
config = {
  _id: "sdx", 
  members: [
    {_id: 0, host: "ip:port"},
    {_id: 1, host: "ip:port"},
    {_id: 2, host: "ip:port", "arbiterOnly": true},
  ]
}

# 或者指定主从优先级
config = {
  _id: "sdx", 
  members: [
    {_id: 0, host: "ip:port", "priority": 1},
    {_id: 1, host: "ip:port", "priority": 1},
    {_id: 2, host: "ip:port", "arbiterOnly": true},
  ],
  settings: {
    "heartbeatTimeoutSecs" : 30,
    "electionTimeoutMillis" : 30000,
  }
}
# priority 的值越大,当主的优先级越高。只要优先级高的节点加入副本集,就自动夺主权限。
# arbiter 节点 priority 默认为0,没有数据,不参与选主。

# 或者只有单节点
config = {
  _id: "sdx", 
  members : [
    {_id: 0, host: "ip:port"},
  ]
}

用这个配置执行初始化:

1
2
3
4
5
6
# 这个配置一定要在集群所有节点运行起来之后执行,否则可能卡死
rs.initiate(config)

# 添加超级用户。一定要添加这个用户,否则后面启动登录认证了,你无法进入mongo管理
use admin
db.createUser({user:"admin",pwd:"xxx",roles: [{ role: "root", db: "admin" }]});

或者线上数据库用下面方法修改配置:

1
2
3
4
1)PRIMARY> cf=rs.conf()
2)PRIMARY> cf.settings.heartbeatTimeoutSecs = 30
3)PRIMARY> cf.settings.electionTimeoutMillis = 30000
4)PRIMARY> rs.reconfig(cf)

下面可以查看各种状态了:

1
2
3
4
5
6
7
# 查看状态
rs.status()
rs.config()
rs.isMaster()

# 查看复制状态
rs.printReplicationInfo()

从库读写可能会报错,主要是没有权限,需要给从库启用读权限:

1
2
sdx:SECONDARY> rs.slaveOk()
sdx:SECONDARY> rs.secondaryOk() # 新命令

安全认证

数据库一般配置在内网环境中,集群之间的通信是没有安全认证的,为了提高安全等级我们启用集群间访问的安全证书。

采用keyfile方式进行安全认证,用下面这条命令生成安全认证文件,然后在三份配置文件中分别引用这个文件:

openssl rand -base64 765 > keyfile

把配置文件中的下面几行注释打开,之后分别重启三个mongo进程。

security:
  authorization: enabled
  keyFile: /home/mqs/mongo_tst/45301/conf/keyfile
  clusterAuthMode: keyFile

注意:必须给三个keyfile文件设置权限chmod 600 keyfile ,否则会报keyfile are too open错误。

添加删除节点

第一种方法是重新加载新的配置文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 登录root用户,必须先用 use admin	
PRIMARY> use admin
PRIMARY> db.auth('root','passwd')

# 注意这里需要写完整的配置,这里是啥配置,
PRIMARY> config = {
  _id: "sdx", 
  members : [
    {_id: 0, host: "10.10.200.142:45301"},
    {_id: 2, host: "10.10.200.142:45303", "arbiterOnly": true},
  ]
}
PRIMARY> rs.reconfig(config)

像上面修改配置文件,无论是加新节点配置或者删除某个以前存在的节点配置,在重新加载配置文件之后,就会自动生效。

第二种方法是用控制台命令行用函数调用:

1
2
3
PRIMARY> rs.add("127.0.0.1:27018");     # 添加节点
PRIMARY> rs.remove("127.0.0.1:27018");  # 删除节
PRIMARY> rs.addArb("127.0.0.2:27018");  # 添加仲裁者节点

注意:加入的新节点如果以前留存有数据,可能会报错甚至mongo进程挂掉。需要删除data目录下的所有文件,重新启动mongo即可。

节点状态

MongoDB一共有10种状态,官方将其分为3大类,核心状态(Core States)为三种成员类型对应的属性(PRIMARY/SECONDARY/ARBITER),还有7种属性,被分为其他状态(Other States)和错误状态(Error States)两类。

按照时间序,其他状态分别为STARTUP、STARTUP2和RECOVERING。每个复制集成员在mongod启动后,都先进入STARTUP状态,然后加载成员的复制集配置,之后进入到STARTUP2状态。如果该成员需要进行初始同步(initial sync),那么它将长期处于该状态,知道同步完所有的数据和索引。随后进入到RECOVERING状态,处于该状态的成员不能接受客户端的读请求,也不能被选举为Primary,但可以进行投票选举。

image-20210715162457564

(完)