less than 1 minute read

整理总结常见的Redis面试题,题目来自网络

  1. 什么是 Redis?

    Redis是一个C语言开发的数据库,与传统数据库不同的是,Redis的数据是存在内存中的,所以读写速度非常快,被广泛用于缓存方向。当然Redis除了可以做缓存,还能用于做分布式锁,甚至消息队列(不过一般不用Redis做消息队列),Redis还提供了多种数据类型来支持不同的业务场景。Redis还支持事务、持久化、Lua脚本、集群。

  2. Redis 有哪些数据类型?

    string、list、hash、set、sorted set、bitmap、HyperLogLog

    string:简单的key-value类型。一般用于需要计数的场景,比如用户访问次数、热点文章点赞转发数

    list:双向链表。可以实现消息队列。

    hash:类似JDK1.8之前的HashMap,适合存储对象

    set:类似HashSet,但是是无需的。存放数据不能重复。

    sorted set:与set相比,增加了权重参数score,使得集合中的元素能够按score进行有序排列。适合需要对数据根据权重排序的场景。

    bitmap:存二进制数字。适合保存状态信息(是否签到,是否登录等)

    HyperLogLogs:可以用于统计网站访问量

  3. Redis 是单线程还是多线程?

    Redis是单线程的。

    追问:单线程如何处理高并发?1. Redis数据是在内存中的,计算也是在内存中的,非常快。2. Redis使用了NIO。3. Redis会给客户端指令通过队列来排队进行顺序处理。5. Redis的响应也有一个响应队列。

  4. Redis 过期删除策略讲一下。

    主要有2个策略。1、惰性删除。客户端访问的时候,判断一下有没有过期,如果过期了,就删除。2、定期删除。每隔一段时间抽取一批key执行删除过期key操作。

  5. Redis 的持久化策略了解嘛?分别介绍下 RDB 和 AOF。

    Redis有两种持久化策略。1、快照(RDB)。创建快照获得存储在内存里面的数据在某个时间点上的副本。2、只追加文件(AOF)。每执行一条更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。

  6. Redis 的缓存更新策略了解嘛?

    主要有三种。1、LRU、LFU、FIFO算法。当缓存使用量达到阈值的时候,根据算法删除现有缓存。2、超时删除。给缓存设置过期时间,超时后自动删除。3、主动更新。主动更新缓存。

  7. 什么是缓存穿透?什么是缓存击穿?什么是缓存雪崩?怎么解决(最高频问题)

    缓存穿透(击穿):数据不在缓存中,导致数据直接请求了数据库,根本没有经过缓存。解决方案:做好参数校验,不合法参数请求直接抛出异常返回给客户端。还可以使用布隆过滤器,把可能的请求值都存放在布隆过滤器中,当用户请求过来,先判断用户发送的请求是否存在于布隆过滤器中。

    缓存雪崩:缓存在同一时间大面积失效,请求直接访问了数据库。解决方案:采用Redis集群以及限流,让热点缓存永不失效。

  8. 设计一个分布式锁?

    线程占位,当别的线程进来操作,发现已经有线程占位了,就会放弃。比如访问前set k1 v1,过期时间为5秒,访问结束删除k1。当其他线程访问的时候,先尝试获取k1,如果能获取到,说明有线程正在临界区,阻塞等待。当然这个做法存在问题,因为过期时间为一个数,如果所用的操作时间大于这个时间,那么会因为超时而自动删除。一个解决思路是将锁的value设置为一个随机字符串,每次释放锁的时候,都去比较随机字符串是否一致,一致再释放(需要引入Lua脚本)。

  9. Redis 缓存失效策略?

    缓存淘汰策略。6种。最常用的是移除最近最少使用的key。

  10. Redis 事务你了解嘛?

    Redis事务不具备原子性(不支持回滚),只能确保当前事务不被其他事务打断

  11. 如何保证 Redis 和 MySQL 的数据一致性?(如果项目同时用到 Redis 和 MySQL,这个问题特别容易被问)

    3种缓存读写策略保证一致性。

    • 旁路缓存模式。适合读请求比较多的场景。简单来说就是以数据库的数据为准。读的时候,如果缓存中有数据,那么直接从缓存中读;如果缓存中没有数据,那么先更新数据库,再把数据写入缓存。写的时候,先更新数据库,再删除缓存。
    • 读写穿透。以缓存的数据为准。实际开发中不常用。读操作,如果缓存中有数据,那么直接从缓存中读;读不到数据则从数据库中读取,然后写入缓存。写操作,若缓存中没有,则更新数据库;反之,则先更新缓存再更新数据库。
    • 异步缓存写入。与读写穿透类似,但是是异步更新数据库的。也就是说先更新缓存,再异步批量更新数据库。