redis如何实现高可用?
持久化、复制、哨兵、集群
- 持久化:落盘,进程退出不会丢失数据
- 复制:数据备份
- 哨兵:故障自动恢复
- 集群:扩展单机存储能力
1.1 哨兵
故障转移流程:
- 哨兵sentinel节点定时心跳检测redis节点
- redis节点回复超时,
主观下线 - 主观下线后,询问其他sentinel节点,超过一定数量n后
客观下线(redis-master节点才有客观下线和故障转移等,n的值通过配置设置) - sentinel节点
选领导者(raft算法) 故障转移:选主、更新主从状态(修改配置文件等)- 通知switch-master事件订阅者(订阅者感知到switch-master事件后,重新读取sentinel节点sentinel master配置,切换到新的连接) 笔记:
- 哨兵节点奇数个,部署到不通物理机(IDC)
待扩展:raft协议
1.2 proxy
1. twemproxy
简单分片代理,无法在线扩容、缩容
2. codis集群架构
codis-fe:运维管理后台codis-dashboard:Codis的集群管理工具,配置中心,整个集群的操作和管理都需要经过dashboard,dashboard中存有集群状态(redis、proxy、slot等状态)
- 创建zk/etcd/fs客户端
- 初始化Topom结构体(存储到zk等,包括存储系统配置信息、group、slot、sentinel配置信息等)
- 清理redis过期连接(每台redis服务器都会有多个连接,过期的连接会被删除)
- 注册API路由(注册group、slot、sentinel等API操作)
- 启动4个协程:1、刷新redis状态、主备关系;2、刷新proxy状态;3、同步操作,一个group中主从数据同步;4、处理slot操作
codis-proxy: 启动流程:
- 创建、填充slot槽 slot:redis-conn
- jodis在zk中创建临时节点,并监听proxy变化(客户端监听proxy的变化) 接收消息:
codis-group: 虚拟节点 (redis-master + redis-slave)storage: 配置存储 zk|etcd|fsredis-sentinel: 哨兵 codis扩容流程- 新增redis实例并启动(master+slave)
- dash-board 增加group
- 槽分配,2种方式:auto-rebalance:自动分配1024个槽 | migrage slot:手动分配
流程
| 同步迁移 | 异步迁移 | |
|---|---|---|
| 请求处理 | 针对某个key进行修改,将这个key迁移完成才能处理请求 | 异步则是将当前请求封装成一次SLOTSMGRT-EXEC-WRAPPER调用,并且将操作命令及参数都发送过去,后者会判断这个key是否在迁移或阻塞,如果是并且当前为写命令则直接返回失败,由Proxy重试 |
| 迁移逻辑 | 每次随机迁移一个key | 小key需要确认才算迁移完成,对于大key还会分拆成多条命令,以保证不阻塞主流程,并且在拆分后的命令都加上TTL,以保证如果中途失败目标Redis的key会及时清掉而不会产生脏数据 |
待扩展:zab协议
1.3 cluster
cluster是redis官方集群方案,节点通信采用gossip协议。 路由:key-槽(16384)-redis节点,双层路由
优点
- 去中心架构
- 自动故障转移
缺点
- 客户端相对复杂
- 最终一致性
- 不支持读写分离;从库为冷备
待扩展:gossip协议