想象一座城市只有一座自来水厂。某天深夜主水泵爆裂,整个城市停水三天:医院手术被迫改期,写字楼空调停摆,超市瓶装水被抢购一空。任何有经验的城市管理者都会告诉你,绝不能让全城的命脉系于一根水管。于是现代城市会建多座水厂、在街区修蓄水池、铺设跨江备用水管,并定期演练“主水厂瘫痪时如何在几分钟内切换供水”。搜索引擎集群,本质上就是一座“信息自来水厂”——每一次搜索,都是用户拧开水龙头。Elasticsearch/Solr 这类分布式搜索引擎中,保证“随时有水喝”的整套设计,就叫高可用与容灾设计。本文用这座水厂的故事,带你拆解副本、心跳、故障转移、灾备、备份恢复这些关键概念。

岗位关联

学会高可用与容灾设计,你才能从“能把搜索跑起来”进阶到“能让搜索在故障中扛得住、坏得掉、恢复得更快”,这是搜索平台工程师与 SRE 的核心竞争力。

目录
  1. 可视化演示
  2. 可用性度量——水厂立下的“军令状”
  3. 数据副本——每个街区都修两座蓄水池
  4. 故障检测——巡厂工人与自动压力表
  5. 故障转移——主水厂瘫了,备用水厂顶上
  6. 灾备架构设计——河对岸再建一座水厂
  7. 数据备份恢复——应急水库与“后悔药”
  8. 集群扩容运维——水厂日常巡检与扩建规划
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

模拟Elasticsearch分片副本架构、节点故障检测与Quorum投票、跨机房主备容灾切换过程,展示搜索引擎高可用机制。

本节配有交互动效(进入视口后自动加载,约 3KB)。

模式1:分片与副本架构 主分片分布在不同节点上 副本分片提供读取与故障备份 可用性 = 1 - (故障率)^(副本数+1) 副本数越多可用性越高。

可用性度量——水厂立下的“军令状”

水务局每年年初都会公布一项承诺:“本年度供水保障率不低于 99.97%”。翻译成大白话,就是一年 8760 小时里,允许停水的时间不超过约 2.6 小时。立下军令状不是为了好看,而是为了让市民、医院、工厂对供水可靠性有明确预期——承诺越硬,背后的基础设施建设就越得跟上。

搜索引擎面对用户,也要立同样的军令状,叫作 SLA(服务等级协议)。运维团队用“可用率”这个数字来度量集群的健康程度,而互联网公司常用“几个九”来分层宣传可靠性:99.9% 允许一年宕机约 8.8 小时,99.99% 约 52 分钟,99.999% 约 5 分钟。多一个九,架构成本往往要翻好几倍。

计算可用率的方法很朴素:用统计周期减去停机时间,再除以统计周期。这里的“停机时间”只统计对用户请求真正不可用的时长——节点抖动但请求仍由副本正常服务时,并不算停机。

水厂靠军令状倒逼自己修建冗余管道和备用水源;搜索团队同样靠可用率目标倒逼架构设计。指标定下来,后面讲到的副本、故障转移、灾备手段,本质上都是在为这个数字买单。

可用率=(1−停机时间统计周期)×100%\displaystyle \text{可用率} = \left(1 - \frac{\text{停机时间}}{\text{统计周期}}\right) \times 100\%
这个公式把一个模糊的“系统稳不稳”变成了可量化、可考核、可写进合同的一个百分比数字。
  1. 分子停机时间:统计周期内服务不可用的总时长,它是唯一会拉低可用率的“减分项”。
    停机时间\displaystyle \text{停机时间}
  2. 分母统计周期:一段固定的时间窗口,常用全年 8760 小时或单月 720 小时。
    统计周期\displaystyle \text{统计周期}
  3. 括号内的减法算出“正常服务时间”占整个周期的比例。
    1−停机时间统计周期\displaystyle 1 - \frac{\text{停机时间}}{\text{统计周期}}
  4. 乘以 100%把比例换算成百分比,得到 99.97% 这类直观的数字。
    ×100%\displaystyle \times 100\%

数据副本——每个街区都修两座蓄水池

一个城市哪怕只有一座水厂,就算承诺 99.97%,水泵故障的那两小时依然全城断水。解决方案很朴素:在每个街区都修蓄水池。主蓄水池检修时,备用水池立刻放水顶上;关键街区甚至会修三座池子,保证任何一座坏掉都不影响供水。

搜索引擎把这份思路搬了过来:同一份数据在多台机器上各存一份,这就是副本(replica)。在 Elasticsearch 中,原始数据叫“主分片”,它的拷贝叫“副本分片”。写请求先落到主分片,再同步给每个副本;读请求可以由主分片和副本共同分担,相当于多个蓄水池同时向用户供水。

有了副本,数据丢失的风险就像买了“多重保险”。每台机器都是独立故障的,只要任何一台上的那一份还活着,数据就还在。这里的数学关系非常漂亮。

蓄水池也不是越多越好——每多一座池子,维护成本和漏水风险都在增加。副本同理:每加一个副本,写性能要打折扣、磁盘要翻倍。生产环境中常见的是 1 主 2 副本,而不是无脑堆 10 个副本。

P丢失=p r\displaystyle P_{\text{丢失}} = p^{\,r}
单台机器故障概率为 p,副本数为 r,整份数据丢失的概率是 p 的 r 次方——副本从 1 个加到 2 个,风险下降一个数量级不止。
  1. 底数 p单台机器在考察期内的故障概率,比如 1%。
    p\displaystyle p
  2. 指数 r同一份数据持有的副本个数,包括主分片在内。
    r\displaystyle r
  3. 幂运算 p^r所有副本同时坏掉数据才丢,概率随副本数指数级下降。
    p r\displaystyle p^{\,r}

故障检测——巡厂工人与自动压力表

水厂怎么知道哪根管道漏了?靠两样东西:巡厂工人定时巡查,以及管网上密密麻麻的压力传感器。前者是周期性检查,后者是实时监测。两者配合,才能在水管爆裂的几分钟内发现异常。

分布式集群用的是一套类似的“巡检制度”:心跳(heartbeat)机制——每个节点周期性向其他节点发送“我还活着”的信号,就像工人定时到各巡视点打卡。如果超过超时阈值仍没收到某个节点的心跳,大家就判定它失联了。心跳间隔和超时阈值就像“巡检频率”,调得太宽松发现故障慢,调得太严格又容易误伤网络抖动的节点。

但判定是会出错的,真正危险的是脑裂(split-brain):集群被网络分区切成两半,两边都以为对方死了,都试图继续服务。这就像两座水厂互相不知道对方存在,各自向同一片区域供水,水压混乱、数据冲突。解决脑裂靠一条铁律。

半数仲裁就是水厂调度中心的铁律:只有超过半数的水厂能互相通信时,供水系统才允许对外供水。看似保守,却保证了任何时刻集群里最多只有一方“说了算”。

q=⌊n2⌋+1\displaystyle q = \left\lfloor \frac{n}{2} \right\rfloor + 1
集群有 n 个节点,必须超过半数(q 个)存活才能对外服务。任何时刻,集群里最多只有一方能凑够这个数,脑裂自然被堵死。
  1. n集群的节点总数,比如 3 或 5。
    n\displaystyle n
  2. 除以 2 后向下取整算出“恰好一半”的整数。
    ⌊n2⌋\displaystyle \left\lfloor \frac{n}{2} \right\rfloor
  3. 加 1保证严格超过半数,让两个“半数群体”不可能同时成立。
    +1\displaystyle + 1

故障转移——主水厂瘫了,备用水厂顶上

如果主水厂真的瘫了,市民通常不会察觉——因为调度中心早已通过阀门,在几秒钟内把供水切到了备用水厂。用户感知到的只是水压轻微波动了一下。这背后是一整套预设好的切换流程。

搜索集群的故障转移(failover)也是同一套动作。主节点失联后,集群自动执行四步:心跳超时确认故障 → 触发新主节点选举 → 将某个副本分片晋升为主分片 → 更新路由表,让新请求打到新主节点。整个过程的目标是“用户无感”,或者至少在几秒内完成。

故障转移的速度直接决定可用率。经典指标有两个:MTBF(平均无故障时间)衡量“多久坏一次”,MTTR(平均恢复时间)衡量“坏了多久能修好”。可用率可以写成两者之比。

想提高可用率有两条路:提高 MTBF(用更稳定的硬件、更严格的变更管理),或者降低 MTTR(自动化故障转移、完善的监控告警)。水厂不会追求永不爆管,而是追求爆管后 5 分钟内切换完毕——降低 MTTR 往往见效更快。

A=MTBFMTBF+MTTR\displaystyle A = \frac{\mathrm{MTBF}}{\mathrm{MTBF} + \mathrm{MTTR}}
一个完整的“坏掉又修好”周期 = 正常工作时间 + 恢复时间,正常时间占整个周期的比例就是可用率。MTTR 越小,可用率越高。
  1. 分子 MTBF两次故障之间的平均工作时长,代表系统的“耐造程度”。
    MTBF\displaystyle \mathrm{MTBF}
  2. 分母 MTBF + MTTR一个完整故障周期,等于好着的时间加上坏着的时间。
    MTBF+MTTR\displaystyle \mathrm{MTBF} + \mathrm{MTTR}
  3. 整体比值好着的时间占整个周期的比例,即固有可用率。
    A\displaystyle A

灾备架构设计——河对岸再建一座水厂

蓄水池再多,如果都建在同一座水厂的院子里,厂区停电照样全城没水。真正的城市供水会考虑极端情况:跨江、跨山,把备用水源修到物理隔离的地方。这就是“故障域”的直观含义——灾难发生的地方,不能同时覆盖主备两套系统。

搜索集群的灾备(disaster recovery)同样强调故障域隔离。同机房的不同机柜,仍共享电力、网络和建筑风险;只有跨机房、甚至跨地域部署,才能扛住“机房断电”“光缆被挖断”这类区域性灾难。常见的模式有冷备(灾备端平时不服务)、热备(灾备端实时同步、随时可切)和双活(两端同时对外服务)。

跨机房同步有同步和异步两种方式。同步复制几乎不丢数据,但写性能被跨机房网络延迟拖累;异步复制速度快,但灾难发生时可能丢一小段时间的数据。这引出一对关键指标:RTO(恢复时间目标)和RPO(恢复点目标)。

水厂在河对岸修备用水厂时,会决策“投资多少管道、多粗的管道”——这对应灾备的同步模式选择;也会对外承诺“灾害后多久恢复供水”(RTO)和“最多丢多少水”(RPO)。RPO 越小,管道就要越粗越实时,成本也越高。

RPO=t故障−t最后同步\displaystyle \text{RPO} = t_{\text{故障}} - t_{\text{最后同步}}
RPO 回答的是“灾难来了会丢多少数据”:最后一次成功同步到灾备端的时刻,与故障时刻之间的时间差,就是要丢掉的数据窗口。
  1. t_故障灾难实际发生的时刻,是时间轴上的终点。
    t故障\displaystyle t_{\text{故障}}
  2. t_最后同步数据最后一次成功同步到灾备端的时刻,是时间轴上的起点。
    t最后同步\displaystyle t_{\text{最后同步}}
  3. 两者相减这段时间内已提交但尚未同步到灾备端的数据,在灾难中会丢失。
    t故障−t最后同步\displaystyle t_{\text{故障}} - t_{\text{最后同步}}

数据备份恢复——应急水库与“后悔药”

即使有了副本和异地灾备,水厂还会做两件事:把历年水质数据存档建册,并在城市边缘修一座应急水库。副本是“实时备用”,应急水库则是“能回到过去”的保险——当灾难是“误操作”而非“硬件故障”时,只有历史存档能把局面拉回来。

搜索集群的应急水库叫快照(snapshot)——在某个一致的时间点,把整个集群的数据“拍照”,存到远端对象存储。它和副本最大的区别是时效性:副本实时存在,快照周期产生。如果发生“误删索引”或“全集群数据损坏”,副本也会跟着遭殃,快照是唯一的后悔药。

快照支持全量和增量两种方式:第一次做全量快照,之后每天只保存变化部分,像档案室只把新增的卷宗归档。快照还需要定期做数据校验和恢复演练,否则真到灾难时刻才发现备份是坏的,比没有备份更可怕。

应急水库也有代价:恢复要时间,而且从备份恢复的数据一定比“灾难发生那一刻”旧——这中间的差距就是 RPO 窗口。所以水厂既要修实时管道(副本),也要建应急水库(快照),两者各司其职、缺一不可。

T恢复=V数据量R恢复速率\displaystyle T_{\text{恢复}} = \frac{V_{\text{数据量}}}{R_{\text{恢复速率}}}
恢复耗时 = 数据量 ÷ 恢复速率。数据量越大、恢复管道越窄,回到可用状态的时间越长,这个时间必须小于 RTO。
  1. V_数据量需要从备份中恢复的快照总大小,包括数据本体和索引结构。
    V数据量\displaystyle V_{\text{数据量}}
  2. R_恢复速率从备份存储拉取数据并重建索引的吞吐速度。
    R恢复速率\displaystyle R_{\text{恢复速率}}
  3. 除法理论上最少需要的恢复时间,实际还要加上校验与路由切换的额外开销。
    V数据量R恢复速率\displaystyle \frac{V_{\text{数据量}}}{R_{\text{恢复速率}}}

集群扩容运维——水厂日常巡检与扩建规划

水厂不可能等爆管了才去修。它每天做水质检测,每周做管道压力测试,提前预测城市人口增长并规划新水厂。高可用不是“出事那一刻”的临场发挥,而是长期运维积累出来的系统能力。

搜索集群同样需要这种“日常功夫”。首先是监控告警:盯 CPU、内存、磁盘、查询延迟和任务队列堆积,就像盯水压表,任何指标异常都要提前预警。其次是滚动升级:版本升级时逐台摘流量、升级、回填,而不是整个集群重启,保证任意时刻至少有一个副本在正常服务。然后是容量规划:数据量只增不减,要根据增长速度推算未来需要多少节点、多少磁盘。

容量规划有一条经验公式:先算出数据总量(当前数据加未来增长预测),乘上副本份数,再除以单节点可稳定承载的量,最后预留 30% 到 50% 的冗余缓冲,防止“磁盘瞬间打满”引发分片无法分配、集群进入只读状态的雪崩。

最重要也最容易被忽视的是容灾演练——就像消防演习:故意杀掉一个节点、切断一条网络线路,观察集群能否自动恢复。演习时手忙脚乱发现问题,总比灾难发生时手忙脚乱要好。

N节点=D总量×(1+r副本)S单机×(1+ε)\displaystyle N_{\text{节点}} = \frac{D_{\text{总量}} \times (1 + r_{\text{副本}})}{S_{\text{单机}}} \times (1 + \varepsilon)
节点数 = 数据总量 × 副本总份数 ÷ 单机容量,再乘一个冗余系数。公式不复杂,但漏掉任何一项,集群都会在几个月后突然“撑爆”。
  1. D_总量规划周期末需要承载的数据总量。
    D总量\displaystyle D_{\text{总量}}
  2. 1 + r_副本主分片加上各副本的总份数,决定数据被重复存储几遍。
    1+r副本\displaystyle 1 + r_{\text{副本}}
  3. S_单机单节点能稳定承载的数据量,而不是磁盘标称容量。
    S单机\displaystyle S_{\text{单机}}
  4. 冗余系数 ε为数据波动、业务增长和滚动升级预留的缓冲空间。
    1+ε\displaystyle 1 + \varepsilon

AI 应用场景

电商大促的搜索集群容灾

阶段:系统架构与运维

解决的问题:大促零点流量洪峰叠加机房抖动,搜索一旦不可用,用户找不到商品、下单转化率直接崩盘。传统单集群架构下主节点故障,整个搜索页只能报错。通过多机房部署 + 心跳检测 + 自动故障转移,把切换时间压缩到秒级,让用户几乎无感。

具体案例:某电商平台在华东、华北各部署一套 Elasticsearch 集群,平时双活读写分离,大促前进行“断网切流”演练,验证 RPO 小于 10 秒、RTO 小于 60 秒的容灾目标。

金融日志检索的快照备份与恢复

阶段:数据安全与合规

解决的问题:金融系统要求日志保留数年,且发生误删除或数据损坏时必须能回滚。只靠副本无法防止“删索引”这类人为事故——副本会跟着一起删。定期把快照备份到对象存储并做恢复演练,才能保证任何时刻都能回到过去某个一致时间点。

具体案例:某支付公司每天凌晨对日志集群做增量快照,每月一次全量快照,每季度演练一次从快照恢复到全新集群,并做数据校验,确保备份真实可用。

社交平台的滚动升级不停服

阶段:变更管理与发布

解决的问题:搜索服务升级版本时,整体重启会让用户短暂搜不到内容。利用多副本架构做滚动升级,逐台摘流量、升级、回填数据,保证任意时刻至少有一个副本在服务,用户请求在节点间无缝切换。

具体案例:某内容社区升级 Elasticsearch 大版本,按“停写入→升级节点→回放数据→恢复服务”的节奏滚动操作 30 个节点,全程搜索可用率保持在 99.99% 以上。

Python 演示

python66 行
import random  class Node:    """一台集群节点, 只关心自己是否存活"""    def __init__(self, name):        self.name = name        self.alive = True  class ClusterSim:    """带半数仲裁与故障转移的模拟搜索集群"""    def __init__(self, names):        self.primary = 0        self.half = len(names) // 2        self.down_rounds = 0        self.switch_count = 0        self.nodes = [Node(n) for n in names]     def quorum(self):        """半数仲裁: 存活节点必须严格超过半数"""        alive_num = sum(1 for nd in self.nodes if nd.alive)        return alive_num > self.half     def heartbeat_round(self):        """模拟一轮心跳检查, 返回本轮服务是否可用"""        if not self.quorum():            self.down_rounds += 1            return False        if not self.nodes[self.primary].alive:            self.failover()        return True     def failover(self):        """主节点失联, 从存活副本中晋升新主"""        lost = self.nodes[self.primary].name        for i, nd in enumerate(self.nodes):            if nd.alive:                self.primary = i                self.switch_count += 1                print("主节点 %s 失联, 晋升副本 %s 为新主" % (lost, nd.name))                return     def random_flip(self, rate):        """按概率随机触发节点故障或恢复"""        for nd in self.nodes:            if random.random() < rate:                nd.alive = not nd.alive  def simulate():    random.seed(7)    cluster = ClusterSim(["A", "B", "C"])    rounds = 2000    for _ in range(rounds):        cluster.random_flip(0.08)        cluster.heartbeat_round()    avail = 1 - cluster.down_rounds / rounds    print("检测轮次:", rounds)    print("不可用轮次:", cluster.down_rounds)    print("故障转移次数:", cluster.switch_count)    print("模拟可用率: %.2f%%" % (avail * 100))  if __name__ == "__main__":    simulate()
目的:用 3 节点集群模拟随机故障下的心跳检测、半数仲裁与故障转移,输出模拟可用率,直观验证正文中的公式和机制。
  1. alive_num = sum(1 for nd in self.nodes if nd.alive)统计当前存活的节点数量,这是仲裁判断的基础。
  2. return alive_num > self.half严格超过半数才允许服务,这就是正文里对抗脑裂的铁律。
  3. self.down_rounds += 1记录不可用轮次,用于最后计算模拟可用率。
  4. if not self.nodes[self.primary].alive: self.failover()主节点失联立即触发故障转移。
  5. for i, nd in enumerate(self.nodes): if nd.alive:从存活副本中选出新主节点并晋升。
  6. random.seed(7)固定随机种子,保证每次运行结果可复现,方便验证。
  7. avail = 1 - cluster.down_rounds / rounds与正文完全一致的可用率公式:1 减去不可用占比。

常见误区

误区我多加几个副本,数据就更不容易丢,集群一定更稳。副本设成 5 份总没错吧?

正解副本提高的是“读可用性”和“抗单点故障”能力,但每个副本都会拖慢写路径——主分片要把每次写入同步给所有副本,还要占用成倍的磁盘和带宽。副本从 1 加到 2 收益很大,从 3 加到 5 边际收益骤降。合理的做法是 1 主 2 副本,配合跨机架或跨机房布局,再加上定期快照,多机制组合而不是单靠数量堆。

为何常见:只看到冗余带来的收益,没考虑写放大和存储成本,把高可用简单等同于“多存几份”。

误区高可用就是保证 7×24 完全不停机,任何一次短暂的不可用都是失败,系统必须做到永远不坏。

正解高可用不是零停机,而是把停机时间控制在 SLA 允许的范围内。99.99% 可用率允许一年约 52 分钟的不可用。关键在于故障发生时能在 RTO 内自动恢复,让用户几乎无感——就像水厂爆管后 5 分钟切换完毕,市民根本不知道发生过事故。

为何常见:把“高可用”误解为“绝对不坏”,忽略了故障是概率事件,“快速恢复”才是高可用的核心含义。

误区我每天做一次快照备份,数据丢了直接恢复就行,没必要养那么多副本,浪费机器。

正解备份解决的是“灾难级恢复”——误删索引、全集群数据损坏;但快照是周期性的,两次快照之间的数据会全部丢失,这个窗口就是 RPO。副本是实时的,主分片挂掉立刻由副本顶上,数据一条不丢。两者是“实时止血”和“事后后悔药”的关系,不能互相替代。

为何常见:混淆了“数据恢复”和“服务连续性”两个不同的目标,以为只要有备份,服务中断和数据丢失都能一并解决。

误区我把节点分散到机房的几个机柜里,已经做了灾备了,机房塌了也不怕。

正解同机房即使放在不同机柜,仍然共享电力、网络接入和建筑风险——一次机房断电或火灾,所有机柜一起完蛋。真正的灾备要求故障域隔离:至少跨机房(不同电力、不同网络出口),关键业务甚至要跨地域部署,才能应对区域性灾难。机柜级冗余只是“高可用”,机房级隔离才是“容灾”。

为何常见:“分散”是初级意识,没有理解故障域的概念,把机柜级别的冗余误当成了机房级别的容灾。

误区集群主节点坏了,随便找一台还活着的机器当主节点就行,反正都是同一份数据。

正解新主节点的选择非常讲究:必须选数据最新最完整的副本,根据数据版本号或任期判断,否则会丢掉已提交的数据;同时选举必须满足半数仲裁,避免网络分区时两端各自选出主节点,造成脑裂。就像水厂切换不能随便开某个阀门,必须确认新水源的水质和水量都合格,并且只有调度中心有权下令。

为何常见:只看到“换人”这个结果,没看到“选谁”和“怎么选”才是保证数据一致性和防脑裂的核心。

面试题

Q1. 决定集群在部分节点失联时是否还能继续服务、从而防止脑裂的机制是?

单选题 · easy

  • A.心跳超时检测机制
  • B.半数仲裁选举机制← 正确答案
  • C.分片副本存储机制
  • D.快照定期备份机制

答案:B。心跳负责“发现”故障,半数仲裁负责“决策”——只有存活节点超过半数才允许服务,从数学上杜绝两个群体同时自认为合格。副本和快照是数据冗余手段,不直接参与防脑裂决策。

Q2. 某集群一年停机约 3 小时,其可用率最接近哪个值?

单选题 · easy

  • A.约 99.9%
  • B.约 99.97%← 正确答案
  • C.约 99.99%
  • D.约 99.5%

答案:B。一年约 8760 小时,3 ÷ 8760 ≈ 0.034%,可用率 ≈ 99.966%,最接近 99.97%。可用率公式就是 1 减去停机时间占比,属于送分题,但要注意与“几个九”对应关系的换算。

Q3. 容灾指标 RPO 描述的是哪项内容?

单选题 · mid

  • A.系统恢复耗时的要求
  • B.最多丢失的数据时间窗← 正确答案
  • C.集群心跳检测的间隔
  • D.数据副本的数量规模

答案:B。RPO(恢复点目标)衡量灾难发生后最多能容忍丢失多长时间的数据,对应“最后同步时刻”到“故障时刻”的差值。恢复耗时是 RTO,心跳间隔是检测参数,副本数量是冗余配置,三者都不是 RPO。

Q4. 3 节点集群按半数仲裁规则,最小存活节点数是多少?

单选题 · mid

  • A.至少 1 台节点存活
  • B.至少 2 台节点存活← 正确答案
  • C.至少 3 台节点存活
  • D.存活数量不受限制

答案:B。半数仲裁公式 q = ⌊n/2⌋ + 1,n=3 时 q=2。要求严格超过半数,所以 2 台是底线。只存活 1 台时集群无法选出可信的主节点,宁可拒绝服务也不能冒险脑裂。

Q5. 数据有 r 个副本,单节点故障概率 p,整份数据丢失的概率约为?

单选题 · mid

  • A.p 的 r 次方即 p^r← 正确答案
  • B.p 乘以 r 即 p×r
  • C.p 除以 r 即 p/r
  • D.1 减去 p^r 的结果

答案:A。所有副本同时故障数据才丢,独立故障概率相乘得到 p^r。比如 p=0.01、r=3 时丢失概率是百万分之一。B 是线性错误直觉,D 是可用率而非丢失概率。

Q6. 主节点故障后,新主节点的正确选择依据是?

单选题 · hard

  • A.随机挑一台存活的机器
  • B.选数据最新最完整的副本← 正确答案
  • C.选最近启动的那一台机器
  • D.选 CPU 负载最低的节点

答案:B。新主必须持有最新最完整的已提交数据,否则会丢数据。随机、按启动时间或按负载选主,都可能选到数据落后的副本,导致已提交写入丢失。选举算法(如 Bully/Raft)都会以数据版本和任期作为核心判断依据。

Q7. 防止集群脑裂最有效的配置手段是?

单选题 · hard

  • A.把副本数量增加到五份
  • B.启用最小主节点数量限制← 正确答案
  • C.把心跳周期缩短到 0.1 秒
  • D.关闭分片自动均衡功能

答案:B。脑裂的本质是网络分区后两边都认为对方死亡。最小主节点数(如过半仲裁)让集群在存活节点不足时拒绝选举,从规则上堵死脑裂。副本数、心跳频率和均衡开关都不影响“谁能当选”的判定。

Q8. 高可用集群通常采用哪些手段组合?

多选题 · mid

  • A.数据副本加主备自动切换← 正确答案
  • B.心跳检测加自动故障转移← 正确答案
  • C.全部数据存单机本地磁盘
  • D.跨机房容灾与多活部署← 正确答案

答案:ABD。副本提供数据冗余,心跳与故障转移提供自动恢复,跨机房部署提供区域容灾,三者叠加才构成完整的高可用体系。C 把所有数据放单机等于把鸡蛋放一个篮子,违背高可用的基本前提。

Q9. 关于快照备份,下列说法正确的是?

多选题 · hard

  • A.提供全局一致的时间点备份← 正确答案
  • B.快照只支持全量不支持增量
  • C.快照可用于跨集群的迁移← 正确答案
  • D.快照能替代副本实时容灾

答案:AC。快照在一致时间点生成,可以整体恢复到新集群,因此常用于数据迁移。快照支持全量加增量组合,所以 B 错。快照是离线备份,有 RPO 窗口,无法替代副本承担实时容灾,D 错。

Q10. 关于 RTO 和 RPO,哪些理解是正确的?

多选题 · mid

  • A.RTO 指恢复业务所需时间← 正确答案
  • B.RPO 越小同步实时性要求越高← 正确答案
  • C.RTO 在数值上总是大于 RPO
  • D.副本同步有助于降低 RPO← 正确答案

答案:ABD。RTO 是业务恢复耗时,RPO 是数据丢失窗口。RPO 越小意味着需要更实时的同步(如同步复制),副本同步能让“最后同步时刻”无限逼近“故障时刻”,从而降低 RPO。RTO 和 RPO 是两套独立指标,没有必然的大小关系,C 错。