首页 > 数据库 >【后端面试题】【中间件】【NoSQL】MongoDB提高可用性的方案(主从结构、仲裁节点、分片、写入语义)

【后端面试题】【中间件】【NoSQL】MongoDB提高可用性的方案(主从结构、仲裁节点、分片、写入语义)

时间:2024-07-07 19:28:51浏览次数:30  
标签:面试题 NoSQL MongoDB 可用性 中间件 数据中心 主从 分片 节点

主从结构

MongoDB的高可用和别的中间件的高可用方案基本类似。比如在MySQL里,接触了分库分表和主从同步;在Redis里,Redis也有主从结构;在Kafka里,分区也是有主从结构的。
所以先介绍启用了主从同步

我们的系统有一个关键组件 - MongoDB,但是在最开始的时候,MongoDB没有启用主从,是一个单节点的。因此每年总会有一两次,MongoDB崩溃不可用。所以我把MongoDB改成了主从同步,最开始的时候业务量不多,为了节省成本,我们用了推荐的配置一主两从。这种改变的好处是:当主节点崩溃后,从节点可以选举出一个新的主节点。

直接说用了几个主从节点,如果问到主从同步的话,回答oplog的内容。

引入仲裁节点

另一种思路是引入仲裁节点,所谓仲裁节点是指这个节点参与主从集群的主节点选举,但是只参与投票,类似于Elasticsearch里的仅投票节点
这种机制在别的中间件也见过了,这类节点的好处在于它们只参与投票,也就是只关心主从选举,所以只需要很少的资源就可以运行起来
在这里插入图片描述

最开始的时候,我们只是部署了一主两从,两个从节点都会同步数据。后面为了进一步提高可用性,引入了仲裁节点。这些仲裁节点被部署在轻量级的服务器上,成本非常低。在引入了这些仲裁节点后,就算有一个从节点崩溃了,整个集群也基本没什么影响,因为这个时候还是有足够的节点可以投票

启用主从模式的配置服务器

我们MongoDB最开始部署的时候,配置服务器并没有启用主从模式,毕竟当时想节省资源。但是后面发现,配置服务器这个对集群的影响太大了,一旦不可用,整个集群就基本不可用了。这种情况下,我们只好引入了主从结构的配置服务器。目前配置服务器本身就有一主两从。

在这里插入图片描述

虽然主节点还是存在崩溃的可能,但是在主节点崩溃之后会有主从选举。更加重要的是,在主节点崩溃之后,整个配置服务集群还是可读的。而我们也知道,在一个 MongoDB 集群里面,元数据也是读多写少的。两者一结合,整个 MongoDB 集群的可用性就提高了。

多数据中心的主从结构

在MongoDB里有一个推荐的架构
在这里插入图片描述
不过整除来说,大部分公司没那么多资源部署,一个简化版本就是用两个数据中心,部署一主三从或两从。

我们公司本身业务规模比较大,对MongoDB的依赖也很严重,所以我们还部署了多数据中心的主从结构。有两个数据中心(可以同域,可以异地),其中一个数据中心,部署了一主一从,另外一个数据中心部署了两个从节点。万一一个数据中心崩溃了,另一个数据中心也还是可用的。

在这里插入图片描述
在主从选举的时候,我们也会倾向于选择和主节点在同一个数据中心的从节点,也就是图里面深黄色的从节点。因为正常来说,同一个数据中心内部的从节点,数据会比较新

同时为了保证在主从选举的时候优先选择同一个数据中心的节点,我们还调整了从节点的优先级。

在整个主从结构都面完了之后,你进一步总结一下。

基本上目前主流的这种大型中间件,在提高可用性上用的方法无外乎就是分片和主从结构。除了 MongoDB,类似的还有 Redis、Elasticsearch、Kafka。

引入分片

分片既可以提高可用性,也可以提高性能。在MongoDB里,引入分片比关系型数据库简单很多,可以直接说在开发新业务的时候就启用了分片功能

随着业务的增长,后面使用MongoDB的时候,都要求开启分片功能,来进一步提高可用性的性能。

另一种思路是为已有的数据添加分片功能。
最后也要总结下

目前来说,支持大数据高并发的中间件基本上也有类似的分片功能。或者说,这一类的中间件明面上都是对等结构,而对等结构里面的每一个“节点”又是一个主从集群。就算是关系型数据库的分库分表,也可以看作是这种对等结构 + 主从结构的模式。

在这里插入图片描述

调整写入语义

写入语义的调整一般有两种思路,一是朝着可用性的角度调整,另一个是朝着性能的角度调整。

以可用性为例

最开始的时候,我们遇到过一个 Bug,就是数据写入到 MongoDB 之后,偶尔会出现数据丢失的问题。因为之前我在 Kafka 上也遇到过类似的问题,所以我就怀疑是不是写入语义没做好。然后我就去排查,果然有发现,在这个数据丢失的场景下,Write Concern 的 w 取值不是默认的 majority,而是 1,也就是说只需要主节点写入就可以。 很明显,在这种情况下,万一写入之后主节点崩溃了,那么从节点就算被提升成主节点,也没有这一条数据。所以,后面我就把这个改回了 majority。同时我还去排查了一个 j 参数,确认设置成了 true。这样一来,数据就不太可能丢失了。

标签:面试题,NoSQL,MongoDB,可用性,中间件,数据中心,主从,分片,节点
From: https://blog.csdn.net/LightOfNight/article/details/140161363

相关文章

  • 【大模型LLM面试合集】大语言模型基础_NLP面试题
    NLP面试题1.BERT1.1基础知识BERT(BidirectionalEncoderRepresentationsfromTransformers)是谷歌提出,作为一个Word2Vec的替代者,其在NLP领域的11个方向大幅刷新了精度,可以说是近年来自残差网络最优突破性的一项技术了。论文的主要特点以下几点:使用了双向Transformer作......
  • Apache Drill 2万字面试题及参考答案
    目录什么是ApacheDrill?ApacheDrill的主要特点是什么?ApacheDrill如何实现对复杂数据的查询?描述ApacheDrill的数据存储模型。为什么ApacheDrill被称为自服务的SQL查询引擎?ApacheDrill支持哪些类型的数据源?解释ApacheDrill中的“schemadiscovery”功能。如何在Apa......
  • Java面试之并发与网络通信常见面试题
    并发编程部分1.什么是进程和线程?进程:操作系统分配资源的最小单位,各个进程之间占据独立的寻址空间,运行也是独立运行,进程间通信需要一些机制。线程:程序执行的基本单位,一个进程可以开启多个线程,他们的很多空间(如堆空间)是公用的。线程执行开销小,但是不够安全。2.线程有几......
  • Android面试题自定义View之Window、ViewRootImpl和View的三大流程
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点View的三大流程指的是measure(测量)、layout(布局)、draw(绘制)。下面我们来分别看看这三大流程View的measure(测量)MeasureSpecMeasureSpec是View的一个内部静......
  • 代码随想录算法训练营第四天 | 24. 两两交换链表中的节点 、 19.删除链表的倒数第N个
    24.两两交换链表中的节点 题目:.-力扣(LeetCode)思路:这题关键是要每次进行两个结点的操作,并且每次都要保存其前结点,做题思路比较清晰,但是总是处理不好边界问题,总是越界。代码:/***Definitionforsingly-linkedlist.*structListNode{*intval;*List......
  • 代码随想录刷题day 4 | 两两交换链表中的节点 19.删除链表的倒数第N个节点 面试题
    24.两两交换链表中的节点迭代的版本:最重要的就是要知道循环变量怎么取,对于这道题,我们只需要存储需要交换的两个节点的前一个节点即可,只有当这个节点后面有两个节点时才进入循环,其实把握住这一点之后这题就非常容易了。递归的版本:这道题用递归做简直不要太简单,首先明白递归结束......
  • Linux常用面试题
    系统部分1、在linux系统中,获取命令帮助的方法有哪些?   man(查看手册页)    help(查看内部命令)   --help(查看外部命令)2、列举find命令的用法?(主要说明使用的选项及其含义)   find查找文件或目录      -name   根据目标的名称进程查找,允许使......
  • Linux系统管理面试题
    中级系统管理面试题训练内容:1)编译安装源代码的过程?      从官方网站下载源码包校验md5值   解压   tar命令解包      配置   进入解压目录配置,指定对应的模块、解包的路径   编译   源代码编译成二进制文件      安装 ......
  • Java面试题系列 - 第4天
    题目:深入理解Java泛型与类型擦除背景说明:Java泛型是JavaSE5引入的一种新特性,它允许在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。然而,Java泛型的实现背后有一个重要的概念——类型擦除,理解这一点对于深入掌握泛型编程至关重要。问题要求:解......
  • ZeroMQ最全面试题解读(3万字长文)
    目录解释ZeroMQ是什么,它的主要用途是什么?ZeroMQ支持哪些通信模式?描述一下ZeroMQ中的“消息”和“消息帧”如何在C++中初始化一个ZeroMQ上下文?在ZeroMQ中,如何创建一个套接字并将其绑定到特定端口?解释什么是“管道模式”(PipePattern)说明如何使用ZeroMQ进行点对点通信Zer......