有坑勿踩(一):MongoDB PSS vs PSA

前言

在技术社区混了这么长时间,由于一些常见的技术问题反复被问到,老是想写写文章把它们讲清楚。无奈不少时候看似基础的技术问题背后都隐藏着很深的缘由,想要一次性说清楚太花时间,而平时又没有不少时间能花在上面(主要是懒),因此产生了写一系列文章的想法,讲讲我或个人客户使用MongoDB过程当中常常遇到的各类“坑”。话虽如此,难者不会会者不难,但愿看了这些讲解你就再也不认为这些是“坑”了。code

在讲解这些问题前,我会假设读者已经对MongoDB有了最基础的了解,所以一些基本名词和概念就不作过多的解释,请本身查阅相关资料。资源

PSS vs PSA

什么是PSS/PSA?

在MongoDB复制集中,存在三种类型的角色:it

  • PRIMARY: 主节点(P)
  • SECONDARY: 从节点(S)
  • ARBITER: 仲裁节点(A)

构建一个复制集至少须要3个节点,因此用户就有了两种选择,即PSS和PSA。
注意:记住A的做用始终是把集群中具备投票权的节点总数凑成奇数用,防止“脑裂”。所以诸如PAA,PSSAA之类的配置是没有存在的意义的,极端状况下还会扰乱集群的正常工做。io

PSA有什么好处?

最直接的好处:省钱啊!随便找台机器,不消耗什么资源就能够运行一个A,比一个S的成本小多了。社区

PSA有什么问题?

读写失效

最直接的问题来自于MongoDB中的一个配置选项{w: "majority"},这个配置决定了一次成功的写入操做须要到达多少个节点才算真正的成功,w能够定义为1,2,...n(n<=集群节点总数)或majority。而majority是保证在集群故障时不丢失数据的必要配置(关于majorityw之后再专门写文章讨论)。其表明的意义是:集群中必须有大多数节点收到并确认了一个写操做,这个写操做才算成功。
在三个节点的集群中,{w: "majority"} == {w: 2}。所以若是集群配置是PSA,因为A是不存数据的,因此集群中可以确认写操做的节点只有P和S,恰好是2。到这里可能有人已经看出问题了:在PSA中若是有一个数据节点宕机,则不再能知足{w: "majority"},全部使用这种配置的写操做都会失败。所以能够说,PSA在必定程度上丢失了高可用性,由于任何一个数据节点的失效都会致使{w: "majority"}类型写入的失败。
引伸一下,ReadConcern一样有可选值majority,所以一样可能由于一个数据节点的失效而失效。集群

集群部分功能失效

可能你会以为:什么{w: "majority"}没据说过啊,我也不在意丢失数据,那用PSA是否是就没有问题了?固然不是!在不少你没注意到的场景都存在着{w: "majority"}。好比:基础

  1. 分片集群数据迁移。不管源或者目标片中不可以知足大多数时,迁移都会失败。
  2. 分片集群管理。包括但不限于如下这些操做实际上都隐含着{w: "majority"}。一旦不能知足,这些操做都会失败:配置

    1. db.dropDatabase()
    2. db.collection.drop()
    3. db.collection.dropIndex({...})
    4. sh.shardCollection(...)
    5. db.createUser(...)

结论

majority比你想象的更重要,PSA不可以提供足够的可用数据节点来保证majority,所以在不少场景下会引起隐藏的错误。在有可能的状况下,应尽可能使用PSS代替PSA。高可用

相关文章
相关标签/搜索