Redis面试

①Redis的持久机制?

答:①RDB(默认使用),通过设置每隔一定时间之内操作键的次数来将内存数据以快照形式保存到磁盘中,redis重启后从磁盘中读取快照文件恢复数据。优点:适合大规模的数据。缺点:不能实时持久化有数据丢失的风险,比较耗时

②AOF:会把每次写的命令记录到日志文件中,redis重启后会将持久化的日志文件恢复。写频率也是可以设置:Always:写一次命令,立刻写到AOF文件中。Everysec:先把命令写到AOF缓冲区中,每隔一秒将缓冲区数据写到AOF文件。No:先把命令写到AOF缓冲区中,由操作系统决定何时写到AOF文件中。其优点是:安全,几乎不会丢失数据。缺点:记录的内容多,文件大,恢复速度慢。

②讲一讲缓存穿透,缓存雪崩,缓存击穿?

答:首先缓存穿透,就是客户端发来的请求穿过redis直接请求到数据库上,如果是大量的请求就有可能导致数据库宕机。通常像查询一个id=-1的数据,redis和数据库中都没有这样的一个数据,就会直接打到数据库上。解决方案:①通过Redis缓存空值。②使用布隆过滤器。③对参数进行合法校验。④对恶意攻击的ip拉黑

其次缓存雪崩,缓存雪崩就是Redis中大量的键在同一时间过期,导致大量的请求全都请求到数据库上,导致数据库挂掉。解决方案:①设置随机失效时间。②搭建高可用分布式集群。

最后缓存击穿,缓存击穿是redis中一个热点的key失效,导致大量的请求打到数据库上使其挂掉。解决方案:①不设置过期时间。②使用分布式锁,只让一个线程获得所然后从数据库中拉取数据写到redis中。

③如何保证缓存与数据库的数据一致性?

答:①首先如果采用的是更新数据库和更新Redis的方案,不管是哪种方案,都会产生数据不一致的问题。先S再R,因为不是原子性的,导致A线程已经更新S了还没来得及更新R,此时B线程就来查就查到了脏数据。先R再S,如果更新完R但是更新S失败了,也会导致数据不一致。所以对于直接更新数据库和MySQL的方案不是很推荐。如果说一定要使用更新缓存的话可以使用ALibaba提供的Canal中间件去实现先更新数据库,再通过订阅MySQL的Binlog日志,去异步更新缓存。

②先删除缓存,再更新数据库:但是如果是并发情况下,A来更新数据,A删除缓存后,然后去操作数据库,此时B来查询,B看到Redis是空的,然后去数据库查询数据(脏数据)再写到缓存中,而此时A还没有更新数据库,也会导致数据不一致。-------->延迟双删策略:删除缓存,更新数据库,一段时间之后再删缓存。针对于删除失败的话就可以通过异步重试机制去确保删除

③先更新数据库,再删除缓存:虽然说也会出现不一致问题。 但是在上面三种情况下可以说是最优的。此时要确保删除缓存操作成功,我们就可以使用MQ消息队列的重试机制去保证删除。

④讲一讲Redis的内存过期策略?

答:①定时删除:为每一个key设置一个定时器,一到过期时间就立即清除key,这种方式对内存很友好,但是占用CPU的大量资源。

②惰性删除:在要使用该key的时候去检查有没有过期,过期则清除。这样可以节省CPU的资源,但是对内存非常不友好,因为当有很多过期的key但是没有去使用的时候,就会导致大量过期的key没有清除。

③定期删除:每隔一段时间就去扫描一定数量的设置了TTL的key,并且清除其中过期的key。默认是1秒10次,一次5个。该策略可以使得CPU和内存资源达到最优的平衡状态。

不过实际上的Redis是同时使用惰性删除和定期删除两种策略。一边每隔一段时间去扫描清除过期的key,一边通过使用key的时候判断是否过期,过期则删除。

⑤讲一讲Redis的内存淘汰策略?

①noeviction:默认策略,不淘汰任何key,但是内存满了操作就会报错。

②volatile-ttl:删除过期时间最早的key。

③allkeys-random:对所有的key随机淘汰。

④volatile-random:对设置了TTL的key进行随机淘汰。

⑤allkeys-lru:对所有的key,最少最近使用的优先淘汰

⑥volatile-lru:对设置了TTL的key,最少最近使用的优先淘汰

⑦allkeys-lfu:对所有的key,最少频率使用的优先淘汰

⑧volatile-lfu:对设置了TTL的key,最少频率使用的优先淘汰

⑥ Redis的分布式锁如何实现?

答:①setnx

②Redisson

⑦布隆过滤器的实现原理?

答:布隆过滤器首先就是通过位图的方式来表示元素是否存在。一般通过1表示存在,0表示不存在。而一般我们是通过hash算法和布隆过滤器的比特位长度来计算出一个编号或者记录的存储位置。因为用到了hash算法就会出现hash碰撞的问题。这就会导致布隆过滤器不是百分百的判断出一个元素是否已经存在,所以使用布隆过滤器应该说可以容忍一定的错误。不过我们也可以通过项加长bit位长度和利用不同的hash算法去获取多个bit位的标识,只有当所有的bit位都是1才能判断其是存在的,当然这也只是大大减小误判的可能性。

⑧为什么要使用Redis以及为什么Redis为什么快?

答:①命令执行是基于内存操作,速度快。

②单线程,避免了线程的切换,减少开销。Redis 6 引进了多线程

③基于I/O多路复用技术提升了Redis的I/O利用率

④高效的数据存储结构

⑤高并发,能承受的请求是远远大于数据库的,基本是数据库额10倍。高性能,通过数据预热以及缓存存储,不用去数据库中查询,能大大提高用户的查询效率

⑨Redis中有哪些数据结构以及应用场景?

String类型:底层是动态字符串SDS(!!①动态扩容②二进制安全③内存预分配,减少了内存分配次数④获取长度时间复杂度为O(1))

应用场景:缓存对象,计数器,分布式锁,共享session

List类型:底层是快表(!!①也是双向链表实现的②每个节点是一个压缩链表,解决了内存占用的问题③控制了压缩列表的大小,解决了连续空间申请效率问题)

应用场景:消息队列

Hash类型:底层是压缩列表或者哈希表

应用场景: 存储对象信息,购物车

Set类型:底层是整数集合或者哈希表

应用场景:点赞,共同关注

Zset类型:底层是压缩列表或者跳表(!!①其实就是个双向链表②节点之间按照score进行排序③每个节点可以包含多层指针④增删改查性能好,与红黑树基本一致,但是跳表实现更简单)

应用场景:排行榜

⑩Redis搭建的高可用或者集群模式?

<一>主从集群,实现读写分离

主从同步原理:

流程:

出现的问题:

优化:

<二>哨兵集群,监控+自动故障恢复+通知

基于心跳监控机制来进行健康检测

选举新的Master节点

故障转移

<三>分片集群,多主多从+插槽绑定数据

散列插槽:key跟插槽进行绑定

相关推荐

  1. redis面试

    2024-06-18 21:56:02       25 阅读
  2. Redisredis面试相关积累

    2024-06-18 21:56:02       36 阅读
  3. Redis面试

    2024-06-18 21:56:02       61 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-18 21:56:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-18 21:56:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-06-18 21:56:02       82 阅读
  4. Python语言-面向对象

    2024-06-18 21:56:02       91 阅读

热门阅读

  1. HTML(8)——CSS选择器

    2024-06-18 21:56:02       36 阅读
  2. LeetCode 2288.价格减免:模拟

    2024-06-18 21:56:02       32 阅读
  3. 给wordpress网站添加瀑布流效果

    2024-06-18 21:56:02       37 阅读
  4. 文件系统更新initrd的方法

    2024-06-18 21:56:02       27 阅读
  5. 广东省省站节能检测试题库(2024年)

    2024-06-18 21:56:02       29 阅读