Redis常见面试题

Redis 常见的数据结构

基础的5种:

  • String:字符串,最基础的数据类型。

  • List:列表。

  • Hash:哈希对象。

  • Set:集合。

  • Sorted Set:有序集合,Set 的基础上加了个分值。

Sorted Set底层数据结构

Sorted Set(有序集合)当前有两种编码:ziplist、skiplist

ziplist:使用压缩列表实现,当保存的元素长度都小于64字节,同时数量小于128时,使用该编码方式,否则会使用 skiplist

skiplist:zset实现,一个zset同时包含一个字典(dict)和一个跳跃表(zskiplist)

Sorted Set 为什么同时使用字典和跳跃表?


主要是为了提升性能。

单独使用字典:在执行范围型操作,比如 zrank、zrange,字典需要进行排序,至少需要 O(NlogN) 的时间复杂度及额外 O(N) 的内存空间。

单独使用跳跃表:根据成员查找分值操作的复杂度从 O(1) 上升为 O(logN)。
 

Hash 对象底层结构

Hash 对象当前有两种编码:ziplist、hashtable

ziplist:使用压缩列表实现,每当有新的键值对要加入到哈希对象时,程序会先将保存了键的节点推入到压缩列表的表尾,然后再将保存了值的节点推入到压缩列表表尾。

hashtable:使用字典作为底层实现,哈希对象中的每个键值对都使用一个字典键值来保存,跟 java 中的 HashMap 类似。

Hash 对象的扩容流程

hash 对象在扩容时使用了一种叫“渐进式 rehash”的方式,步骤如下:

1.计算新表 size,为新表分配空间,让字典同时持有 ht[0] 和 ht[1] 两个哈希表

2.将 rehash 索引计数器变量 的值设置为0,表示 rehash 正式开始。

3。在 rehash 进行期间,每次对字典执行增删改查操作时,程序除了执行指定的操作以外,还会触发额外的 rehash 操作,rehash操作就是从旧的hash表中找到索引计数器位置的值,将它rehash到新表中去,然后将索引加一,同时将旧表索引位置的值删除

4.如果没有对字典进行增删改查操作,redis也可以定时rehash操作

5.rehash完成后,会将h[0] 又指向新表的位置,索引计数器的值又设置为-1

渐进式 rehash 的优点

避免了集中式 rehash 而带来的庞大计算量

查找需要去两张表里查找

渐进式 rehash 执行期间,新增的键值对会被直接保存到 ht[1], ht[0] 不再进行任何添加操作

Redis 删除过期键的策略(缓存失效策略、数据过期策略)


定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临时,立即执行对键的删除操作。对内存最友好,对 CPU 时间最不友好。

惰性删除:放任键过期不管,但是每次获取键时,都检査键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。对 CPU 时间最优化,对内存最不友好。

定期删除:每隔一段时间,默认100ms,程序就对数据库进行一次检査,删除里面的过期键。至 于要删除多少过期键,以及要检査多少个数据库,则由算法决定。前两种策略的折中,对 CPU 时间和内存的友好程度较平衡。

Redis 使用惰性删除和定期删除

Redis 的内存淘汰(驱逐)策略


当 redis 的内存空间(maxmemory 参数配置)已经用满时,redis 将根据配置的驱逐策略(maxmemory-policy 参数配置),进行相应的动作。

网上很多资料都是写 6 种,但是其实当前 redis 的淘汰策略已经有 8 种了,多余的两种是 Redis 4.0 新增的,基于 LFU(Least Frequently Used)算法实现的。

noeviction:默认策略,不淘汰任何 key,直接返回错误
allkeys-lru:在所有的 key 中,使用 LRU 算法淘汰部分 key
allkeys-lfu:在所有的 key 中,使用 LFU 算法淘汰部分 key,该算法于 Redis 4.0 新增
allkeys-random:在所有的 key 中,随机淘汰部分 key
volatile-lru:在设置了过期时间的 key 中,使用 LRU 算法淘汰部分 key
volatile-lfu:在设置了过期时间的 key 中,使用 LFU 算法淘汰部分 key,该算法于 Redis 4.0 新增
volatile-random:在设置了过期时间的 key 中,随机淘汰部分 key
volatile-ttl:在设置了过期时间的 key 中,挑选 TTL(time to live,剩余时间)短的 key 淘汰
 

Redis 的持久化机制有哪几种,各自的实现原理和优缺点?

Redis 的持久化机制有:RDB、AOF、混合持久化

RDB:类似于快照,在某个时间点,将内存中的数据通过压缩保存到磁盘上,RDB是二进制文件。

RDB可以通过使用 save point 配置来触发保存RDB文件, save point可以配置在多少秒内数据发生了多少次改变,就保存快照文件。

RDB保存其实是通过创建一个子进程来进行保存操作的不会阻塞主线程

优点:二进制文件占用磁盘小,适合做备份,比AOF更适合大数据量恢复,性能好(子进程进行的保存)

缺点:容易数据丢失,阅读性差,子进程采用的是 copy-on-write 的方式,内存可能占用为原来的两倍,数据很大的时候,可能redis会卡顿。

AOF:保存 Redis 服务器所执行的所有写操作命令来记录数据库状态

AOF 服务器在执行完写命令后,我们可以配置参数来控制命令保存到磁盘上AOF文件的时机,会将命令保存到aof的缓冲区,然后aof缓冲区的内容会先写入到aof缓存区,最后保存到磁盘上的AOF文件。比如每执行完一个命令就保存,每一秒保存,让系统自己决定。

优点:可阅读,数据丢失风险更小,更可靠

缺点:文件大,性能比RDB慢

混合持久化

混合持久化只发生于 AOF 重写过程。使用了混合持久化,重写后的新 AOF 文件前半段是 RDB 格式的全量数据,后半段是 AOF 格式的增量数据。

优点:结合 RDB 和 AOF 的优点, 更快的重写和恢复。

缺点:AOF 文件里面的 RDB 部分不再是 AOF 格式,可读性差

Redis 怎么保证高可用、有哪些集群模式

主从复制、哨兵模式、集群模式。

1.主从复制:一个主节点多个从节点,可以使用slaveof命令 ip地址 端口 开启

1.建立连接,身份验证,发送从的ip和端口,发送可以同步数据的能力,然后开启数据同步,最后命令传播(有写命令就发送给从节点)

2.哨兵模式:

哨兵(Sentinel) 是 Redis 的高可用性解决方案:由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器。

Sentinel 可以在被监视的主服务器进入下线状态时,自动将下线主服务器的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
哨兵故障检测:主观下线,向所监测的节点发送ping,如果没有获得成功就将该节点标记为主观下线,然后问同样监测该节点的其它sentinel,问它是不是下线了,如果是那就将该节点设置为客观下线。

故障转移:1.sentinel选出领头的实例,该实例去选择一个从节点让它升级为主节点,领头 Sentinel 将剩余的所有从服务器改为复制新的主服务器,领头 Sentinel 更新相关配置信息,当这个旧的主服务器重新上线时,将其设置为新的主服务器的从服务器

3.集群模式:

集群模式也是redis的高可用解决方法之一:由多个主从服务器构成。

将数据按槽分配到多个主服务器上,所以的redis节点之间互相通信,客户端随便连接一个主节点就可以。

集群的故障转移:当从节点发现自己的主节点故障了,从节点就给集群发一条消息,让其他主节点给自己投票,主节点经过校验从节点是否满足升为主节点的条件,如果满足就投一票如果收到的票大于1半就成功升级为主节点。

如何保证集群扩容安全:ASK错误机制保证,如果在扩容中,发现所要的数据被复制到其它节点,就返回一个ask错误,该错误会指引客户端转向正在导入槽的目标节点。

缓存穿透

描述:访问一个缓存和数据库都不存在的 key,此时会直接打到数据库上,并且查不到数据,没法写缓存,所以下一次同样会打到数据库上。

缓存击穿

描述:某一个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,甚至可能打垮数据库。

缓存雪崩

描述:大量的热点 key 设置了相同的过期时间,导在缓存在同一时刻全部失效,造成瞬时数据库请求量大、压力骤增,引起雪崩,甚至导致数据库被打挂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值