Redis 集群
- redis 主从复制以及哨兵,可以提高读的并发,但单个 master 容量有限,数据达到一定程度会有瓶颈,这个时候可以通过水平扩展为多 master-slave 成为集群
- redis-cluster:可以支撑多个 master-slave,支持海量数据,实现高可用与高并发
- 哨兵模式也是一种集群,能够提高读请求的并发,但容错方面可能会有一些问题,比如:master 同步数据给 slave,是异步复制,如果 master 宕机,slave 上的数据就没有 master 新,数据同步需要时间,1-2 秒的数据会丢失,master 恢复并转换成 slave 后,新数据则丢失
集群特点
- 每个节点知道彼此之间的关系,知道自己的角色,知道在一个集群环境中,相互之间可以交互和通信,比如 ping pong,这些关系都会存储到配置文件中,每个节点都有
- 客户端要和集群建立连接的话,只需要和其中一个建立关系
- 某个节点宕机,通过超半数的节点进行检测,客观下线后主从切换,类似哨兵机制
- redis 中存在很多的插槽,又可以称之为槽节点,用于存储数据
集群容错
- 构建 redis 集群,一般需要 3 个节点作为 master,组成一个高可用的集群,每个 master 配备一个 slave,整个集群需要 6 个节点,这是最经典的 redis 集群,称之为三主三从,容错性更佳
搭建集群
- 开启集群模式
cluster-enabled yes - 每一个节点需要有一个配置文件,每个节点处于集群的角色都需要告知其他所有节点,彼此知道,这个文件用于存储集群模式下的集群状态等信息,文件由 redis 维护
cluster-config-file redis-cluster-noden.conf - 超时时间,超时则认为 master 宕机,随后主备切换
cluster-node-timeout 5000 - 开启AOF
appendonly yes - redis3.x 版本构建集群
使用 redis-trib.rb 来构建集群,最新版使用 C 语言来构建 - 新版的 redis 构建方式
创建集群,主节点和从节点比例为 1,1-3 为主,4-6 为从,1 和 4,2 和 5,3 和 6 分别对应为主从关系,最经典用的最多的集群模式
redis-cli --cluster create ip1:port1 ip2:port2 ip3:port3 ip4:port4 ip5:port5 ip6:port6 --cluster-replicas 1 - 检查 redis 集群信息
redis-cli --cluster check masterip:masterport
集群内部通信
- 在 redis cluster 架构下,每个 redis 要放开两个端口号,比如一个是 6379,另外一个就是加 1w 的端口号,比如 16379
- 16379 端口号用来节点间通信,也就是 cluster bus 的东西,cluster bus 的通信,用来进行故障检测、配置更新、故障转移授权
- 集群元数据的维护有两种方式:集中式、Gossip 协议(redis cluster 采用)
- 集中式:将集群元数据(节点信息、故障等等)集中存储在某个节点上
- 优点:元数据的读取和更新,时效性非常好,一旦元数据出现了变更,就立即更新到集中式的存储中,其它节点读取的时候就可以感知到
- 缺点:所有的元数据的更新压力全部集中在一个地方,可能会导致元数据的存储有压力
- Gossip 协议:所有节点都持有一份元数据,不同的节点如果出现了元数据的变更,就不断将元数据发送给其它的节点,让其它节点也进行元数据的变更
- 优点:元数据的更新比较分散,不是集中在一个地方,更新请求会陆陆续续打到所有节点上去更新,降低了压力
- 缺点:元数据的更新有延时,可能导致集群中的一些操作会有一些滞后
- 集中式:将集群元数据(节点信息、故障等等)集中存储在某个节点上
redis cluster hash slots
- 一个 redis 集群包含 16384 个插槽(hash slot), 数据库中的每个键都属于这 16384 个插槽的其中一个,集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽
- 举个例子, 如果集群有三个主节点, 其中:
节点 A 负责处理 0 号至 5500 号插槽
节点 B 负责处理 5501 号至 11000 号插槽
节点 C 负责处理 11001 号至 16383 号插槽 - redis-cli 每次录入、查询键值,redis 都会计算出该 key 应该送往的插槽,如果不是该客户端对应服务器的插槽,redis 会报错,并告知应前往的 redis 实例地址和端口
- redis-cli 客户端提供 –c 参数实现自动重定向,如 redis-cli -c –p 6379 登入后,再录入、查询键值对可以自动重定向,不在一个 slot 下的键值,不能使用 mget、mset 等多键操作,可以通过 {} 来定义组的概念,从而使 key 中 {} 内相同内容的键值对放到一个 slot 中去
分布式寻址算法
- hash 算法(大量缓存重建)
- 一致性 hash 算法(自动缓存迁移) + 虚拟节点(自动负载均衡)
- redis cluster 的 hash slot 算法