多数据中心的主从结构
在MongoDB里有一个推荐的架构
不过整除来说,大部分公司没那么多资源部署,一个简化版本就是用两个数据中心,部署一主三从或两从。
我们公司本身业务规模比较大,对MongoDB的依赖也很严重,所以我们还部署了多数据中心的主从结构。有两个数据中心(可以同域,可以异地),其中一个数据中心,部署了一主一从,另外一个数据中心部署了两个从节点。万一一个数据中心崩溃了,另一个数据中心也还是可用的。
在主从选举的时候,我们也会倾向于选择和主节点在同一个数据中心的从节点,也就是图里面深黄色的从节点。因为正常来说,同一个数据中心内部的从节点,数据会比较新。
同时为了保证在主从选举的时候优先选择同一个数据中心的节点,我们还调整了从节点的优先级。
在整个主从结构都面完了之后,你进一步总结一下。
基本上目前主流的这种大型中间件,在提高可用性上用的方法无外乎就是分片和主从结构。除了 MongoDB,类似的还有 Redis、Elasticsearch、Kafka。
引入分片
分片既可以提高可用性,也可以提高性能。在MongoDB里,引入分片比关系型数据库简单很多,可以直接说在开发新业务的时候就启用了分片功能
随着业务的增长,后面使用MongoDB的时候,都要求开启分片功能,来进一步提高可用性的性能。
另一种思路是为已有的数据添加分片功能。
最后也要总结下
目前来说,支持大数据高并发的中间件基本上也有类似的分片功能。或者说,这一类的中间件明面上都是对等结构,而对等结构里面的每一个“节点”又是一个主从集群。就算是关系型数据库的分库分表,也可以看作是这种对等结构 + 主从结构的模式。
调整写入语义
写入语义的调整一般有两种思路,一是朝着可用性的角度调整,另一个是朝着性能的角度调整。
以可用性为例
最开始的时候,我们遇到过一个 Bug,就是数据写入到 MongoDB 之后,偶尔会出现数据丢失的问题。因为之前我在 Kafka 上也遇到过类似的问题,所以我就怀疑是不是写入语义没做好。然后我就去排查,果然有发现,在这个数据丢失的场景下,Write Concern 的 w 取值不是默认的 majority,而是 1,也就是说只需要主节点写入就可以。 很明显,在这种情况下,万一写入之后主节点崩溃了,那么从节点就算被提升成主节点,也没有这一条数据。所以,后面我就把这个改回了 majority。同时我还去排查了一个 j 参数,确认设置成了 true。这样一来,数据就不太可能丢失了。