Redis的面试连环炮

  • 在项目中缓存是如何使用的?缓存如果使用不当会造成什么后果?
  • Redis 和 Memcached 有什么区别?Redis 的线程模型是什么?为什么单线程的 Redis 比多线程的 Memcached 效率要高得多?
  • Redis 都有哪些数据类型?分别在哪些场景下使用比较合适?
  • Redis 的过期策略都有哪些?手写一下 LRU 代码实现?
  • 如何保证 Redis 高并发、高可用?Redis 的主从复制原理能介绍一下么?Redis 的哨兵原理能介绍一下么?
  • Redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的?
  • Redis 集群模式的工作原理能说一下么?在集群模式下,Redis 的 key 是如何寻址的?分布式寻址都有哪些算法?了解一致性 hash 算法吗?如何动态增加和删除一个节点?
  • 了解什么是 redis 的雪崩、穿透和击穿?Redis 崩溃之后会怎么样?系统该如何应对这种情况?如何处理 Redis 的穿透?
  • 如何保证缓存与数据库的双写一致性?
  • Redis 的并发竞争问题是什么?如何解决这个问题?了解 Redis 事务的 CAS 方案吗?
  • 生产环境中的 Redis 是怎么部署的?

面试题

redis 的并发竞争问题是什么?如何解决这个问题?了解 redis 事务的 CAS 方案吗?

面试官心理分析

这个也是线上非常常见的一个问题,就是多客户端同时并发写一个 key,可能本来应该先到的数据后到了,导致数据版本错了;或者是多客户端同时获取一个 key,修改值之后再写回去,只要顺序错了,数据就错了。

而且 redis 自己就有天然解决这个问题的 CAS 类的乐观锁方案。

面试题剖析

 

Redis并发竞争的问题是什么?

这个也是线上非常常见的一个问题,就是多客户端同时并发写一个key,可能本来应该先到的数据后到了,导致数据版本错了。或者是多客户端同时获取一个key,修改值之后再写回去,只要顺序错了,数据就错了

如下图所示:我们有好几个系统同时取访问缓存,并且发起了一个写缓存的操作

  • set V1、V2、V3、V4
  • 我们期望的是它是有顺序的去执行,但是最后却没有顺序了
  • 变成了:set V1、V3、V4、V2
  • 一般解决这种问题,就是使用分布式锁
  • redis事务也可以解决,但是用得少(基本不用)

基于Zookeeper的分布式锁

某个时刻,多个系统实例都去更新某个 key。可以基于 zookeeper 实现分布式锁。每个系统通过 zookeeper 获取分布式锁,确保同一时间,只能有一个系统实例在操作某个 key,别人都不允许读和写。

redis jedis lettuce相互干扰 redis并发竞争解决_redis

你要写入缓存的数据,都是从 mysql 里查出来的,都得写入 mysql 中,写入 mysql 中的时候必须保存一个时间戳,从 mysql 查出来的时候,时间戳也查出来。

 

每次要写之前,先判断一下当前这个 value 的时间戳是否比缓存里的 value 的时间戳要新。如果是的话,那么可以写,否则,就不能用旧的数据覆盖新的数据。

分布式锁:确保同一时间,只有一个系统实例在操作某个key,别人都不需要读和写

这里修改的时候,就需要引入时间戳,因为写入缓存的数据,都是从mysql中查询出来的,都得写入mysql中,写入mysql的时候,是必须保存一个时间戳,同时查询的时候,也需要把时间戳也查询出来

v1 10.00.00 v2 10.00.01 v3 10.00.02 v4 10.00.03

每次要写入之前,首先判断一下当前这个value的时间戳是否比缓存的value的时间戳大,如果比缓存中的时间戳更大,那么就执行写入操作,如果更小,就不能用旧的数据覆盖新的数据。

Redis的事务

可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序串行化的执行而不会被其他命令插入。Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚。事务中任意命令执行失败,其余的命令仍会被执行。

其中,Redis事务分为三个阶段

  • 开始事务
  • 命令入队
  • 执行事务