导读
- redis的工作模型和常用数据结构
- redis的持久化及数据淘汰机制
- redis的应用场景及应对措施
- 分布式锁
- 缓存穿透、缓存击穿和缓存雪崩
- redis的性能瓶颈
redis工作模型
redis的特点:
- 单线程
- 高并发
- 高性能
- 支持分布式锁
单线程
-
多线程的优缺点:
- 优点:提高cpu的利用率
- 缺点:需要额外的管理开销,需要复杂的同步机制,避免死锁等等。
-
单线程的优缺点:
- 没有线程切换的消耗
- 实现并发处理,有点复杂
-
redis为什么要使用单线程?
- 没有线程上下文切换的消耗
- redis在内存中工作,性能比较好,无需多线程
- redis依赖多路复用,实现了并发处理
底层数据结构
-
redis底层的数据类型
-
字符串
- 简单动态字符串
- free:可以知道缓存区还有多少剩余空间,可以将惰性空间释放
- len:做字符串间隔,不需要用指定的字符来间隔,并且可以直接获取字符串长度,不需要遍历
-
链表
-
哈希
- table:指向桶
- size:元素的个数
- sizemask:hash计算掩码
- rehash的过程:
- 按照ht[0]的大小给h[1]分配空间
- 将ht[0]的元素rehash计算放入ht[1]中
- ht[0]放完之后,释放ht[0]
- 将原ht[0]指向ht[1]
- 渐进式rehash
- 按照ht[0]的大小给h[1]分配空间
- 维持一个rehashIndex,记录迁移状态
- 每次增删改查都对ht[0]和ht[1]操作,将ht[0]删除,rehashIndex++
- 当迁移完成之后,将ht[0]释放,并rehashIndex置未-1
-
集合
- 无序
- 不重复
- 整数集合:当这个集合内只有整数的时候,redis会自动选择使用整数集合
-
有序集合 sortSet
-
-
redis的工作模型
了解redis的单线程模型工作原理?一篇文章就够了
多路复用模型+事件处理器 -
redis的应用场景
Redis在互联网公司一般有以下应用:
String:缓存、限流、计数器、分布式锁、分布式Session
Hash:存储用户信息、用户主页访问量、组合查询
List:微博关注人时间轴列表、简单队列
Set:赞、踩、标签、好友关系
Zset:排行榜
持久化
- redis持久化
- RDB:数据快照模式(save、bgsave、自定义)
- 优点:
- 简单、恢复快
- 不影响性能(bgsave)
- 缺点:
- 在fork的之后,如果有变更,会丢失
- 实现比较重,只有数据的最终状态
- 优点:
- AOF:增量日志模式(always、second、自定义)
- 优点:
- 安全,可以根据不同配置,保证较小区间的数据丢失
- 轻量、灵活
- 缺点:
- rewrite可能会影响系统性能
- 恢复慢
- 优点:
- RDB:数据快照模式(save、bgsave、自定义)
缓存淘汰
- redis过期策略和内存淘汰
-
- redis采用定时删除+惰性删除,缺点是如果一些key始终没有被操作,那会一直存在于内存中。这时就需要内存淘汰机制。
- redis的定时删除
Redis 默认会每秒进行 10 次(redis.conf 中通过 hz 配置)过期扫描,扫描并不是遍历过期字典中的所有键,而是采用了如下方法:
从过期字典中随机取出 20 个键
删除这 20 个键中过期的键
如果过期键的比例超过 25% ,重复步骤 1 和 2为了保证扫描不会出现循环过度,导致线程卡死现象,还增加了扫描时间的上限,默认是 25 毫秒(即默认在慢模式下,如果是快模式,扫描上限是 1 毫秒)
-
内存淘汰机制
- LRU算法:Redis 缓存淘汰算法------LRU算法
- LFU算法
-
redis集群
-
redis分布式集群的常见形式
主从模式
哨兵模式
集群模式 -
Redis的多路复用
-
集群模式下key是怎么寻址的
-
分布式寻址都有哪些算法
-
一致性hash算法如何动态的增加和删除一个节点
常见问题
-
缓存穿透、缓存击穿、缓存雪崩
- 缓存穿透
- 查询了不存在的数据,每次都会透过redis,查询db
- 解决方法:布隆过滤器、当返回结果为空,也进行缓存。
- 缓存雪崩
- 大量key在同一时刻过期,导致db压力暴增。
- 解决方法:
- 可以设置一个随机范围的过期时间
- 互斥锁更新
- 缓存击穿
- 单个key过期时,正好有大量调用,请求直接打到db上。
- 解决方法:
- 互斥锁更新
- 设置永不失效(不推荐)
- 无论结果是否存在都返回,不存在则起异步线程去获取
- 缓存穿透
-
redis性能为什么高?
- 设计巧妙的数据结构
- 多路复用模型
- 事件机制
-
有海量key和value都比较小的数据,在redis中如何存储才更省内存?
首先这是一个hash结构的数据,在redis中hash结构的数据通常是有两种结构保存。- 压缩列表
- hashtable
从更省内存的角度来看,应该选择压缩列表,这种场景,可以将key映射到不同的map里,因为key和value都很小,这样就可以使用压缩列表的数据结构保存数据。
(事实上,redis在创建数据的时候,会自我判断使用哪种数据结构。) -
如何保证redis和DB中的数据一致性?
-
如何用redis实现分布式锁?
-
压测产生的垃圾数据该怎么清理
- db,用影子表
- redis,key带上后缀,标志
- 常见缓存问题解决方案
- redis事务
- redis的CAS方案
- redis的pipeline
- redis的主从复制原理
- 百亿级key存储方案
- 如何保证redis和数据库的一致性
- redis和membercache的区别,为什么单线程的redis性能要比多线程的membercache要高
- redis的并发竞争实质是什么?如何解决
- redis的性能瓶颈
Redis 常见的性能问题和解决方法
Redis 的性能幻想与残酷现实
延伸
- redis中hash的扩容与缩容与java的hashmap方法的比较?
- 有序链表的实现
- redis中的跳跃表与hashmap的红黑树
网友评论