Gitlab redis多AZ容灾高可用方案调研

背景

Gitlab多AZ容灾建设,目前自身服务已实现单AZ故障演练服务秒级自动切换恢复。但对应Gitlab依赖的服务平台,还有redis没有完全参与AZ容灾演练,AZ容灾效果仍处于未知状态。

问题

  1. Gitlab****只支持redis哨兵模式,不支持redis cluster mode
  2. 公司redis集群哨兵模式不支持AZ逃生,且后续暂无计划支持
  3. 现状问题是AZ故障时,可以确保Gitlab服务正常,但故障恢复后的短暂时间(预估2~3min)会有redis双写问题

问题现状分析

经过调研和梳理,之前gitlab服务所在AZ和依赖redis所在AZ情况,整理如下场景:

img

综上,如果是按照AZ2.0架构,进行多AZ容灾建设,如果是单一AZ故障的话,Gitlab可以通过一些低成本的逃生手段达到AZ故障逃生,进而正常提供服务。

但如果通过AZ容灾演练,redis主节点发生变化,即****redis主节点和gitlab应用服务器在同一AZ时,就会出现问题

img

上述故障切换第3种情况,若故障恢复后,AZ4连接还是之前的AZ3 redis集群,AZ1连接的是新的AZ4 redis集群,在对故障AZ4的Gitlab服务进行修改之前的这段时间故障时所在AZ的Gitlab服务器无法登录和操作,此时可能会出现reids双写,数据不一致的情况

业界调研

Gitlab redis社区方案是使用redis sentinel模式,未给出有相关多AZ可用区的建设参考方案。Gitalb不支持redis cluster模式Redis Cluster mode is not supported by GitLab.

gitlab.com使用的推荐方案是使用第三方云服务提供商,自身可不用考虑AZ容灾的问题,交给云服务提供商解决。

各大厂redis容灾方案调研

快手 Google cloud platform 阿里云 腾讯云
架构部署 img Memorystore for Redis img img 集群架构1.代理模式img 2.直连模式img 集群架构 img
容灾方案 img imgAZ2.0img KCC平台AZ逃生前提条件:使用公司框架****没有写死ip地址情况(需要业务自行修改客户端配置切换AZ) 跨地区复制读取副本允许分布式读取 img 单可用区高可用方案同城容灾方案跨地域容灾方案 img img img 多可用区实例具有更高的可用性和容灾能力。主机、机架、可用区级容灾能力。img 两可用区部署:img

方案

针对目前redis容灾问题,整理几个方案思路,供参考讨论,具体可行性及成本待进一步调研验证

  1. AZ故障时,Gitlab reids容灾接受短时间的redis双写问题,尽量减少故障恢复处理时长(具体方案待补充)
  2. 改造Gitlab,支持redis cluster模式?
  • 如果使用redis cluster模式,就要确保mutli-key都在同一个slot,否则会出现错误:ERR CROSSSLOT Keys in request don’t hash to the same slot,而Gitlab源码中redis使用了多multi-key的命令场景,如Gitlab::Redis::Cache.with { |redis| redis.mget(‘foo’, ‘bar’) }
  1. 搭建Proxy 代理,Gitlab直连proxy,不关注后端redis,proxy能够自动检测redis可用性,并自动摘除/切换redis?
  2. 使用第三方云服务商,调研公司云集CMP

改造成本,维护成本,潜在风险等多方面考虑。

2023.7.10更新

上次讨论遗留问题:

  1. 分析数据可不可以丢失,丢失成本?
    • 缓存类数据可容忍丢失,如仓库数据、session等,
    • sidekiq队列任务不可容忍丢失,如merge更新合并、webhook等丢失后可能影响代码错乱、丢失等风险
  1. 分析使用cluster模式的命令,有哪些不支持,影响有哪些? 我们是否使用? 是否可以部分切换cluster模式
    • 分两类,一类是multi-key命令,如mget,缓存类使用,通过hash tag方式改造,有可能使用cluster模式,如redis-ratelimiting
    • 另一类阻塞类命令,sidekiq使用brpop,属于cluster模式受限制命令,无法使用cluster模式
  1. 分析故障恢复后,双redis数据不一致的影响?
    • 相比数据丢失,数据不一致可能影响更大、更麻烦。
  1. redis同学确认主和冷备切换同步逻辑,故障时是否停止同步任务,同步方向
    • redis AZ故障前,热备1向冷备2同步,AZ故障时,同步会断开,需要业务切换redis连接到冷备2,此时原热备1相当于没有流量和数据。业务切换完成后,需要找redis同学重新开启同步,即冷备2(新的热备)向热备1(新的冷备)全量同步。
    • 若故障恢复后,原热备1还有流量,此时会双集群读写,可能会数据不一致,公司redis无法处理解决这种情况
  1. 服务注册、服务发现的思路,Gitlab应该连哪个健康的节点,问题节点自动摘除、切换
1
2
3
# reids sentinel健康检查
/opt/gitlab/embedded/bin/redis-cli -h public-bjzey-rs-redis666.idchb1az3.hb1.kwaidc.com -p 17312 ping
PONG

Gitlab redis详细调研

redis分为不同的种类,其中 Redis queues, shared state, and tracechunks是需要持久化存储的,目前都是同一个reids集群存储。

img

redis集群 存储数据内容 补充
gitlabHARedisSentinelNew queue队列 1%session 30%shard_statetrace_chunks**rate_limiting(可容忍丢失)**之前拆分集群历史遗留数据(不过期)52%其他 15% img
gitlabRedisCache 缓存cache,可容忍数据丢失。新旧集群双写,无需数据同步迁移存在不过期的数据?49737个 imgimg

Gitlab社区相关issue讨论redis水平扩展性,Redis cluster vs redis::Distributed, 其中redis cluster模式,sidekiq是个例外,不能使用。sidekiq中使用的大量的redis brpop命令,属于cluster模式受限命令

https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1986

img

redis cluster模式命令限制

img

sidekiq异步队列

Sidekiq 是 Ruby on Rails 应用程序中使用的多线程后台作业处理系统。Gitlab中主要执行包括:推送后更新合并请求、 发送电子邮件、 更新用户授权、 处理 CI 构建和管道等。目前总共大概350+种队列任务

Gitlab社区新版本支持redis cluster模式探索

目前Gitlab redis cpu和内存使用限制,不支持横向扩展。

Gitlab后续新版本探索和支持redis cluster,v16.0版本支持rate limiting类型

GitLab supports Redis Cluster only for the Redis rate-limiting type, introduced in epic 823.

https://gitlab.com/gitlab-com/gl-infra/readiness/-/blob/a965c665a22d2e59ab6325ca9ab453255ab62730/redis-cluster/ratelimiting.md

rate limiting类型几个考虑:

  1. 没有分片命令操作(has no cross-slot operations)
  2. 数据丢失可容忍度高
  3. 数据生命周期都是短暂的,不用迁移现有数据,直接切换使用新的集群,相对成本较低
  4. 从Omnibus拆分单独的redis管理配置
  5. redis版本7, 包含一些专门针对 Redis Cluster 的修复和改进

Gitlab社区目标是redis-cache类型迁移使用redis cluster模式,里程碑2023-7-28

2023-7-19 三次更新

TODO

  1. gitlab 切换redis配置自动化操作,降低人工操作错误率和时间成本

  2. redis单个集群跨机房,风险点调研确认,决策是否自建redis sentinel跨机房集群

    1. redis主从复制严重依赖网络,虽然redis不断提升复制能力(Redis 主从复制的原理及演进),sync->psync->psync2,但redis部署在不同的IDC,发生长网络抖动时可能会出现全量复制风暴,全量复制风暴对可用性是毁灭性的
    2. 网络延时影响:主从复制,proxy访问转发,sentinel探活,这些事情都是要求时效性要求较高的,比如说出现网络抖动,同机房可能就是抖一下,跨机房可能延迟超过探活直接切换了
    3. 全量同步fork 耗时过长,阻塞主进程,执行fork 时,需要拷贝大量的内存页表,这是一个耗时较多的操作,尤其当内存使用量较大的时候。fork 的时候主进程阻塞 100 多毫秒,这对 Redis 而言,实在太长了。另外fork 之后,如果主库中有不少的写入,那么由于写时复制机制,会额外消耗不少的内存,还会增大响应时间。

img

小结:kcc不支持单redis集群跨IDC机房部署。也不建议自建redis sentinel跨机房集群

  1. 双集群热备-冷备模式,单集群故障了,目标是能够实现全自动感知与切换,确保无人值守时服务正常(consul服务发现?)

公司kcc redis冷备故障切换示意图:

img img


Gitlab redis多AZ容灾高可用方案调研
http://coder-xieshijie.cn/2023/07/23/个人成长/工作领域汇总/Gitlab-redis多AZ容灾高可用方案调研/
作者
谢世杰
发布于
2023年7月23日
许可协议