Replica 数据恢复

原理

通常来说,Pegasus的数据会存储3个副本。对于每个partition,正常情况下应当都有一主两备3个replica提供服务。

但是,集群不可避免会发生节点宕机、网络异常、心跳失联等情况,造成副本丢失,对服务可用性产生影响。副本丢失的程度会影响读写的能力(在负载均衡里也有介绍):

  • 一主两备都可用:partition完全健康,可以正常读和写
  • 一主一备可用:根据PacificA一致性协议,同样可以安全地读和写
  • 只有一主可用:此时不可写,但是可读
  • 全部不可用:此时不可读写。这种情况我们称之为DDD,即Dead-Dead-Dead的缩写,表示3个副本都不可用。

以上情况中,除了全部不可用的DDD状态,其他情况下MetaServer都能自动补充副本,并最终恢复至完全健康状态。但是如果partition进入DDD状态,MetaServer就无法对其进行自动恢复,需要进行人工干预。

这个讨论中给出了进入DDD状态的例子。实际上,只要某个partition进入DDD状态,且LastDrop的最后两个节点中有一个节点无法正常启动,就会进入需要人工干预的DDD状态。而在线上集群多个节点的起起停停过程中,这种情况是很容易出现的。

可以通过Shell工具的ls -d命令查看健康状况,如果read_unhealthy的个数大于0,就表示有partition进入了DDD状态。

DDD诊断工具

从v1.11.0版本开始,Pegasus在Shell工具中提供了ddd_diagnose命令,以支持DDD自动诊断功能。

命令用法:

ddd_diagnose [-g|--gpid appid|appid.pidx] [-d|--diagnose] [-a|--auto_diagnose]
             [-s|--skip_prompt] [-o|--output file_name]

参数说明:

  • -g:指定app_id或者partition_id,譬如-g 1或者-g 1.3;如果不指定,则对所有表执行操作。
  • -d:进入诊断模式;如果不指定,则只显示DDD情况,但不进行诊断。
  • -a:开启自动诊断,即在保证数据一致性前提下,如果诊断工具能寻找到合适的备份作为该partition的主备份,则自动将其设置为primary,完成数据恢复,无需人工干预。
  • -s:避免交互模式;如果不指定,则在进行诊断的过程中可能会要求用户输入信息,以完成选择、确认、或者信息补充。
  • -o:将结果输出到指定文件。

使用示例(如果看不清楚,请在单独的页面中打开图片):

ddd-diagnose.png

上图是使用ddd_diagnose命令时的输出,我们通过红色的箭头标识依次进行说明:

  • 1:当前正在诊断的partition id。
  • 2:该partition在zookeeper上持久化的ballotlast_committed_decree信息,但是由于持久化不是实时的,该值可能小于实际值。
  • 3:dropped列表,列举曾经服务过该partition的节点的状态信息,重点关注:
    • alive:该节点是否可用。
    • ballot:该partition在该节点上replica的实际ballot;如果为-1,表示该partition在该节点上不存在数据。
    • last_committed:该partition在该节点上replica的实际last_committed_decree
    • last_prepared:该partition在该节点上replica的实际last_prepared_decree
    • 最后如果有<==,表示该节点是 最后一个变得不可用(the latest) 还是 倒数第二个变得不可用(the secondary latest)。
  • 4:last_drops列表,记录节点变得不可用的时间顺序。
  • 5:ddd_reason,表示该partition变成DDD状态的原因。
  • 6:recommanded_primary,诊断工具在保证数据一致性的前提下推荐的新primary;如果无法给出,则为none
  • 7:如果第6步给出了推荐节点,则提示用户采取下一步操作(如果指定了-a或者-s选项,则不会进入这一步,相当于总是自动选择y):
    • y:采用该推荐节点作为新的primary。
    • n:不采用该推荐节点,而是让用户选择其他的节点。
    • s:忽略对该partition的诊断。
  • 8:如果第6步没有给出推荐节点或者第7步选择了n,则提示用户输入新的节点作为primary。
  • 9:生成propose命令,发送给MetaServer,将节点指定为新的primary,对该partition进行恢复。
  • 10:收到propose命令的回复,ERR_OK表示执行成功。
  • 11:显示当前已经完成的进度,分子为已经完成诊断的个数,分母为需要进行诊断的总个数。

推荐用法

  • ddd_diagnose -d -a,即开启自动诊断,对于无法自动完成诊断的partition,通过与用户交互来获得人工干预。这是最简单省心的用法,在大部分情况下都能自动完成恢复过程,无需人工干预。

在无法完成自动诊断的情况下,会进入上图中的第8步,需要用户输入新的节点作为primary。那么,在dropped列表的众多节点中,如何选择最合适的节点作为primary呢?我们的建议是:

  • 在所有alive为true的节点中,选择last_prepared值最大的节点,因为这样能尽可能多地恢复数据,减少数据丢失的可能性。
Copyright © 2023 The Apache Software Foundation. Licensed under the Apache License, Version 2.0.

Apache Pegasus is an effort undergoing incubation at The Apache Software Foundation (ASF), sponsored by the Apache Incubator. Incubation is required of all newly accepted projects until a further review indicates that the infrastructure, communications, and decision making process have stabilized in a manner consistent with other successful ASF projects. While incubation status is not necessarily a reflection of the completeness or stability of the code, it does indicate that the project has yet to be fully endorsed by the ASF.

Apache Pegasus, Pegasus, Apache, the Apache feather logo, and the Apache Pegasus project logo are either registered trademarks or trademarks of The Apache Software Foundation in the United States and other countries.