• Redis常见面试题


    在平时我们常常使用 Redis ,这里总结一下 Redis 的相关面试题和一些常见问题的解决方案。

    Redis 在互联网公司一般有已下应用:

    • String:缓存、限流、计数器、分布式锁、分布式 Session
    • Hash:存储用户信息、用户主页访问量、组合查询
    • List:微博关注人时间轴列表、简单队列
    • Set:踩、赞、标签、好友关系
    • Zset:排行榜

    Redis 为什么会这么快?

    • Redis 是纯内存操作,并且异步持久化到硬盘中。
    • Redis 是单线程,从而避免了多线程中上下文频繁切换的问题。
    • Redis 底层数据结构简单,对数据的操作也简单。
    • Redis 使用非阻塞多路 I/O 复用模型,效率高。

    Redis 缓存雪崩该如何避免?

    1.对缓存设置相同的过期时间,导致某段时间内缓存失效,请求全部走数据库

    在缓存的时候给过期时间加上一个随机值,这样就会大幅减少缓存再同一时间过期。

    2.Redis 挂掉了,请求全部走数据库

    事发前:实现 Redis 的高可用
    事发中:本地缓存(ehcache)+限流(hystrix),尽可能的减少数据库被干掉的可能
    事发后:使用 Redis 的持久化机制,重启后快速恢复缓存数据

    缓存击穿如何避免?

    缓存击穿是指查询一个一定不存在的数据,由于缓存不命中,并且从数据库查询不到的数据不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,失去了缓存的意义。

    1.对请求的参数使用布隆过滤器(BloomFilter)或者提前拦截这个请求,不让其请求到数据库。
    2.我们也可以对这个空值对象缓存到 Redis,当然我们必须设置一个较短的过期时间,以防止这空值对象对业务数据产生影响。

    缓存与数据库双写一致

    一般的我们队读操作都有一个套路:
    1.如果我们的数据在缓存中有,我们就直接取缓存中的。
    2.如果缓存中没有我们想要的数据,我们会先去查询数据库,然后将数据库查询出来的数据写到缓存中。
    3.最后将数据返回给用户请求。

    高并发情况下,无论是先操作数据库还是后操作数据库,再加上缓存更新,就更加容易导致数据库与缓存数据不一致的问题。如果每次更新了数据库都去更新缓存将是一个非常耗费性能的操作,不如将缓存直接删除掉。等下次读取的时候,缓存没有找到,再到数据库找,再将数据库中的数据缓存到 Redis 中。

    解决思路:
    先更新数据库,再删除缓存
    这样可以解决大部分的并发问题,但是也存在一定的概率(极小)导致缓存不一致的情况。

    • 缓存刚好失效
    • 线程 A 查询数据库,得到一个旧值
    • 线程 B 将新值写入数据库
    • 线程 B 删除缓存
    • 线程 A将插到的旧数据写入缓存

    先删除缓存,再删除数据库
    这样其实也可以解决并发问题,但是其实也会有一定概率导致缓存不一致的情况。

    • 线程 A 删除了缓存
    • 线程 B 查询,发现缓存已不存在
    • 线程 B 去数据库查询得到旧数据
    • 线程 B 将旧数据写入缓存
    • 线程 A 将新值写入数据库

    但是上面两种方式都是在很极端的情况下才会发生的情况,如果在需要缓存和数据强一致性的情况下可以将删除缓存、修改数据库放在一个队列中去执行,实现串行化,这样就可以保证缓存和数据库的一致性。

  • 相关阅读:
    使用ExcelMapper制作用于打印的矩阵
    八皇后问题-回溯法解
    HashMap-1.8 你看得懂的原理分析
    一生之敌
    必学十大经典排序算法,看这篇就够了(附完整代码/动图/优质文章)
    事务的四种隔离级别
    数据库的三范式
    ConcurrentHashMap底层实现原理和源码分析
    leetcode-160-相交链表(simple)
    JAVA中priorityqueue详解
  • 原文地址:https://www.cnblogs.com/manastudent/p/12264367.html
Copyright © 2020-2023  润新知