摘要: 2018 数据库直播大讲堂峰会 Redis 专场, 来自阿里云技术专家夏周为大家介绍了阿里云 Redis 容灾体系本文主要分单机房主备容灾同城双机房容灾和异地多机房容灾 & 多活三部分进行讲解, 其中包括它们的产品定位架构介绍以及同步优化和内核优化等
2018 数据库直播大讲堂峰会 Redis 专场, 来自阿里云技术专家夏周为大家介绍了阿里云 Redis 容灾体系本文主要分单机房主备容灾同城双机房容灾和异地多机房容灾 & 多活三部分进行讲解, 其中包括它们的产品定位架构介绍以及同步优化和内核优化等
以下为精彩视频内容整理:
单机房主备容灾
阿里云 Redis 双副本容灾形态
阿里云 Redis 推出了 4.0 版本, 架构上有集群版标准版和读写分离版标准版是主备版本, 提供最好的 Redis 命令兼容性, 当主节点出现宕机时, HA 高可用切换模块会去做故障迁移, 将 Slave 提升为 Master, 原来的 Master 恢复后作为新的 Slave; 集群版架构相对复杂, 后端有多个 DB 节点, 每个 DB 节点架构类似于标准版主备形态, 多个 DB 节点数据需要做路由, 就需要多个 Proxy 节点, 集群版还增加一个 Configserver, 该角色保存了集群间元素信息当某一个 DB 节点出现宕机, 都会有一个独立的切换模块, 并更新 Configserver 和 Proxy 的信息; 读写分离版只有一个 DB 节点, 一个 Master 上挂了多个只读节点, 当读流量进来时, 会根据 Proxy 判断后端只读节点数量做自动负载均衡, 当 Master 出现宕机时, 只读节点需要挂载到新的 Master 上
高可用 (HA) 架构
HA 本质上是在做 Master 故障时 Slave 自动提升为主, 解决关键问题是判断是否要做切换 HA 本身多机房部署, 保证自身是高可用的, 每个机房会有多个 HA 模块, 每个 HA 模块负责一部分节点 HA 切换, 当某一个工作 HA 节点宕机后, 另外一些 HA 节点会做争抢式调度我们优先同机房 HA 节点做探测, 对于后端 Redis 的探活逻辑也是有很多种策略的, 比如从 DNS VIP 层面探测后端服务的可用性, 也会探测本身 DB 节点是否存活, 以及主机磁盘是否完好
独立 HA 线程优化
阿里云 Redis 在运营过程中进行了优化, Redis 本身是单线程的, 当做 keyshgetall 等时, Redis 很容易出现假死情况, HA 可能会误切换主线程仍然可以做任何操作, 我们的优化是专门启动了一个状态线程监测主线程是否存活, 也会响应 HA 模块的探活请求, 并探测磁盘可用性另外, 状态线程也会吐出状态信息, 保证监控采集不会因为主线程 hang 住而采集不到信息
同城双机房容灾
同城双机房容灾的产品定位是: 对于业务单元化部署或本身就是单一地域的业务, 对容灾有需求, 主机房故障时, 流量能迅速切换到备机房, 主机房恢复时, 流量可以切回
目前 Redis 同城容灾架构如图下半部分是 Redis 本身的架构情况, 上半部分是底层传输网络情况购买 Redis 后, 我们可以取得域名和端口, 经过 DNS 解析走到骨干网, 流量再通过 LVS 集群流到 Proxy, 最后到后端 Master 节点当主机房出现掉电或网络不通时, Redis 会有一键切换程序, 备机房 Slave 提升为 Master, 并调用 Configserver 接口为 Proxy 推新的路由信息, 也会更新 MetaDB 的一些信息; 底层网络走大小段路由方式, 优先选择更为细致的路由, 当主机房出现故障时, 就不会向主机房上传路由明细信息, 骨干网只有备机房大段路由信息, 这时就会自动把请求路由到备机房
同步优化 Log Based Replication
当主机房出现故障时流量切换到备机房, 当主机房恢复时都会从备机房做同步 Redis 最早提供全量同步机制, 整机房全量同步会带来灾难性后果, 如果所有的 Slave 都做全量同步, 子进程 CPU 会跑满, 还要疯狂的向恢复的主机房传输的 RDB 写流量, 由于流量太大可能导致备机房服务不可用
我们目前提供的同步机制对 Redis 持久化机制做了改造, 会有 slipshot 对应日志位点, AOFbinlog 不断做最佳写, 当 AOFbinlog 堆积到一定程度, 需要重新做 slipshot 对其进行清理 AOFbinlog 每一个操作写命令会增加一些元数据信息 Opid, 我们给每一个操作增加一个全局唯一的 ID, 当 Slave 出现同步中断时, 会通知 Master 同步 Opid 位点信息, 此时位点已经不是 offset 信息, Master 会判断此 Opid 是否在 AOFbinlog 中保存, 如果在即异步发送 AOFbinlog 给 Slave,Slave 不断从 Master 本地磁盘读缺失增量, 当追上 Master 同步时, 再去内存中把一部分增量拿过来
总结来看, 同步位点借鉴了 MySQL GTID, 实现全局 Opid; 性能保证上, 查找 Opid 位点信息是后台线程操作, 做到无锁, 发送 AOFbinlog 是异步同步, 可以去做限流; 同时, 我们做到向前向后兼容, 可以做平滑升级回滚
Slave 和 Master 的具体通信情况如图, 当 Slave 和 Master 出现同步中断时, Slave 给 Master 发送 PSYNCrunnidoffset 和 Opid 信息, Master 根据 offset 判断 backlog 是否能满足需求, 如果可以满足需求, 直接从 backlog 复制数据发给 Slave 即可, 如果不能满足需求, 就会通知 Slave 开始 AOF Psync,Master 首先会通过 Opid 找 AOFbinlog 中同步位点, 然后无锁通知主线程, 主线程异步发送 AOFbinlog, 当 Slave 追上 AOFbinlog 后, Master 还要同步 aof_buf&repl_offset 给 Slave
异地多机房容灾 & 多活
异地多机房容灾 & 多活的产品定位是: 业务对可用性要求极高, 如金融类部分民生类业务等; 允许 N-1 机房断电, 任一机房均能承担所有流量
异地多活架构如图, 上海中心和深圳中心都会有两个 Redis 集群, 可以做到互相同步底层链路有 BLS Manager, 上海中心生产一些增量数据, 通过 Collector 写入 BLS Tunnel, 深圳中心 Receiver 会从 BLS Tunnel 中消费增量数据, 并写入深圳 Master 集群, 这样, 上海中心数据就同步到深圳中心了同理, 深圳中心数据同步到上海中心也是如此 BLS Manager 会去做一些调度, 比如 Collector 和 Receiver 挂掉时, BLS Manager 负责拉起或创建新的 Collector 和 Receiver,BLS Manager 也会对 BLS Tunnel 做管理
内核优化
增量生产
获取增量接口是内核以命令方式原生支持的, 是一个标准化 get 接口, 支持现有开源 SDK, 支持增量过滤, 包括库级过滤和 key 模式匹配过滤 Collector 消费增量时, 会发送 opget opid 信息, 明确从哪一点开始获取 oplog,Redis 主线程会创建任务通知后台线程, 后台线程基于 Opid 查找增量位点, 无锁通知主线程可以从哪开始读, Redis 异步读取 AOFbinlog 并做解析和封装操作, 同时缓存客户端状态, 然后回复 Collector,Collector 下次发送 opget opid 命令时, 就不再需要走上述流程了
增量消费
增量格式本身兼容 Redis 协议, 目的端接收并且执行就可以了其中, timestamp 做时间点恢复增量消费要避免两个问题: 一是复制回源, 不能让 A 复制给 B 的再从 B 复制回 A, 我们会标识标识 oplog 来源实例(server_id), 如果复制回源, 直接丢弃即可; 一是环形复制, 如何避免 C 通过 B 复制的数据再次返回 A, 我们记录了每一个 src_server_id, 以及 src_server_id 在 C 上 max_opid 情况, 通过判断是否发生环形复制
来源: http://www.jianshu.com/p/ac8718f5aecd