通常来说,Pegasus的数据会存储3个副本。对于每个partition,正常情况下应当都有一主两备3个replica提供服务。
但是,集群不可避免会发生节点宕机、网络异常、心跳失联等情况,造成副本丢失,对服务可用性产生影响。副本丢失的程度会影响读写的能力(在负载均衡里也有介绍):
以上情况中,除了全部不可用的DDD状态,其他情况下MetaServer都能自动补充副本,并最终恢复至完全健康状态。但是如果partition进入DDD状态,MetaServer就无法对其进行自动恢复,需要进行人工干预。
这个讨论中给出了进入DDD状态的例子。实际上,只要某个partition进入DDD状态,且LastDrop的最后两个节点中有一个节点无法正常启动,就会进入需要人工干预的DDD状态。而在线上集群多个节点的起起停停过程中,这种情况是很容易出现的。
可以通过Shell工具的ls -d
命令查看健康状况,如果read_unhealthy
的个数大于0,就表示有partition进入了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
:将结果输出到指定文件。使用示例(如果看不清楚,请在单独的页面中打开图片):
{:class=“img-responsive”}
上图是使用ddd_diagnose
命令时的输出,我们通过红色的箭头标识依次进行说明:
ballot
和last_committed_decree
信息,但是由于持久化不是实时的,该值可能小于实际值。ballot
;如果为-1,表示该partition在该节点上不存在数据。last_committed_decree
。last_prepared_decree
。<==
,表示该节点是 最后一个变得不可用(the latest) 还是 倒数第二个变得不可用(the secondary latest)。none
。-a
或者-s
选项,则不会进入这一步,相当于总是自动选择y):ERR_OK
表示执行成功。推荐用法:
ddd_diagnose -d -a
,即开启自动诊断,对于无法自动完成诊断的partition,通过与用户交互来获得人工干预。这是最简单省心的用法,在大部分情况下都能自动完成恢复过程,无需人工干预。在无法完成自动诊断的情况下,会进入上图中的第8步,需要用户输入新的节点作为primary。那么,在dropped列表的众多节点中,如何选择最合适的节点作为primary呢?我们的建议是:
last_prepared
值最大的节点,因为这样能尽可能多地恢复数据,减少数据丢失的可能性。