Redis
高频面试题:※※※※※※
一.Redis数据结构
1.Redis基本数据结构
(1)String 底层实现 SDS
(2)List 底层实现:快表QuickList(LinkedList+压缩链表ZipList)
(3)Set 底层实现 IntSet,Dict
(4)ZSet(有序集合) 底层实现 跳表SkipList,Dict哈希表
(5)Hash 底层实现 Dict哈希表
2.Redis底层数据结构介绍
(1)压缩链表ZipList
简介:特殊的双端链表,不是双端链表,但具有双端链表的性质。
entry结构:
previous_entry_length:前一节的长度
encoding记录content的数据类型以及长度
contents负责保存节点的数据
可以通过长度计算,获得当前节点的上一节点,下一节点的地址
连续更新问题:
简而言之:一个节点cur更新变大导致其下一个节点next的previous_entry_length增加,而previous_entry_length正好进位,使next的长度增加,又导致next的下一个节点的previous_entry_length增加产生连锁问题。
优点:不使用指针,节省了内存
缺点:申请的是连续空间,内存占用较多
存储大量数据时,会超过ZipList上限,所以需要切分
如何在多个ZipList之间建立联系->引出QuickList
(2)快表QuickList
QuickList就是一个LinkedList双向链表,但其中每个节点都是一个ZipList
(3)跳表SkipList
和传统链表的差异:每个节点包含score和ele值,按照score值升序排序,ele存储数据。
每个节点包含多个指针,指针跨度不同,最大允许32级指针,查询效率高(空间换时间)
查找过程:从最高级指针去找,如果最高级指针指向的节点的score>所需的score,降级查找,类似二分查找,时间复杂度logn
特点:增删改查效率和红黑树基本一致,实现更简单
二.Redis持久化方式
1.RDB持久化
将redis在内存中的数据以快照的形式写入磁盘。快照是redis某个时间点上的内存数据镜像,也就是redis数据库在某个时间点的备份
优点:快速,简单
缺点:快照时间点后的数据会丢失
2.AOF持久化
将redis执行的每个写命令,写入磁盘文件,每次redis执行一个写命令,就将该命令追加到AOF文件的末尾,类似MySQL的redolog日志。是一个环形文件。
优点:数据安全性高
缺点:消耗更多磁盘空间和写入性能
文件体积大,回复速度慢
3.两者相结合
在AOF文件中,前半段记录RDB快照数据,重写过程中,如果再有命令执行,以AOF格式追加在数据后
三. Redis线程问题
1.Redis单线程怎么理解
Redis程序是多线程的,但其中处理命令是单线程的。
为什么使用单线程:Redis是内存操作,速度很快,性能瓶颈通常是网络延迟和内存大小,所以业务模块使用多线程不会带来性能提升。
2.Redis单线程为什么快
Redis是基于内存的。
单线程没有线程切换开销
数据结构高效
四. Redis集群问题
五. Redis缓存问题
1.缓存穿透
定义:请求的数据在缓存和数据库中都不存在,缓存永远不会生效,请求直接到数据库。
解决方法:布隆过滤器,缓存空对象并设置ttl
2.缓存雪崩
定义:同一时间大量的key失效或者Redis服务宕机,导致大量请求到达数据库。
解决方法:对同时失效:给不同的key增加随机过期时间
对Redis宕机:利用Redis集群或使用多级缓存
3.缓存击穿(热点Key问题)
一个高并发访问的Key失效,大量请求直接到达数据库
解决:使用逻辑过期:不设置ttl,存储时增加一个逻辑过期时间
使用锁(不推荐,影响吞吐量)
4.BigKey问题
产生原因程序设计不当,比如直接使用 String 类型存储较大的文件对应的二进制数据。
对于业务的数据规模考虑不周到,比如使用集合类型的时候没有考虑到数据量的快速增长。
未及时清理垃圾数据,比如哈希中冗余了大量的无用键值对。
5.Redis如何保证缓存和数据库双写时的一致性
首先在更新数据库时,不要同时更新缓存,因为在并发情景下,会将脏数据刷到缓存。
对于数据更新,将缓存删除
延时双删法:先删除缓存,再修改数据库,间隔一段时间后,再删除缓存。
这个间隔时间,就是其他线程拿到脏数据后,更新到缓存中的时间。第二次删除就是为了删除这些脏数据
会造成短期不一致,但不会增加系统复杂度和影响性能
五. 过期键删除策略
定时删除:类似守护线程,每过一段时间就检查过期字典,从中间选择一部分删除
惰性删除:惰性删除即当查询某个Key时,判断该key是否已过期,如果已过期则从缓存中删除,同时返回空。
六. Redis内存淘汰策略
超过最大内存后,Redis清理内存的策略
主要分为针对所有key和针对过期key两种,对应着LRU,LFU,RANDOM等算法
中频面试题:※※※※
#我的实习求职记录##我的求职思考#研二狗的八股文整理