缓存雪崩
缓存同一时间大面积失效(缓存服务器重启/缓存数据失效),后续请求直接打到数据库上,造成数据库短时间内承受大量请求而崩溃
解决办法
- 缓存数据的过期时间设置随机,防止同一时间大量数据过期
- 缓存预热,把热点数据预先写到缓存里
- 给每个缓存增加相应的缓存标记记录缓存是否失效,缺点是会增加系统消耗
- 互斥锁,对同一个缓存键上锁
缓存穿透
缓存和数据库中都没有的数据,每次请求都会打到数据库上
解决办法
- 在接口层增加校验
- 对于缓存和数据库中都没有的数据,可以将请求的键值设置为null,这样可以防止对同一个键值的重复请求
- 布隆过滤器
缓存击穿
缓存中没有(一般是缓存时间过期),数据库中有
解决办法
- 设置热点数据永不过期
- 加互斥锁,访问的缓存键加锁这样访问数据库只有一个请求,其他请求都在排队,可以减少请求打到数据库上的数量
setnx 和 set 的区别
setnx将key的值设定为value,当且仅当key不存在;若给定的key已存在,则setnx不做任何动作
redis的过期键删除策略
- 惰性过期:只有当访问key时才会判断该key是否过期,过期则清除,能大量节省cpu,对内存不友好
- 定期过期:每隔一定时间会扫描一定数量的expires字典中的key,并且清除过期的key,消耗cpu,对内存友好。
调优: 可以调整扫描时间间隔和每次扫描限定耗时
redis线程模型
- 纯内存操作
- IO多路复用
- 单线程避免了多线程的频繁上下文切换带来的性能问题
- 存储数据结构(全局哈希表)
- string类型:redis存储键值对的时候会先把值转换成整型,如果能转那么这个键就是整型
- hash结构:hset
- 列表list结构:
- lpush key value 从左边
- rpush key value 从右边
- set集合结构:
- SADD key { 集合 }
- SPOP key count
- 有序集合zset
- 跳表:有序单链表+索引,便利变成二分查找O(logN),空间换时间。将有序链表改造为支持二分查找,可以快速的插入、删除、查找操作。元素越多(超过128),zset自动调整为调表存储结构
redis事务实现
A:原子性,没有回滚机制
C: 一致性
I: 持久性
D: 隔离性,单线程
- 事务开始:multi命令会将客户端状态的flag属性中打开REDIS_MUTIL标识
- 命令入队:命令放到队列中并检查命令语法是否正确(redis只会检查语法是否正确不会对具体的操作命令做检查,如果操作出错不会回滚),等到客户端发送EXEC命令,执行事务
- 事务执行:客户端发送EXEC命令。遍历事务队列然后执行
WATCH:乐观锁
MUTIL:用于开启一个事务
EXEC:执行事务内的命令
DISCARD:客户端可以清空事务队列,并放弃执行事务,客户端从事务状态中退出
UNWATCH:取消watch对所有key的监控
redis集群方案
- 主从
- 哨兵模式:高可用,分布式。通常需要三个哨兵实例,保证集群健壮性。不保证数据零丢失,只保证高可用
- redis cluster(服务端分片)
- 通过哈希将数据分片,每个节点均分存储一定哈希槽(哈希值)区间的数据,默认分配了16384个槽位
- 互为主从,不保持强一致性。
- 需开放两个端口号,一个6379,另一个默认加10000的端口。6379用来数据访问,16379用来节点之间通讯。
- 无中心架构,支持动态扩容
- redis sharding(客户端分片)
- 每个redis实例像单服务实例,非常容易线性扩展
redis主从复制核心原理
- 全量复制:
- 主节点通过bgsave命令fork子进程进行RDB持久化,该过程非常消耗CPU,内存(页表复制),硬盘IO
- 主节点通过网络讲RDB文件发送给从节点,这对主节点的带宽有很大的消耗
- 从节点清空老数据,载入新的RDB文件的过程是阻塞的,无法响应客户端的命令,如果从节点执行bgrewriteaof也会带来额外的消耗
- 部分复制:
- 复制偏移量,执行复制的双方主从节点,分别会维护一个复制偏移量offset
- 复制积压缓冲区:主节点内部维护了一个固定的长度队列作为复制积压缓冲区,当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制只能执行全量复制
- 服务器运行ID(runid):每个redis节点都有运行ID,主节点将自己的运行ID发送给从节点,从节点讲主节点的运行ID存起来,从节点根据运行ID来判断同步的进度
- 如果从节点保存的runid和主节点的runid相同,说明之前主从同步过,主节点会继续尝试使用部分复制
- 如果从节点保存的runid和主节点的runid不同,说明节点在断线前同步的redis节点不是当前的主节点,只能进行全量复制
过程如下
CAP理论
C(Consistency) 一致性
所有节点在同一时间的数据完全一致
对于客户端,并发访问时获取到的数据保持一致
对于服务端,将更新复制分布到整个系统保持数据最终一致A(Availability):可用性
服务一直可用并且正常响应时间P(Partition Tolerance):分区容错性
分布式系统在遇到某个节点或网络故障,任能对外提供满足一致性和可用性的服务
CP和AP:当网络发生分区,如果要继续服务,那么一致性和可用性只能二选一,但是必须保证分区容错性
BASE理论
对于CAP理论一致性和可用性平衡的结果
- 基本可用
- 响应时间上:正常0.5s;异常3s
- 系统功能上:正常全部功能可用;异常部分功能可用
- 软状态:数据同步允许一定的延迟
- 最终一致性:系统所有数据副本在一段时间的同步后最终达到一致性,不要求实时