Redis集群

595 阅读5分钟

单机,单节点,单实例带来的问题

  • 单点故障
  • 容量有限
  • 访问压力

1 集群方式——AKF

  • X:全量镜像
  • Y:业务,功能 拆分
  • Z:优先级,逻辑再次拆分

CAP

  • 一致性(Consistency):是指在同一时刻,分布式系统中的所有数据备份为相同值;
  • 可用性(Availability):指集群中的某一个节点故障宕机后,集群还能响应客户端请求。
  • 分区容忍性(Partition tolerance):当分布式系统中因为一些原因导致无法通信而分成多个分区,系统还能正常对外服务。

1.1 X

  • 主备:只能访问master
  • 主从:可以访问master 和 slave

引入问题

数据一致性

所有节点阻塞,直到数据全部一致(强一致性)

同步阻塞,有可能破坏可用性

弱一致性(redis)

容忍数据丢失一部分

最终一致性(zookeeper)

Master单点问题

对Master做HA 高可用

对检测Master单点问题程序做集群

集群中投票数量过半才算数——解决脑裂问题
一般集群使用基数台(基数台(2n+1)和偶数台(2(n+1))解决的问题是一样的,但是偶数台比基数台更容易出现故障)

存在问题

无法解决容量有限问题

1.2 Y

由于X 无法解决容量问题,所以需要业务,功能 拆分

拆分规则

  • 数据可以分类,交集不多,根据业务逻辑拆分
  • 数据没办法划分拆解,根据算法(hash+取模--modula)拆分

hash 取模弊端:取模的数是固定的,影响分布式下的扩展

  • 数据没办法划分拆解,random 随机拆分

使用场景:消息队列(list)

  • 数据没办法划分拆解,一致性哈希(kemata)

没有取模,key 和 node 都要参与运算
规则是一个哈希环(虚拟节点,物理节点)
虚拟节点:解决数据倾斜

优点:加节点可以分担其他节点的压力,不会造成全局洗牌
缺点:新增节点会造成一小部分数据不能命中

  1. 问题:击穿,压到数据库
  2. 方案:设法取理我最近的2个物理节点
  • modula random kemata 更倾向于作为缓存,而不是数据库使用
  • 数据分治——聚合操作很难实现

实现方案

  • 客户端分区:在客户端已经决定数据会被存储到哪个redistribution 节点
  • 代理分区:客户端将请求发送给代理,有代理决定写入哪个节点

Twemproxypredixy

  • 查询路由分区:客户端随机地请求任意一个redis实例,然后由Redis将请求转发给正确的Redis节点

cluster

Redis 分区缺点

  • 不可跨节点执行事务,集合操作
  • 分区时动态扩容或缩容可能非常复杂

2 Redis 集群

  • Redis做缓存,使用一致性哈希实现动态扩容缩容。
  • Redis做持久化存储,必须使用固定的keys-to-nodes映射关系,节点的数量一旦确定不能变化。

2.1 Master-Slave

主从复制配置

replicaof <masterip> <masterport>
replica-serve-stale-data yes

当从库同主机失去连接或者复制正在进行
replica-serve-stale-data yes 继续响应客户端的请求
replica-serve-stale-data no 除特定命令外都返回错误

replica-read-only yes

从库是否只读

repl-diskless-sync no

repl-diskless-sync no 使用disk方式同步数据,master新起进程把rdb文件存放到磁盘,再把磁盘的rdb传给slave
repl-diskless-sync yes 使用socket方式同步数据,master新起进程把rdb直接传给slave

repl-backlog-size 1mb

主从的增量复制 min-replicas-to-write 3 最少写几个写成功
min-replicas-max-lag 10

缺点

需要人工维护主的故障问题

2.2 Sentinel 哨兵

哨兵会通过发布订阅发现其他哨兵

哨兵任务

  • Monitoring: Sentinel会不断地检查Master和Slave是否运作正常。
  • Notification: 当被监控的某个Redis服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
  • Automatic failover: 当一个Master不能正常工作时, Sentinel 会开始一次自动故障迁移操作,选出新的Master

启动sentinel

redis-server /path/to/sentinel.conf --sentinel

配置信息

port **
sentinel monitor mymaster 127.0.0.1 6379 2

监控 mymaster ip(127.0.0.1) port(6379)
将这个主服务器判断为失效至少需要 2 个 Sentinel 同意

3 缓存常见问题

3.1 击穿

出现原因

redis 作为缓存, key过期清除掉了(LRU,LFU),此时发生高并发

阻止并发到达DB,redis 中没有key
解决方案 :setnx()->锁

  1. get key
  1. setnx key
  2. ok 去DB
  3. false,sleep->1

引出问题

  1. 如果第一个人挂了

可以设置多的过期时间

  1. 没挂,但是锁超时了

多线程
一个线程取DB
一个线程监控是否取回来,更新锁时间

3.2 穿透

出现原因

从业务接受查询的是系统根本不存在的数据

布隆过滤器/布谷鸟过滤器

client 自己包含算法
算法 bitMap -> redis 无状态
redis 集成bloom

3.3 雪崩

出现原因

大量的key同时失效,间接造成大量的访问到达DB

  1. 零点过期

强依赖击穿方案
业务层加判断零点延时

  1. 与时点无关

随机过期时间

3.4 分布式锁

  1. setnx
  2. 设置过期时间
  3. 多线程(守护线程) 延长过期
  4. redisson
  5. zookeeper 做分布式锁