单机,单节点,单实例带来的问题
- 单点故障
- 容量有限
- 访问压力
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 都要参与运算
规则是一个哈希环(虚拟节点,物理节点)
虚拟节点:解决数据倾斜优点:加节点可以分担其他节点的压力,不会造成全局洗牌
缺点:新增节点会造成一小部分数据不能命中
- 问题:击穿,压到数据库
- 方案:设法取理我最近的2个物理节点
- modula random kemata 更倾向于作为缓存,而不是数据库使用
- 数据分治——聚合操作很难实现
实现方案
- 客户端分区:在客户端已经决定数据会被存储到哪个redistribution 节点
- 代理分区:客户端将请求发送给代理,有代理决定写入哪个节点
- 查询路由分区:客户端随机地请求任意一个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直接传给slaverepl-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()->锁
- get key
- setnx key
- ok 去DB
- false,sleep->1
引出问题
- 如果第一个人挂了
可以设置多的过期时间
- 没挂,但是锁超时了
多线程
一个线程取DB
一个线程监控是否取回来,更新锁时间
3.2 穿透
出现原因
从业务接受查询的是系统根本不存在的数据
布隆过滤器/布谷鸟过滤器
client 自己包含算法
算法 bitMap -> redis 无状态
redis 集成bloom
3.3 雪崩
出现原因
大量的key同时失效,间接造成大量的访问到达DB
- 零点过期
强依赖击穿方案
业务层加判断零点延时
- 与时点无关
随机过期时间
3.4 分布式锁
- setnx
- 设置过期时间
- 多线程(守护线程) 延长过期
- redisson
- zookeeper 做分布式锁