Redis 集群架构
下面介绍一下我们的 Redis 集群架构 。集群里有三个组件:Server、Proxy 和 Configserver,分别完成不同的功能 。
- Server:存储数据的组件,即 Redis Server,其后端部署模型是一个多分片的模型 。分片之间的 Server Pod 没有通信,为 share-nothing 的架构 。分片内部为一主多从的模式,可以一主一从、一主两从,甚至更多 。
- Proxy:承接 client 发来的请求,同时根据读写拓扑,把请求转发给后端的 Server 分片 。
- Configserver:配置管理组件,本身是无状态的,所有的状态信息都存储在 etcd 。集群生命周期里 Server 所有的分片信息都保存在 Configserver 里 。Configserver 会对每一个分片的 Master 节点进行定期探活,如果发现某一个分片的 Master 节点不可用,就会执行 Failover,把分片内可用的 Slave 提成新的 Master,保证分片可继续对外提供服务 。同时,Configserver 也会定期根据 Failover 或其他一些实例信息的变更来更新自己的读写拓扑关系,保证 Proxy 可以从 Configserver 拉取新的正确的配置 。
文章插图
结合以上介绍的 Redis 架构以及 K8s 的特性,我们抽象了一个 Redis 集群在 K8s 集群上部署的基本形态:
- 使用 Deployment 将无状态的 Configserver 部署在 K8s 上 。因为 Configserver 可被所有 Redis 集群共用,为了简化运维复杂度,我们规定所有的 Redis 集群共用一个 Configserver 。
- Proxy 也是无状态的组件,也用 Deployment 来部署 。
- 因为我们有多分片,而且 Server 是有状态的,所以每一个分片用 StatefulSet 进行托管 。在新建集群时,我们默认分片内的 0 号 Pod 为 Master Pod,其余所有的 Pod 是 Slave 。这是一个初始状态,后续可能会跟随 Failover 或其他异常发生变更,但是 Configserver 里会实时记录最新的状态信息 。
Redis Server 启动的时候需要一些配置文件,里面涉及到一些用户名和密码,我们是用 Secret 来存储的 。在 Server Pod 运行的时候通过 volume 机制挂载到 Server Pod 内部 。
对于 Proxy,通过 HPA,基于 Proxy 的 CPU 利用率,支持 Proxy 服务的动态扩缩容 。
文章插图
放置策略
对于一个 Redis 集群涉及到的 Server 和 Proxy 组件,我们有一些放置策略的要求,比如:
- 同一个 Server 分片下的节点不能在同一台机器上,即,一个分片内的主从节点不能在同一台机器上 。转换成 K8s 里面的模型,即我们希望一个 StatefulSet 下所有的 Pod 部署在不同的机器上 。我们会利用 Pod-AntiAffinity 下面的 required 语义,来保证 StatefulSet 下所有的 Pod 都部署在不同的机器上 。
- 一个集群下的 Proxy Pod 需要尽可能分布在不同的机器上,可通过 Pod-AntiAffinity 下的 preferred 语义加上拓扑分布约束来满足 。preferred 语义只能保证 Pod 尽可能分布在不同的机器上,为了避免极端情况下所有 Pod 都在同一台机器上的情况,我们会使用拓扑分布约束 。
存储
存储使用的是 PVC 加 PV 再加上具有动态供给能力的 StorageClass 。使用 StorageClass 是为了抽象不同的存储后端,可支持本地磁盘和分布式存储 。可以通过 StorageClass 的配置直接申请对应的存储,不用了解具体后端的实现 。
另外,我们使用的是支持动态供给的 StorageClass,可自动按需创建不同大小的 PV 。如果使用静态供给,就无法提前预知所有 Redis 实例的规格,也无法把它们对应的指定数量的 PV 都创建出来 。
推荐阅读
- 一篇详解Redis -- 延时队列
- python 手把手教你基于搜索引擎实现文章查重
- 克柳切夫火山喷发 克柳切夫火山喷出6000米高灰柱
- 历史上火山最大的喷发 世界上最大的一次火山喷发
- 哪座火山爆发毁灭了古罗马的庞贝城 哪个火山摧毁了古罗马的庞贝城
- 哪个火山的爆发毁灭了古罗马帝国的庞贝城?
- 马达加斯加岛是火山岛吗 阿拉斯加湖泊的形成
- 开发人员如何快速定制化实现一个基于Solr的搜索引擎
- 网易考拉规则引擎平台架构设计与实践
- Redis集群的5种使用方式,及各自优缺点对比分析