Skip to main content

单副本高可用

info

本文中提及的 AutoMQ Kafka 术语,均特指安托盟丘(杭州)科技有限公司通过 GitHub AutoMQ 组织下开源的 automq-for-kafka 项目。

引言

在 IDC 时代,因为本地磁盘是不可靠,各种存储类的产品需要通过 RAID 或者自己做复制来保障数据的可靠性和可用性。而在云的时代,云盘作为云存储中应用最广泛的存储之一,基于多副本和纠错码机制,已经提供 4 个 9 的服务可用性和 9 个 9 的数据可靠性。如果存储类应用架构再基于云盘之上去构建多副本,提升数据可靠性的作用微乎其微,反而会使存储成本成倍增加。

AutoMQ for Kafka(AutoMQ Kafka) 使用云盘来作为 Delta WAL 的存储,由云盘来保障数据的高可靠。采用单副本云盘模式,在云盘上层不做额外的复制。免去副本复制,这样不仅能节省磁盘的成本,还能节省出来网络带宽提供更多消费 Fanout 的吞吐。

单副本云盘已经可以解决数据可靠性问题,但是在日常应用进行发布、重启等运维操作时,云盘挂载的节点属于不可用状态,在这段时间云盘上的数据不可读写,会造成可用性问题。不可用时间为节点从关机到运维操作结束重新拉起恢复完成时间,通常要持续数分钟。如果是节点宕机,那么恢复的时间会更长。

那么 AutoMQ Kafka 是如何保障单副本云盘在日常运维和宕机场景下的高可用呢?

日常运维

当 AutoMQ Kafka 在进行发布升级、重启等涉及到节点关机操作的时候:

  1. Broker 接收到 kill 15 关机信号,开始优雅关闭;
  2. Broker 强制将云盘中 Delta WAL 的数据作为一个 WAL object 上传到对象存储,然后将 Delta WAL 进行标记清空。Delta WAL 的大小在 500MB 以内,100MB/s 实例利用网络突发性能 2s 左右就可以完成上传;
  3. Delta WAL 上传到对象存储后,该 Broker 上所有 Partition 的数据可以被集群中其他任意节点通过对象存储访问。接着 Controller 将该 Broker 的 Partition 秒级调度到其他存活的节点。
  4. 待 Partition 全都转移后,Broker 完成优雅关机。

AutoMQ Kafka 整个关机流程1分钟左右就能完成。通过 Broker 关机将 Delta WAL 上传到对象存储和 Partition 转移的方式,Partition 不可用时间均值为 1.5s。在日常运维的同时,AutoMQ Kafka 客户端的发送和消费行为几乎不受到影响(客户端底层有失败重试机制,Partition 能在超时时间内完成恢复)。

异常宕机

caution

当前 AutoMQ Kafka 异常宕机需要等待宕机 Broker 重启恢复来进行 Delta WAL 上传。下面提到的秒级容灾方案计划在后续版本中实现。

在 Broker 异常宕机场景,无法优雅的将本节点的 Delta WAL 上传到对象存储。异常宕机的问题转化为如何将宕机节点的 Delta WAL 安全的上传到对象存储,其中“安全”代表上传前要 Fence 掉原有 Broker 的进一步写入(因为该 Broker 可能是假死),“上传”代表其他节点能读取 Delta WAL。

AutoMQ Kafka 为了在宕机场景能由其他节点安全的上传 Delta WAL 数据,使用了云盘的 Multi-Attach 能力。异常宕机容灾流程如下:

  1. Controller 监测到 Broker 会话超时,把该 Broker 标记成宕机,并指定集群中一台存活的节点作为容灾负责节点;
  2. 容灾负责节点首先会通过云盘的 Multi-Attach 挂载宕机节点的云盘,调用 NVMe Reservation Acquire 去 Fence 掉宕机节点的写入权限,并且获取该云盘的读写权限;
  3. 读取 Delta WAL 并上传到对象存储;
  4. 关闭宕机节点负责的 Partition 对应的 S3Stream,触发 Partition 重新调度;
  5. Partition 从 unclean shutdown 恢复重新打开,完成宕机容灾。

步骤 1 - 4 整体耗时大致为 20s 左右。步骤 5 由于 Kafka Partition unclean shutdown 需要重建最后一个 LogSegment 的索引,所以耗时通常为分钟级。