Redis热点知识回顾
redis为什么效率高
数据存取单线程,无线程上下文切换;纯内存数据,没有磁盘IO;数据结构简单,充分发挥CPU性能。
redis的有序列表实现
压缩列表(ziplist),跳表(skiplist)
跳表的实现:
详细原理:https://lotabout.me/2018/skip-list/
每次新增节点,节点层数每增加一层的概率为P(0.25),每个节点的最大层数记为MaxLevel(32)
跳表节点的平均层数为:1/(1-P)
平均查找长度约为:C(log1/pn-1)=(log(1/p^(n-1))/p,平均时间复杂度为:O(log n),最坏的情况下,没有随机到任何高层索引,导致时间复杂度退化为O(n)
有点通过类似二叉搜索树的原理,每次插入时建立向后跳的索引,搜索时可快速跳过大量节点,减少操作次数。
Redis 为什么用跳表而不用平衡树
- 跳表最底层是一个链表,可以很方便地做范围查询。而平衡树则需要做中序遍历。
- 跳表插入元素只需要修改前后节点的指针指向,而平衡树会触发子树的平衡性调整。
- 跳表的结构更扁平和直观,容易理解。
Redis缓存更新为什么要做缓存延迟双删
缓存更新策略:
- 先更新数据库,再更新缓存:A更新DB,B更新DB,B更新缓存,A更新缓存,缓存脏数据。
- 先删除缓存,再更新数据库:A删缓存,B查DB,B更新缓存,A更新数据库,缓存脏数据。
- 先更新数据库,再删除缓存:A更新DB,B查询缓存,A删除缓存,中间会有一段时间的旧缓存数据。另外,若在更新DB前,缓存超时自动失效,C查,然后在A删除后更新,也有脏数据问题。
- 为了防止3中缓存超时的情况发生,采用先删一次缓存的方式,然后再更新数据库,然后为了防止2的情况发生,再进行一次延迟删除缓存。
先更新缓存,再更新数据库:数据库更新失败,导致数据不一致。
Redis的对象内存分配
Redis 主从复制的过程
Slave连接上Master时,发送全量同步指令,Master通过bgsave生成快照,同时缓存这段时间内的写指令,当快照全部发给Slave之后,再将缓存的写指令发送过去。之后就只需要进行指令同步就可以了。
缓存雪崩:大量缓存数据同时过期或Redis故障,导致DB出现高并发。
解决大量缓存同时过期的策略:1.过期时间加随机值,分摊负载。2.添加互斥锁,保证同一时间只有一个请求来构建缓存。3. 双key策略,主Key设置过期时间,备key不设置,更新时同时需要同时更新。
Redis宕机:一般是采用服务熔断,就是直接返回错误,暂停访问等待恢复,主要是保护数据库的正常访问;或者采取服务限流,通过令牌桶,限制流量速率,防止过量请求。
缓存击穿:部分热点数据缓存过期,导致DB高并发。
缓存穿透:访问的数据既不在缓存,也不在数据库。
通过缓存空值或默认值;或者使用布隆过滤器过滤来处理。
Redis 大量key过期如何清理?
惰性删除:发生访问时检查是否过期,过期则删除,否则不处理。会导致内存占用
定期全删除:定时对所有过期的key执行删除操作,可能会导致CUP高,影响吞吐量和响应时间。
定期部分删除:定期扫描过期的key,每次只清除一部分过期的key。是两种方案的折中。
Redis 内存满了数据如何处理?
redis.conf
文件中,配置的maxmemory
的大小参数限制了redis可使用的最大内存空间。
Redis默认的策略是,新申请内存的指令直接返回错误信息,也就是不进行内存置换。
可以通过配置修改内存置换策略:一般使用allkeys-LRU,对所有的key都使用最近最久未使用的算法淘汰。
可选择的策略:
- 对所有的key执行 LRU 或 LFU 或 RANDOM 淘汰策略。
- 进队配置了 expire 过期时间字段的key执行 LRU 或 LFT 或 RANDOM 淘汰策略。
allkeys-LRU
allkeys-LFU
volatile-LRU
volatile-LFU
volatile-ttl
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 using1174@foxmail.com
文章标题: Redis热点知识回顾
文章字数: 1,191
本文作者: Jun
发布时间: 2022-03-14, 15:41:00
最后更新: 2022-05-06, 23:36:31
原始链接: http://yoursite.com/2022/03/14/Redis热点知识回顾/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。