线程模型
单线程为什么还这么快?
-
单线程指的是网络IO,SET,GET等命令是单线程。持久化、集群同步是由另外的线程完成。
-
大部分的操作在内存中完成。高效的数据结构(跳表等)
-
单线程避免了上线文的切换。
-
多路复用IO
-
4.0之后添加了多线程的异步删除。
-
6.0之后添加了IO读写并发能力。
高可用
数据不丢失?持久化
-
AOF
-
RDB:生成快照:bgsave/save
-
4.0之后添加了先以RDB写入,然后把后续命令以AOF方式写入。
集群模式
主从+哨兵
数据丢失:
-
脑裂
-
主从复制
数据丢失解决办法:
-
保证数据最少同步到一个cluster算写入成功
-
如果10S没有复制到cluster完成,则master拒绝写请求。
原理:redis的sub/pub,每个哨兵都向redis的chanel里面发送消息
RedisCluster
-
hash槽的分配:创建cluster的时候平均分配,总数为16384个槽
-
手动分配:cluster meet命令手动分配
雪崩
导致redis服务挂掉
解决办法:
-
事前:redis高可用;缓存的失效时间随机打散,避免在一个时间点全部失效。
-
事中:添加二级缓存
-
事后:从磁盘恢复。
穿透
- 大量请求在redis中没有找到,落到了数据库上。
解决办法:
- key set null
随机key攻击redis:
- 布隆过滤器解决
热key
-
解释:突然有大量的请求访问某个特定的key,造成流量过于集中,到达物理网卡的上限,导致redis服务器挂了,然后直接打到数据库上。
-
解决:二级缓存,找到热key,加载到多台redis上。
缓存并发
-
解释:并发请求某个特定的key,但是这个key在redis中不存在,都要做这个操作:去数据库查找并且更新到redis中。
-
解决:如果redis中不存在,使用setnx给key加锁。如果加锁成功,则从数据库获取到数据后写入redis;如果加锁失败,则休眠N秒后继续从redis中请求。
Redis缓存清理策略
- 解释:当缓存达到Redis设置的内存大小时,会清理掉部分数据。默认策略为LRU(将最近最少使用的清除)
Redis过期策略:
-
定时删除:在SET的时候生成一个定时器,用于处理过期。占用资源多。
-
定期删除:在SET的时候,将需要过期的KEY单独存放到了一个字典里面。每隔100ms随机去N个Key执行过期处理;如果1/4的key过时,则循环执行下一次。采用贪心策略
-
惰性删除,在GET的时候去判断是否过期
-
默认采用定期过期+惰性过期