首先Mongo集群的安装和部署参考以前的文章:/2021/02/07101629-001-install.html

高可用方案

Mongodb一共有三种集群搭建的方式

1
2
3
Replica Set(副本集)# 推荐
Sharding(切片)
Master-Slaver(主从)# 目前已不推荐使用了

其中,Sharding集群也是三种集群中最复杂的。副本集比起主从可以实现故障转移!而主从不能故障转移,需要手工切换。目前已不推荐使用主从模式,取而代之的是副本集模式。副本集其实一种互为主从的关系,可理解为主主。

副本集指将数据复制,多份保存,不同服务器保存同一份数据,在出现故障时自动切换。对应的是数据冗余、备份、镜像、读写分离、高可用性等关键词;

而分片则指为处理大量数据,将数据分开存储,不同服务器保存不同的数据,它们的数据总和即为整个数据集。追求的是高性能。在生产环境中,通常是这两种技术结合使用,分片+副本集。

判断数据是否一致

可以用比较笨的办法,依次在主从数据中查询每个db的状态。

1
2
3
sdx:PRIMARY> show dbs
sdx:PRIMARY> use local
sdx:PRIMARY> db.stats()

主从热切换

有时候需要手动切换Mongo的主从服务器;对于高可用方案部署的mongo来说,这个操作很容易。

前面我们已经学习过动态调整Mongo集群中的节点。可以灵活的添加或者删除副本集节点和仲裁节点。集群中有两个以上副本集之后就可以随意切换主从了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 1. 检查节点的优先级
# 用下面的命令查看members中节点优先级,最好改成一样,否则手工设置主从之后,可能因为
# 优先级的缘故,节点主从自动发生变化。
rs.config()
# 设置优先权的命令
1)PRIMARY> config=rs.conf()
2)PRIMARY> config.members[3].priority = 1
3)PRIMARY> rs.reconfig(config)

# 2. 将Primary节点降级为Secondary节点
# 默认维持60s,如果这段时间内没有新的primary被选举出来,这个节点可以要求重新进行选举。
PRIMARY> rs.stepDown()
PRIMARY> rs.stepDown(120)

备份还原数据

由于我们在三台实例的配置过程中,没有人为指定主从的服务器,因此一旦主不通之后,从和仲裁服务器很快会选举现在的从变成主。而以前的主在启动以后自动会变成从。其实这个过程中存在数据没有完全同步而丢失数据的可能。

分享一些操作技巧:

1
2
3
4
5
6
# 可以在主节点删除和加入其它节点
PRIMARY> rs.add("127.0.0.1:27018");     # 添加节点
PRIMARY> rs.remove("127.0.0.1:27018");  # 删除节
PRIMARY> rs.addArb("127.0.0.2:27018");  # 添加仲裁者节点

# mongo3.2.x 版本的 data 目录无法在 4.4.x或更高版本下直接启动,版本相差太大,会提示错误

版本升级变化过大的情况下,稳妥的办法还是导出数据在新实例上还原。

详细可以参考:https://www.cnblogs.com/operationhome/p/10724374.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 备份数据
mongodump -h x.x.x.x --port 10000 -u dbuser -p passwd -d mydb -o /dir/dumpmydb
# 如果只备份指定的表加 -c TableName
mongodump -h ip --port x -u dbuser -p passwd -d mydb -c table -o ./mytables
# 好像不能同时指定多张表,可以每张表写一条语句,依次备份

# 还原数据
mongorestore -h x.x.x.x --port=45301 -uadmin -pxxx /dir/dumpmydb
# 还原时候可以变更库,加参数
--nsFrom='mydb.*' --nsTo='newdb.*'

# 还原的时候用 超级管理员用户还原,然后在数据库上重新加入用户。
db.createUser({user:"mydbuser", pwd:"xxx", roles: [{ role: "readWrite", db: "mydb" }]});

几组导出导入工具

  • mongoexport/mongoimport :导入/导出的是JSON格式或者CSV格式
  • mongodump/mongorestore :导入/导出的是BSON格式
  • bsondump:将 bson 格式的文件转储为 json 格式的数据

两组命令的区别

  1. JSON可读性强但体积较大,BSON则是二进制文件,体积小但几乎没有可读性。
  2. 在一些mongodb版本之间,BSON格式可能会随版本不同而有所不同,所以不同版本之间用mongodump/mongorestore可能不会成功,具体要看版本之间的兼容性。
  3. 当无法使用BSON进行跨版本的数据迁移的时候,使用JSON格式即mongoexport/mongoimport是一个可选项。JSON虽然具有较好的跨版本通用性,但其只保留了数据部分,不保留索引,账户等其他基础信息。
  4. mongodump/mongorestore 支持库和集合级别的操作,mongoexport/mongoimport 只支持集合级别操作。
  5. mongodump 导出文件包含索引页。mongoexport 导出文件不包含索引页。

更多备份还原参考:

https://blog.51cto.com/wujianwei/2464417

https://www.cndba.cn/dave/article/107972

错误1:打开文件数太多

[conn136921] cannot open /dev/urandom Too many open files
[conn136921] Fatal Assertion 28839
[conn136920] cannot open /dev/urandom Too many open files
[conn136920] Fatal Assertion 28839

遇到这种情况可以用下面的命令查看:

1
2
3
ps aux|grep mongo        # 查看进程ID,目前MongoDB的pid进程号是4842
cat /proc/4842/limits    # 查看4842进程号的相关的ulimit的信息, 可以加 | grep files
ll /proc/4842/fd | wc -l # 查看4842进程打开了多少文件

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

安装 Mongo的时候要保证下面的参数设置:

 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

以上设置都是需要重启服务器的,下面这种方法可以热设置,但是重启服务器会失效,建议两种设置同时做。

1
2
prlimit --pid 4842 --nofile=1048576:1048576 # 修改命令
cat /proc/4842/limits  |grep files # 查看是否生效

更多参考:

https://www.pianshen.com/article/14371909869/

(完)