Redis 相关面试题(下)

(1)redis的缓存失效策略和主键失效机制

作为缓存系统都要定期清理无效数据,就需要一个主键失效和淘汰策略.

在Redis当中,有生存期的key被称为volatile。在创建缓存时,要为给定的key设置生存期,当key过期的时候(生存期为0),它可能会被删除。

1.过期时间跟着key走,与值无关
在Redis中,带有过期时间的key被称为『易失的』(volatile)。 过期时间可以通过使用 DEL命令来删除整个key来移除,或者被 SET和 GETSET命令覆写(overwrite),这意味着,如果一个命令只是修改(alter)一个带过期时间的 key的值而不是用一个新的 key值来代替(replace)它的话,那么过期时间不会被改变。比如说,对一个 key执行 INCR命令,对一个列表进行 LPUSH命令,或者对一个哈希表执行 HSET命令,这类操作都不会修改 key本身的过期时间。

2.设置永久有效期
使用PERSIST命令可以清除超时,使其变成一个永久的key。

3.rename命令对有效期影响
如果key被RENAME命令修改,相关的超时时间会转移到新key上面。
如果key被RENAME命令修改,比如原来就存在Key_A,然后调用RENAME Key_B Key_A命令,这时不管原来Key_A是永久的还是设置为超时的,都会由Key_B的有效期状态覆盖。

4.刷新过期时间
对已经有过期时间的key执行EXPIRE操作,将会更新它的过期时间。
  
5.最大缓存配置
在 redis 中,允许用户设置最大使用内存大小server.maxmemory默认为0,没有指定最大缓存,如果有新的数据添加,超过最大内存,则会使redis崩溃,所以一定要设置。redis 内存数据集大小上升到一定大小的时候,就会实行数据淘汰策略。redis 提供 6种数据淘汰策略:

volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

no-enviction(驱逐):禁止驱逐数据
  注意这里的6种机制,volatile和allkeys规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的lru、ttl以及random是三种不同的淘汰策略,再加上一种no-enviction永不回收的策略。
  
  使用策略规则:
  1、如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问频率低,则使用allkeys-lru
  2、如果数据呈现平等分布,也就是所有的数据访问频率都相同,则使用allkeys-random
  三种数据淘汰策略:
  ttl和random比较容易理解,实现也会比较简单。主要是Lru最近最少使用淘汰策略,设计上会对key 按失效时间排序,然后取最先失效的key进行淘汰.

(2)Redis内部数据结构的实现

在Redis内部,有非常多的数据结构:sds(简单动态字符串),list,intset(整数集合),hash(字典),zskiplist(跳跃表),ziplist(压缩表)等。
1.simple dynamic string:一种简单动态字符串,而sdshdr封装了C原生字符串,并在其基础上,增加了一些功能,使之后对它的调用简单易懂可扩展。

sds 的具体实现结构adshdr,len表示sds的长度,alloc表示分配了的长度,这样方便扩展;free 空闲的长度;flags标志来判断使用哪个类型;buf[]则作为sds的真正储存数组。

2.list
Redis中,list的实现是一个双端链表,这样可以方便的获取其前后的节点值,方便之后对节点的查找;Redis通过list来对listNode进行持有,分别记录list的头尾节点list长度,可在O(n)的时间复杂度上进行查找;
这里写图片描述
list在Redis中运用相当广泛,除了实现列表外,发布和订阅、慢查询、监视器等功能也使用了链表来获取,另外,Redis服务器还使用链表来持有 多个客户端的状态信息,以及用链表来构建客户端输出缓冲区。

3.dict
dictEntry是最核心的字典结构的节点结构,它保存了key和value的内容;另外,next指针是为了解决hash冲突,字典结构的hash冲突解决方法是拉链法,对于hashcode重复的节点以链表的形式存储。

dictht是节点dictEntry的持有者,将dictEntry结构串起来,table就是hash表,其实dictEntry *table[]这样的书写方式更容易理解些,size就是table数组的长度,used标志已有节点的数目。

dict是最外层的字典结构的接口形式,type标志类型,privdata标志其私有数据,dict持有两个dictht结构,一个用来存储数据,一个用来在rehash时使用,rehashidx标志是否正在rehash(因为Redis中rehash是一个渐近的过程,正在rehash的时候rehashidx记录rehash的阶段,否则为-1。
这里写图片描述
注:因为dictEntry节点组成的链表没有子项链表尾部的指针,所以新加的节点一般都加在链表的头部,排在已有节点的前面,因为这样的时间复杂度为O(1)。

4.intset
当一个集合元素只有整数并且数量元素不多的时候,可以选择用整数集合来作为其底层实现。整数集合的数据结构如上所示。
重点说一下这个contents数组,它存储集合中的内容,并且以从小到大的顺序排列,并保证其没有重复的元素。虽然定义中其类型为int8_t,但具体编码方式还是取决于encoding。

当最大的数在相关范围之内是便会对应不同的数据类型,但是如果移除了这个最大取值,不会降级。int_6, int_32,int_64

分范围定义其类型有两个好处:提高其灵活性,节约内存。但是也增加了升级的开销。

在Redis 中,整数集合的应用范围不是很广,只在实现集合时用到。

5.zskiplist(跳跃表)
对于不了解跳跃表的可以去这个地方看看,了解一下:
http://blog.nosqlfan.com/html/3041.html
跳表是一种实现起来很简单,单层多指针的链表,它查找效率很高,堪比优化过的二叉平衡树,且比平衡树的实现,简单的多的多。

6.ziplist(压缩表)
ziplist是一个编码后的列表,是由一系列特殊编码的连续内存块组成的顺序型数据结构,特殊的设计使得内存操作非常有效率,此列表可以同时存放字符串和整数类型,列表可以在头尾各边支持推加和弹出操作在O(1)常量时间,但是,因为每次操作涉及到内存的重新分配释放,所以加大了操作的复杂性 。
zlentry是实际存储数据的节点。一个ziplist可以有多个zlentry节点,具体形式如下:
这里写图片描述
这里写图片描述
压缩表在Redis中的应用只存在于hash和list结构的实现中,为了在存储时节省内存。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis相关面试题涵盖了以下几个方面: 1. Redis的基本概念和特性:面试官可能会问到你对Redis的理解和熟悉程度。你可以回答Redis是一个开源的内存键值存储系统,具有高性能和持久化能力。它支持多种数据结构,如字符串、哈希表、列表、集合和有序集合等。 2. Redis的数据持久化方式:Redis提供了两种方式来将数据持久化到磁盘上,分别是RDB(Redis Database)和AOF(Append Only File)。RDB是一种快照方式,可以将数据以二进制形式保存到硬盘上,而AOF则是将每个写操作追加到文件末尾。你可以解释一下这两种方式的优缺点,并说明在不同场景下应该选择哪种方式。 3. Redis的线程模型:在Redis 6.0之前,Redis是单线程的。而在Redis 6.0之后开始支持多线程。Redis内部使用基于epoll的多路复用来处理网络IO,而执行命令的核心模块仍然是单线程的。你可以简要介绍一下Redis的线程模型以及引入多线程的原因。 4. Redis的扩展模块:Redis支持通过扩展模块来增加额外的功能。例如,BloomFilter、RedisSearch和Redis-ML等扩展模块可以用于实现不同的功能需求。你可以提到一些常用的Redis扩展模块,并解释一下它们的作用和用途。 总结起来,面试中关于Redis的问题主要包括对Redis的基本概念和特性的理解、数据持久化方式、线程模型以及扩展模块的使用等方面。通过对这些问题的了解和回答,可以展示出你对Redis的熟悉程度和实际应用能力。同时,你还可以结合自己的经验和实际项目,给出一些实际的应用场景和解决方案,从而更好地回答面试官的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [面试 Redis 没底?这 40 道面试题让你不再慌(附答案)](https://blog.csdn.net/xmt1139057136/article/details/115423283)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [redis面试题总结(附答案)](https://blog.csdn.net/guorui_java/article/details/117194603)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值