MongoDB 4.x——高可靠

1、节点部署优化

务必记住一点,单机模式的MongoDB实例无法保证高可用,生产环境中应该使用副本集模式或分片副本集模式的集群。对于每个MongoDB实例节点的部署,可以遵循一些最佳实践来提升性能及稳定性。

1.1、硬件规划

1.1.1、保证足够的内存

MongoDB在工作集小于可用内存时性能表现最好。对提升高实时业务的读写性能而言,足够的内存往往是最重要的因素。在内存不足的情况下,其他优化一般所能产生的效果是有限的。如果工作集超过了单一服务器的内存,则可以考虑通过分片实现水平扩展。

最好的做法是提前规划工作集的大小,在运行期间可以执行serverStatus命令,通过检查WiredTiger缓存的淘汰频率来评估缓存大小是否足够。

1.1.2、使用SSD硬盘

对于以写入为主的应用建议使用固态硬盘(SSD)来保存数据和日志。MongoDB在大多数情况下会使用随机I/O操作,因而固态硬盘可以显著提高写入密集型应用的性能。在磁盘系统中,数据的读取主要由寻道时间决定。对于机械磁盘而言,寻道时间约为5ms,而固态硬盘的寻道时间则约为0.1ms,比机械磁盘快了大概50倍。

对于副本集成员中的数据节点,应保持一致的配置。一种常见的问题是为备节点配置了较主节点更低性能的磁盘,导致主备节点的oplog差异过大,增加了复制窗口断裂的风险。对于使用WriteConcern:majority的写入,则会严重影响性能。

1.1.3、使用RAID10

RAID(独立磁盘冗余阵列)是一种提高磁盘可靠性和性能的技术,在所有的配置方式中,推荐使用RAID10。RAID10兼备了RAID0和RAID1的优点,在提供并行写入的同时也通过镜像提高了可靠性。建议在MongoDB的数据和日志存储中使用RAID10磁盘阵列。

1.1.4、保证网络质量

在没有其他因素的干扰下,网络吞吐量与MongoDB的吞吐量是成正比的。应用上必须保证MongoDB集群内部、业务服务到MongoDB集群的网络带宽是充足的。这包括:

  • 保证MongoDB集群内部以及应用侧与mongos之间能达到较高的网络吞吐量(每秒千兆以上)​。
  • 保证MongoDB集群内部以及应用侧与mongos之间有较低的网络延迟(小于100毫秒)​。

1.2、系统调优

1.2.1、选择合适的文件系统

在Linux系统中,必须使用EXT4或者XFS文件系统作为数据和日志的存储卷。不推荐EXT3文件系统,MongoDB会定期进行文件的预分配操作,如果选用了EXT3文件系统,那么这些操作会造成一些难以接受的卡顿。而在EXT4和XFS文件系统中,预分配将只会影响元数据层的修改,这比EXT3的预分配方式要高效很多。

1.2.2、关闭NUMA

众所周知,基于NUMA的非一致性内存架构不适合数据库的场景。NUMA适用于多核架构下高速访问少量缓存数据的场景,但MongoDB倾向于访问更多的数据,如果启用NUMA,则可能会导致CPU本地缓存大量的溢出和置换,会大大降低性能。

可以在执行MongoDB相关命令前加上numactl–interleave=all,以关闭NUMA功能。参考下面的命令:

numactl --interleave=all /opt/mongodb/bin/mongod -f
/opt/mongodb/conf/mongo.conf
1.2.3、关闭磁盘预读(readahead)

对于WiredTiger存储引擎,建议禁用磁盘预读(readahead设置为0)​。

为了进一步减少真实的I/O操作次数,磁盘每次都会进行预读,即读取数据的同时按顺序向后读取一定长度的数据并置入内存。磁盘预读的前提是大部分数据是连续读取的,例如对视频文件读取一部分之后,一定会读取后面的数据段。然而在大多数场景中,MongoDB会随机访问磁盘,因此,预读对性能的提升帮助有限,反而会产生一些无效的内存占用。

通过下面的命令查看磁盘预读配置:
在这里插入图片描述
执行如下命令修改预读:
在这里插入图片描述

1.2.4、关闭透明大页

由于数据库对内存的访问一般都是随机访问,而不是连续访问。透明大页(Transparent Huge Pages, THP)在随机访问模式上反而制约了MongoDB的性能。因此建议在Linux系统中关闭THP特性。

为MongoDB所在服务器关闭THP,可以在/etc/rc.local中添加如下命令:
在这里插入图片描述
检查THP是否已经关闭,代码如下:
在这里插入图片描述
不同的Linux版本所在配置文件可能不同,可视情况而定。

1.2.5、关闭atime选项

文件系统默认会记录每个文件的访问时间,由于MongoDB可能会频繁访问数据文件,将访问时间记录禁用可以获得一些性能提升。在Linux系统中挂载数据分区时使用noatime选项,代码如下:
在这里插入图片描述

1.2.6、修改资源限制

MongoDB会视情况动态创建连接,在默认的网络I/O模型中,每个连接会使用一个线程,同时包含一个文件描述符句柄。为了避免产生限制,建议将这些参数设置得大一些。

编辑/etc/sysctl.conf文件,设置内核参数,代码如下:
在这里插入图片描述
保存内核参数设置,代码如下:
在这里插入图片描述
设置ulimit,代码如下:
在这里插入图片描述

1.3、数据库配置

1.3.1、启用Journal日志

无论何种情况,都建议启用Jounal日志功能。MongoDB采用了缓冲延迟刷盘的机制,写入数据存在最高60s丢失的风险。Journal日志功能提供断电保护,可将损失风险降低到100ms以内。

检查MongoDB配置文件,确认开启Jounal日志功能,代码如下:

在这里插入图片描述

1.3.2、日志和数据分离

建议将MongoDB运行日志、Journal预写日志、数据文件存放到不同的磁盘,有利于提升整体I/O的吞吐量。

此外,可以开启directoryPerDB将不同数据库的数据文件使用单独的目录挂载。配置文件示例如下:
在这里插入图片描述
在这里插入图片描述
如上述配置,就可以将/data/mongodb、/data/mongodb/log、/data/mongodb/journal单独挂载。

1.3.3、保持时钟同步

务必让集群各节点保持时钟同步,最好延迟不要超过1s。MongoDB对时钟偏移做了一些兼容,但分布式节点之间的时钟延迟仍然可能产生一些未知的影响。此外,要谨慎发生时间跳变的情况,在MongoDB 3.4版本中,副本集节点在时间跳变时会导致主备节点切换。oplog使用本地时间和计数器来生成optime,一些异常的时钟跳变会增加计数器溢出的风险。

在Linux系统中建议使用NTP服务来保持节点间的时钟同步。

1.3.4、连接数限制

对MongoDB来说,太高的并发连接会造成服务器被大量的资源所占用。

  • 每个连接需要占用一个文件句柄,同时还包括TCP协议栈的独立读写缓冲区。
  • 默认情况下,MongoDB为每个连接分配一个线程,默认的线程栈最大为1MB的空间。

当存在大量的并发连接时,会导致MongoDB产生很高的内存压力,上下文切换的开销变大。此时性能下降明显。应用上应该规划合理的连接池分布,避免产生过高的连接数。除此之外,还应该尽量避免使用短连接,一些应用处理产生的Bug很容易产生连接泄露问题。

在MongoDB服务器端,通过配置net.maxIncomingConnections来限制最高的并发连接数,这个值建议不大于1万。在客户端方面,驱动默认为每个远程主机连接设置100的连接数上限,应用可适当进行调整,结合自身的吞吐量、请求时延以及具体的部署拓扑综合考量。

2、集群高可靠

对于集群模式的部署,保持资源隔离是颇为重要的一个原则。无论是计算,还是存储,一旦多个节点使用了共享资源,则必然会大幅度增加故障的隐患。

2.1、反亲和部署

如果产品使用了自建MongoDB集群的部署模式,则需要仔细审视集群节点是否满足反亲和的要求。对于同一个副本集内的不同节点,应保证其所在虚拟机位于不同的物理机上。一旦物理机发生电源、网络等故障,其他成员仍然可以工作,如图所示。

在这里插入图片描述

2.2、避免集中存储

虚拟化环境中另一个常见的做法是使用存储池(RAID)技术,对MongoDB副本集来说,将多个节点对接到同一个存储池是存在风险的,如图所示。
在这里插入图片描述

如果条件允许,则应该将各个副本集成员分离到不同的存储池上,对于分片集群,可以考虑如图所示的部署。

在这里插入图片描述
利用图中的部署方式,假设某个存储池发生故障,所有分片仍然可以保持可用。

2.3、警惕资源超分

超分是一种提升资源利用效率的手段,宿主机(物理机)通常可以分配比实际情况更大的CPU、内存。但资源超分的合理性有一个前提,那就是客户机在正常情况下都不会处于高负荷的状态。Ballooning技术可以让客户机(虚拟机)在运行时动态地调整内存资源;然而这对MongoDB十分不利,WiredTiger更适合独占式内存,在物理内存变得紧张的情况下可能会出现意外。另外,CPU超分同样会导致计算资源抢占,在一些负载较重的生产环境中,资源超分情况往往会让MongoDB数据库表现失常。

3、应用层高可靠

分布式环境带来了诸多的不确定性,因而有必要在应用层面考虑实现高可用。业务上对MongoDB的读写操作需满足如下目的。

  • 故障隔离,部分业务产生的故障不应该级联影响其他业务。
  • 可恢复性,对于局部性故障可自动实现转移,或者业务在产生一些异常抖动时可以通过重试的手段进行恢复。

3.1、故障隔离

  1. 连接池分离。通常,单个应用(微服务)内部可能只会使用一个连接池(MongoClient)进行读写。在业务场景错综复杂时,使用同一个连接池难以保证各业务彼此不受影响。例如,某个订单服务同时提供了快速下单、批量查询历史日志功能,对于前者通常需要实时响应(如响应时延在20ms)​,而后者则允许有一定的时延。如果仅使用一个连接池,则很容易出现连接抢占的情况。MongoClient为每个获取连接的线程提供了排队机制(waitQueueSize)​,默认的队列大小为连接池的5倍。持续增加的日志查询类请求会抢占连接,此时会导致大量下单请求线程进入阻塞队列,队列一旦溢出,就可能出现拒绝服务的问题。在有限的条件下,考虑在应用内部为不同业务启用单独的连接池,可以降低这类风险,如图所示。
    在这里插入图片描述
  2. 主分片分离。在分片集群中,对每一个启用分片功能的数据库都会指定一个唯一的主分片,此时所有非分片集群都存储在主分片中。生产环境中的主分片通常承担了更大的压力(并非所有集合都启用了分片机制)​。如果集群中存在多个逻辑库(按微服务划分)​,则应尽可能将不同逻辑库的主分片分散到不同分片上,如图所示。

在这里插入图片描述

  1. 标签(tag)分离。考虑按业务划分不同的标签,将不同的业务数据存储到不同分片区域中,如图所示。
    在这里插入图片描述

  2. 集群分离。对不同的业务使用单独的MongoDB集群,如图所示。

在这里插入图片描述

3.2、故障转移/恢复

  1. 服务实例同时接入多个mongos,避免单点故障。MongoClient会定时向多个mongos主机发送心跳以探测对端是否存活。如果某个mongos出现故障,则MongoClient会自动屏蔽故障节点以避免业务受损,如图所示。
    在这里插入图片描述
    应用服务实例同时连接多个mongos,同时也有利于实现mongos之间的负载平衡。

  2. 实现重试。数据库节点故障、网络异常或是主备节点切换行为都可能导致业务出现失败。为了应对一些临时性的失效,MongoDB Java Driver提供了可重试的读写能力来降低影响(MongoDB 3.6版本提供可重试写,MongoDB 4.2版本支持可重试读)​。在最新的版本中,可重试的读写行为是默认的,但当前的实现仅支持一次重试。对于一些关键性业务,可以自行实现重试逻辑(或使用spring-retry框架)​。

4、备份可靠性

毫无疑问,数据备份是非常重要的一个环节。随时持有可用的备份数据,可以在发生不可逆故障时降低业务的损失。对于部署在生产环境中的数据库集群,我们通常需要定期进行数据备份。

MongoDB实现备份的方式包含如下几种。

  • 使用mongodump/mongorestore进行逻辑备份、恢复。
  • 使用文件系统复制、LVM(logical volumemanager,逻辑卷管理)快照等方式进行物理备份。
  • 使用mongodump/mongorestore进行逻辑备份、恢复。
  • 使用文件系统复制、LVM(logical volumemanager,逻辑卷管理)快照等方式进行物理备份。
  • 使用管理工具进行数据备份管理。

4.1、逻辑备份

在MongoDB安装软件中附带了mongodump、mongorestore,因此不需要单独获取。

4.1.1、mongodump命令

mongodump命令可以将数据库文档导出为BSON格式,除了支持库级、表级备份,还可以指定查询条件过滤不需要的数据。BSON格式的文件可以在任意结构的MongoDB集群中进行恢复,甚至是不同的版本。

执行下面的命令,对本机的数据库进行dump备份:

mongodump --port 27017 -o backup

该命令会将除local外的所有数据库导出到backup目录下,每个集合对应一个BSON文件。通常mongodump命令导出的数据要少一些,因为该命令不会导出索引数据,导出结果中只会包含索引的定义文件(JSON)​。在通过mongorestore进行恢复数据时会自动重建索引。

备份指定的表,可以使用-c参数,代码如下:

mongodump --port 27017 --db appdb -c T_TEST_DATA -o backup

这样在输出结果中,所有集合都会对应一个.gz后缀的压缩后的文件。由于导出文件比较分散,一种更加便捷的方式是将所有备份文件合并成一个归档文件,代码如下:

mongodump --port 27017 --archive-all.archive
4.1.2、mongorestore命令

使用mongorestore命令可以将用mongodump命令导出的备份文件进行恢复。如下面的命令:

mongorestore --port 27017 --drop backup/

–drop表示恢复时先删除存在的集合,由于mongorestore只会执行insert操作,为了避免冲突往往需要先清空集合。如果只希望恢复部分集合,则可以使用–nsInclude选项,代码如下:

mongorestore --port 27017 --nsInclude appdb.*  --gzip --drop backup/
4.1.3、备份快照一致性

在mongodump命令执行的过程中,业务服务可能会产生新的数据写入,为了实现Point-In-Time(时间点一致)的备份,需要使用–oplog选项,代码如下:

mongodump --oplog -o backup

–oplog需要对副本集成员使用,加入该选项后,mongodump命令会在导出过程中捕捉增量产生的oplog输出到结果文件中。同样,在mongorestore命令中使用–oplogReplay选项来恢复这些oplog,代码如下:

mongorestore --oplogReplay --drop backup/

注意,mongodump命令对性能的影响比较明显,其会实现大量的临时内存,在系统内存比较紧张时通常会明显加大I/O压力。不适合在大数据集中执行mongodump/mongorestore命令,这会非常缓慢。一般小型部署或特定场景中可以使用逻辑备份。

从MongoDB 4.2版本开始,已经不推荐使用mongodump命令进行分片集群的数据备份,因为该命令无法保证分布式事务的原子性。

4.2、物理备份

物理备份的原理比较简单,一般通过系统工具(cp或rsync)对数据和日志文件进行复制。如果条件允许,则可以使用LVM来创建快照备份卷,基于LVM的文件系统快照效率更高。物理备份的文件不具备通用性,必须在使用同一种存储引擎、同一个拓扑结构以及同一版本的MongoDB集群中进行恢复。

4.2.1、分片集群备份

(1)关闭分片均衡器。连接mongos,执行如下命令:

> use config
> sh.stopBalancer()

(2)选择用于备份的备节点,在config备节点和每个分片的备节点上执行fsyncLock命令,代码如下:

> db.fsyncLock()

执行fsyncLock命令时,mongod会将内存中的修改同步到磁盘,并阻塞所有的写操作。由于fsyncLock命令会令备节点停止同步,因此需要保证备份锁定的时间不能太长,否则可能导致备节点脱离主节点的复制窗口。

(3)备份config节点数据。使用文件复制或LVM快照的方式进行数据备份。备份完成后,执行fsyncUnlock命令进行解锁,代码如下:

> db.fsyncUnlock()

(4)备份每个分片的备节点数据。

(5)为每个分片的备节点执行fsyncUnlock命令解锁。

(6)重新开启均衡器。连接mongos,执行如下代码:

> use config
> sh.setBalancerState(true)
4.2.2、分片集群恢复

(1)停止所有mongos/config/shard节点。

(2)恢复config节点备份。使用文件复制或LVM卷的方式恢复数据,重新启动。

如果是恢复到新的部署(节点IP发生变化)​,则需要执行:

  • 删除local数据库并重新初始化副本集。
  • 更新config.shards集合,将新集群的分片信息写入。

(3)恢复shard备份使用复制或LVM卷挂载的方式恢复数据,重新启动。如果是恢复到新的部署(节点IP发生变化)​,则同样需要删除local数据库并重新初始化副本集。

(4)重启所有mongos节点。如果是恢复到新的部署(节点IP发生变化)​,则需要将配置服务器指向新的config节点地址。

(5)检查集群状态。连接mongos节点,执行sh.status命令查看状态。

4.3、增量备份

无论是使用mongodump命令,还是文件快照备份,都是对全量的系统数据进行备份。全量备份需要使用更多的空间,而且恢复时间也更长,这种备份一般按天或按周进行。为了达到更细粒度的控制,即恢复到任意时间点(PITR)​,可以选择增量备份。

增量备份需要基于oplog实现,大致过程如下:

(1)执行全量备份,并记录当前全量备份的时刻TSP。

(2)10分钟后,使用mongodump命令对oplog进行备份,选择TSP时刻到当前时间的日志数据。命令如下:
在这里插入图片描述
在查询条件中,TS_START对应TSP时刻,TS_END对应当前时刻,可以将开始时间往前移动几秒钟,尽可能保证不丢失日志。备份完成后,更新TSP为当前的时刻。

(3)重复执行步骤(2)​,这样我们可以持续获得从上一次全量备份之后的多份增量数据。如果需要恢复到某个时间点,则只需要先恢复最近的全量备份,然后通过mongorestore–oplogReplay恢复增量的oplog。代码如下:
在这里插入图片描述
对于生产环境中的备份管理,可以遵循如下一些原则:

  • 优先使用基于快照的物理备份进行全量备份。
  • 定期备份,至少同时保有两份可用的全量备份。
  • 将备份数据保存到远程服务器,提高可靠性。
  • 校验备份文件的完整性,在条件允许的情况下对备份文件进行测试。
  • 在必要时进行增量备份,使用成熟的备份管理工具或托管服务提升效率。

5、容灾可靠性

1. 数据库容灾

我们在前面已经谈及副本集高可用的多个细节,高可用的目的是当某个节点发生故障(意外中断)时,系统能快速恢复。实现高可用的技术仍然需要依赖许多本地的基础设施,例如对故障节点的检测首先需要保证基础网络的可用性。那么,如果这些基础设施也发生故障了呢?根据墨菲定律,凡是有可能发生出错的事情,终究有一天会出现。当应用系统、数据库以及运行它们所必需的基础设施发生不可抗力的损坏时,我们就需要借助系统级的容灾能力来进行接管,以保证业务能继续运行。

数据库的容灾通常需要考虑冗余、数据复制及故障转移等多个方面的基数。对于一个容灾系统来说,我们关注的SLA指标主要如下。

  • RPO(Recovery Point Objective)​:指目标恢复时间点,当灾难发生时,系统最多可能发生丢失的数据时长。
  • RTO(Recovery Time Objective)​:指目标恢复时间,当灾难发生时,需要多长的时间完成系统恢复。

对于中小型应用来说,常见的做法是使用定时备份,例如每天将数据备份保存到异地的远程服务器。在发生灾难性故障时第一时间重建集群,并拉取远程备份数据进行恢复,这是一种离线式的容灾(冷备)​。数据备份可以存储多个,或者长期保存以保证持久可用。但备份数据的恢复时间通常较慢(包含远程下载、本地恢复的时间)​,而且在备份窗口内的数据都会丢失,如果提供了增量备份,则可以减少丢失的数据。因此,基于备份的容灾只能用于对RTO、RPO要求较低的系统。

为了达成高可用的容灾目的,目标方案是使用热备,这需要让主数据中心和备用数据中心同时工作并保持数据同步,当出现问题时能及时切换。热备容灾也是本节讨论的重点,对于MongoDB来说,需要结合现有的基础设施来构建容灾方案。

2. 理解Region、AZ

云计算领域基于基础设施隔离的角度定义了Region、AZ(Available Zone)两个概念。

  • Region(地域)​:通常是物理意义上位于不同地方的数据中心,地域之间的距离较远,这意味着构建Region之间的高速传输网络会产生较高的成本。
  • AZ(Available Zone)​:即可用区,可理解为同一地域内互相独立的物理机房。同一Region中的多个AZ保持独立的电力供应,AZ之间一般通过高速光纤相连。相比跨Region来说,跨AZ的网络时延要更短(大约只有几毫秒)​。

举个例子,以深圳、上海分别作为两个Region,而深圳的Region中又搭建了福田机房(可用区1)​、观澜机房(可用区2)​、南山机房(可用区3)​。

5.1、同城灾备

对于同一个副本集,或者分片集群来说,可以将各个副本集成员部署到多个可用区(AZ)来实现同城灾备,如图所示。

在这里插入图片描述

在同城灾备架构中,一个分片集群被均匀地分布到3个可用区上。每个分片,包括配置副本集的主备节点都位于不同的AZ。mongos节点同样也保持均匀分布,当某个AZ故障时,所有的分片、配置副本集以及mongos都仍然是可用的。

5.2、异地灾备

如果需要支持异地灾备,则可以在不同的Region中建立主备两个集群。集群之间利用oplog复制来实现数据同步,如图所示。
在这里插入图片描述
只要保证oplog的可见性,容灾复制方案就是可行的。连接器所负责的工作与副本集内部的复制线程大致相同,而使用批量化提交有助于提升同步的吞吐量。可以自己实现连接器代码,或者使用开源框架,如MongoShake。

理论上,连接器也可以用于两个独立的分片集群,但必须小心自动均衡带来的问题。集群场景中需要为多个分片分别使用单独的连接器,这可以实现并行复制。同时,为了降低连接器的性能损耗,一些分片均衡迁移产生的oplog需要被过滤掉。那么当chunk数据发生迁移时,就有可能会出现乱序问题。尽管我们可以关闭均衡器来规避这个问题,但始终不是完美的解决方案。

基于新版本的Change Stream为容灾复制提供了新的思路,Change Stream是基于oplog实现的,而且更加简单、稳定,同时也具有断点续传的能力。更重要的一点是,在分片集群中获得的Change Stream是全局有序的,可以不需要担心均衡器带来的困扰。从MongoDB4.0版本开始,Change Stream支持库级、集群级别的监听,进一步简化了应用的开发,如图所示。
在这里插入图片描述
这里还有一些可以改进的地方,例如为不同的数据库使 用独立的连接器,还可以使用消息队列分发来提升写入的吞吐量。

异地灾备要点

数据复制是实现异地灾备的关键技术,但除此之外我们需要考虑的因素还有很多,例如:

  • 数据同步服务(连接器)是否稳定,写入性能是否足够快。
  • 同步过程中业务性能是否会受到影响。
  • 主备节点之间的数据是否一致,如何对一些关键的元数据进行校验。
  • 如何准确判定主备系统是否故障,如何避免频繁切换。
  • 容灾切换是否快速、高效,如何降低切换时数据的丢失率。

5.3、异地多活

异地多活是一种更加复杂的容灾设计,它要求在同一时刻,所有不同地域的子系统都是可用的,而且每个子系统都同时承担了一定的流量。

利用MongoDB原生的复制以及ShardZone分区特性,可以实现按地理容灾多活的模式,如图所示。

在这里插入图片描述
在图中,我们将一个集群中的每个分片都均匀分布到了不同的机房。其中S1.P是shard1的Primary节点,S3.S是指shard3的Secondary节点,依次类推,例如北京机房则同时部署了shard1主节点、shard3备节点、shard2备(隐藏)节点。

异地多活场景下还同时需要满足就近写入、读取的原则,例如社交平台上的用户优先通过离自己最近的服务器进行注册、查看同城好友的互动等。利用ShardZone(分区标签)特性,可以为数据加上地域标签,代码如下:
在这里插入图片描述
在这里插入图片描述
sh.addShardToZone命令等同于sh.addShardTag,sh.updateZoneKeyRange命令则等同于sh.addTagRange。从MongoDB 3.4版本开始,使用Zone来表达分片标签的语义。

除了定义分片标签、数据范围分区,不要忘记为数据表(users)启用分片,这里分片键必须包含分片范围字段(前缀匹配)​,代码如下:
在这里插入图片描述
如此,我们便获得了在不同地域存储多个数据副本的能力,利用副本集自动的失效转移(failover)能力,当某个机房发生故障时能自行切换。客户端通过指定readPreference=primary或primaryPerferred可优先读取本地数据。如果希望在机房故障修复后还能恢复本地(local)读写的能力,可以通过设定成员的选举优先权(priority)来进行控制,例如为shard1上的北京节点设置最高的优先级。

然而,地理分散型的容灾架构仍然存在一些挑战:

  • 由于副本集采用了跨Region部署,很难保证网络时延问题,可能会造成数据同步差距较大。
  • 一旦发生故障,只能由另一个Region接管当前业务,性能、可靠性会出现降级。而且,也没有较好的办法进行流量切换。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值