redis面试题


redis面试题

什么是redis?主要用来干什么?

Redis是一个开源的支持网络、可基于内存、持久化的日志型、key-value数据库

redis的数据是存于内存中的,读写速度非常快,被用于缓存,也被用来做分布式锁,还支持事务、持久化、lua脚本还有集群方案

如何保证redis和mysql的数据一致

导致数据不一致的原因

在高并发的业务场景下,数据库大多数情况下都是用户并发访问最薄弱的环节,需要redis来做一个缓冲的操作,让请求先到redis,而不是直接访问数据库,从而缓解数据库的压力

但是一旦涉及到数据更新,数据库和缓存更新的话,容易出现数据不一致的问题

  • 先写数据库,再删除缓存:在删除缓存前,写数据库的线程宕机了,没有删除数据,也会出现数据不一致
  • 先删除缓存,再写数据库:如果先删除缓存,还没有写数据库,另一个线程就来读取,发现缓存为空,去数据库读写数据库写入缓存,而此时缓存为脏数据

如何保证

1、延时双删策略:写库前后都进行redis.del(key)操作,并且设定合理的超时时间

public void write(Strig key,Object data){
    redis.del(key);
    db.updataData(data);
    Thread.sleep(500);
    redis.del(key);
}
  • 具体步骤:
  1. 先删除缓存
  2. 再写数据库
  3. 休眠500毫秒,根据具体的业务情况而定
  4. 再次删除缓存

为什么要休眠500毫秒?

由于读写的并发性,读线程获取到时间片这一片段的执行,就会将脏数据写入缓存,线程休眠就是确保读线程结束,而写请求可以删除读请求造成的缓存脏数据

休眠写操作因此对可能出现的读操作确保结束,写操作不会对读操作进行时间片片段的争抢,从而删除操作可以删除读操作造成的缓存脏数据,最后写请求对数据库数据进行更新

删除缓存失败了,怎么办?借助mq来进行重试

异步延时删除:

  • 具体步骤:
    1. 先删除缓存
    2. 再写数据库
    3. 触发异步写入串行化mq
    4. mq接收再次删除缓存

2、异步更新缓存(基于Mysql binlog的同步机制)

思路:

1、涉及到更新的数据操作,利用Mysql binlog进行增量订阅消费

2、将消息发送到消息队列

3、通过消息队列消费将增量数据更新到redis上

4、操作情况

redis的更新过程

  • 全量:将所有数据一次性写入redis
  • 增量:实时更新
    • 增量指的是mysql的update、insert、delete操作数据

利用消息队列,推送更新redis缓存数据

1、一旦mysql产生新的写入、删除、更新等操作,可以把binlog相关信息推送到redis

2、redis再根据binlog中的记录,对redis进行操作


Author: baiwenhui
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source baiwenhui !
  TOC