为持久容错 GCS 调优 Redis#

使用 Redis 备份全局控制存储 (GCS) 并结合 KubeRay,可以在 Ray Head 丢失时提供容错能力。它允许新的 Ray Head 通过读取 Redis 来重建其状态。

然而,如果 Redis 丢失数据,Ray Head 的状态也会丢失。

因此,您可能希望在 Redis 集群发生部分或完全故障时获得进一步的保护。本指南介绍了如何为使用 KubeRay 的高可用 Ray 集群配置和调优 Redis。

调优您的 Ray 集群以实现高可用性,可以保护长时间运行的作业免受意外故障的影响,并允许您在通用硬件/可抢占机器上运行 Ray。

解决方案概览#

KubeRay 支持使用 Redis 来持久化 GCS,这使得您可以将(数据丢失的)故障点转移到 Ray 外部。然而,您仍然需要配置 Redis 本身以具备故障恢复能力。

此解决方案提供一个由硬件存储支持的持久卷(Persistent Volume),Redis 将使用它来定期写入快照。如果您丢失了 Redis 或其主机节点,可以从快照恢复 Redis 部署。

虽然 Redis 支持集群,但 KubeRay 仅支持独立(单副本)的 Redis,因此省略了集群配置。

持久存储#

特殊存储卷(如 Google Cloud Storage FUSE 或 S3)不支持追加操作,而 Redis 使用追加操作来高效地写入其追加仅文件 (Append Only File, AOF) 日志。使用这些选项时,建议禁用 AOF。

对于 GCP GKE 和 Azure AKS,默认的存储类分别是持久磁盘SSD Azure 磁盘,配置磁盘所需的唯一配置如下:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redis-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
  storageClassName: standard-rwo

在 AWS 上,您也必须自己创建一个存储类

调优备份#

Redis 支持按设定的间隔进行数据库转储(dump),这有利于快速恢复和正常运行期间的高性能。

Redis 还支持以频繁的间隔(或持续)进行日志记录(journaling),这可以提供更强的持久性,但代价是更多的磁盘写入(即性能较慢)。

备份的一个良好起点是同时启用这两者,如下所示:

# Dump a backup every 60s, if there are 1000 writes since the prev. backup.
save 60 1000
dbfilename dump.rdb

# Enable the append-only log file.
appendonly yes
appendfilename "appendonly.aof"

在这种推荐配置中,Redis 每 60 秒创建一次完整备份,并每秒更新一次追加文件,这在磁盘空间、延迟和数据安全之间取得了合理的平衡。

还有更多配置 AOF 的选项,此处显示默认值:

# Sync the log to disk every second.
# Alternatives are "no" and "always" (every write).
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

您可以在此处查看完整参考。

如果您的作业通常是幂等的,并且可以从几分钟的状态丢失中恢复,您可能更倾向于禁用追加仅文件日志。

如果您希望您的作业尽可能少地丢失状态,那么您可能更倾向于将 appendfsync 设置为 always,以便 Redis 立即存储所有写入。

整合#

编辑完整的 YAML 文件以符合您的需求并应用它:

kubectl apply -f config/samples/ray-cluster.persistent-redis.yaml

验证 Kubernetes 是否配置了磁盘并且 Redis 正在运行:

kubectl get persistentvolumes
kubectl get pods
# Should see redis-0 running.

运行一个在 GCS 中具有一些状态的作业后,您可以删除 Ray Head pod 和 Redis pod,而不会丢失数据。

验证#

使用Ray kubectl 插件转发到刚刚创建的 Ray 集群的连接:

$ kubectl ray session raycluster-external-redis

然后提交您选择的任何 Ray 作业并让其运行。完成后,删除所有 pod:

$ kubectl delete pods --all

等待 Kubernetes 配置 Ray Head 并进入就绪状态。然后重新启动端口转发并查看 Ray Dashboard。您应该会发现 Ray 和 Redis 已持久化您的作业元数据,即使 Ray Head 和 Redis 副本丢失了也是如此。