哨兵模式
集群监控:负责监控 redis master 和 slave
消息通知:如果某个 redis 实例有故障,通知给管理员。
故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
判断一个 master node 是否宕机了,大部分的哨兵都同意,分布式选举
配置中心:故障转移,通知 client 客户端新的 master 地址。
核心知识
至少需要 3 个实例
哨兵 + redis 主从的部署架构,是不保证数据零丢失的,只能保证高可用性。
Cluster 方案(服务端路由查询)
分布式寻址算法
hash 算法(大量缓存重建)
一致性 hash 算法(自动缓存迁移)+ 虚拟节点(自动负载均衡解决数据倾斜问题)
redis cluster 的 hash slot哈希槽 算法 16384
主从架构
每份数据分片会存储在多个互为主从的多节点
多个节点间的数据不保持一致性
先写主节点,再同步到从节点(支持配置为阻塞同步)
当客户端操作的key没有分配在该节点上时,redis会返回转向指令,指向正确的节点
扩容时时需要需要把旧节点的数据迁移一部分到新节点
优点
支持动态扩容
具备Sentinel的监控和自动Failover(故障转移)能力
免去了proxy代理的损耗
连接集群中任何一个可用节点
基于客户端分配
采用哈希算法将Redis数据的key进行散列,通过hash函数,特定的key会映射到特定的Redis节点上
Redis实例彼此独立,相互无关联
不支持动态增删节点,每个客户端都需要更新调整
连接不能共享,当应用规模增大时,资源浪费制约优化
基于代理服务器分片
请求到一个代理组件,代理解析客户端的数据,并将请求转发至正确的节点
切换成本低
代理层多了一次转发,性能有所损耗
主从架构
一主多从,主负责写,并且将数据复制到其它的 slave 节点,从节点负责读。所有的读请求全部走从节点。支撑读高并发。
redis replication -> 主从架构 -> 读写分离 -> 水平扩容支撑读高并发
核心机制
异步方式复制
发送一个 PSYNC
full resynchronization 全量复制,master 会启动一个后台线程,开始生成一份 RDB 快照文件
将这个 RDB 发送给 slave,slave 会先写入本地磁盘,然后再从本地磁盘加载到内存中
master 会将内存中缓存的写命令发送到 slave
必须开启 master node 的持久化
在 master 宕机重启的时候数据是空的,然后可能一经过复制, slave node 的数据也丢了
从备份中挑选一份 rdb 去恢复 master,这样才能确保启动的时候,是有数据的
lave node 可以自动接管 master node,但也可能 sentinel 还没检测到 master failure,master node 就自动重启了,还是可能导致上面所有的 slave node 数据被清空
分区缺点
涉及多个key的操作通常不会被支持
不能对两个集合求交集
被存储到不同的Redis实例
同时操作多个key,则不能使用Redis事务.
数据处理会非常复杂
必须从不同的Redis实例和主机同时收集RDB / AOF文件
动态扩容或缩容可能非常复
Redis集群在运行时增加或者删除Redis节点,能做到最大程度对用户透明地数据再平衡,但其他一些客户端分区或者代理分区方法则不支持这种特性。
分布式锁
SETNX SET if Not eXists
当且仅当 key 不存在,将 key 的值设为 value。给定的 key 已经存在,则 SETNX 不做任何动作
解决 Redis 的并发竞争 Key
分布式锁(zookeeper 和 redis 都可以实现分布式锁)
每个客户端对某个方法加锁时,在zookeeper上的与该方法对应的指定节点的目录下,生成一个唯一的瞬时有序节点。
判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。 当释放锁的时候,只需将这个瞬时节点删除即可。
同时,其可以避免服务宕机导致的锁无法释放,而产生的死锁问题。完成业务流程后,删除对应的子节点释放锁。
Redlock
互斥访问,即永远只有一个 client 能拿到锁
最终 client 都可能拿到锁,不会出现死锁的情况
只要大部分 Redis 节点存活就可以正常提供服务