0

我很难理解领导者何时真正确认客户。这是 DistributedLog文档的一部分:

在此处输入图像描述

每个附加到日志段的批处理条目将由日志段编写器分配一个单调递增的条目 ID。所有条目都异步写入管道中。因此,日志段写入器会更新内存中的指针,称为 LAP (LastAddPushed),它是写入器推送到日志段存储的最后一个批处理条目的条目 id。条目可以乱序写入,但只能按条目 ID 顺序进行确认。除了成功确认之外,日志段编写器还更新内存中的指针,称为 LAC (LastAddConfirmed)。LAC 是作者已经确认的最后一个条目的条目 ID。在 LAC 和 LAP 之间写入的所有条目都是未确认的数据,它们对读者不可见。

读取器可以读取高达 LAC 的条目,因为已知这些条目是持久复制的 - 因此可以安全地读取,而不会违反读取顺序的风险。writer 在发送给 BookKeeper 的每个条目中都包含当前 LAC。因此,每个后续条目都会使前一个条目中的记录对读者可见。LAC 更新可以搭载在编写器写入的下一个条目上。由于读者是严格的追随者,他们可以利用 LAC 从任何副本中读取持久数据,而无需与作者进行任何沟通或协调。

DL 引入了一种系统记录,称为控制记录——它作为两阶段提交算法中的提交请求。如果在指定的 SLA 内没有应用程序记录到达,编写器将生成控制记录。随着控制记录的写入,它将推进日志流的LAC。在收到写入用户记录的确认后立即添加控制记录,如果没有添加应用程序记录,则定期添加控制记录。它被配置为写入器刷新策略的一部分。虽然控制日志记录存在于物理日志流中,但它们不会由日志读取器传递给应用程序。

现在考虑以下场景:

  1. Leader 向 Bookkeeper 发布消息
  2. 追随者获取消息,附加到日志并向领导者发送ACK
  3. 领导者从追随者那里得到确认,增加 LAC 并回复客户端消息已提交。
  4. 现在:领导者在它可以搭载 LAC 已增加的追随者之前失败。
  5. 问题是:由于潜在的领导者不知道 LAC 已增加的事实,它成为新的领导者并将日志截断为旧的 LAC,这意味着我们丢失了日志中已由前任领导者确认的条目。

结果客户端已经确认消息已经写入成功,但是已经丢失了。

4

1 回答 1

1

由于潜在领导者不知道 LAC 已增加的事实,因此它成为新领导者并将日志截断为旧 LAC,这意味着我们丢失了日志中已由前领导者确认的条目。

有几种情况:

1)如果领导者优雅地关闭日志,它将密封它正在写入的日志段。LAC 将是高级的,它也将被记录为日志段元数据的一部分(存储在元数据存储中)。

2)如果领导者崩溃并且没有优雅地关闭日志,那么潜在的领导者就会出现,它将经历一个恢复过程。新领导人所做的将是:

  • a) 它将尝试封印前一个领导者写入的最后一个日志段。封印过程由 bookkeeper 客户端完成,包括两部分: (a) 它将隔离日志段。fencing 强制在此日志段中不能再发生写入。(b) 然后它将从最后一个已知的 LAC 进行前向恢复并恢复已写入但尚未提交的条目。

  • b) 恢复最后一个日志段后,新的领导者将打开一个新的日志段写入条目。

希望这能解释你的问题。

DistributedLog 还有一篇发表在 ICDE 2017 上的论文。你可以从这里获得。

于 2018-01-10T00:37:20.870 回答