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等算法

中频面试题:※※※※

#我的实习求职记录##我的求职思考#
八股文整理 文章被收录于专栏

研二狗的八股文整理

全部评论

相关推荐

点赞 7 评论
分享
牛客网
牛客企业服务