Java面试题———Redis篇②

目录

1.RDB期间可以同时处理写请求吗

2.Redis集群有哪些方案

3.如何保存Redis数据与MySQL一致

4.什么是缓存预热

5.什么是缓存穿透, 怎么解决

6.什么是缓存击穿,怎么解决

7.什么是缓存雪崩,怎么解决

8.用过Redis的事务吗


1.RDB期间可以同时处理写请求吗

Redis在进行RDB期间是可以同时处理写请求的,这得益于Redis使用操作系统的多进程写时复制技术来实现快照持久化

具体来说,就是Redis在持久化时会产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求

当主线程执行写指令修改数据的时候,这个数据就会复制一份副本, 子进程读取这个副本数据写到 RDB 文件

这既保证了快照的完整性,也允许主线程同时对数据进行修改,避免了对正常业务的影响

2.Redis集群有哪些方案

在Redis中提供的集群主要有三种,分别是主从、哨兵和分片集群

  1. 主从集群主要用来解决Redis的并发问题,一般是一个主节点负责数据写入,多个从节点负责数据读取,主节点的数据会实时同步给从节点

  2. 哨兵集群主要用来解决Redis的高可用问题,哨兵会监控集群中节点的状态,并在主节点出现问题时进行重新选主

  3. 分片集群主要用来解决Redis的海量数据存储问题,它要求有多个主节点,然后数据写入的数据会经过计算落到其中一个上

    在这个计算的过程中Redis引入了哈希槽的概念,Redis集群有16384个哈希槽,每个 key通过CRC16校验后对16384取模来决定放置哪个槽

    而分片集群的每个节点负责一部分 hash 槽,这样就可以计算出一个key会出现在哪个节点上了,查询的时候也是同时的方式来定位即可

3.如何保存Redis数据与MySQL一致

保证Redis和MySQL数据一致性的方案有很多,最常见的有三种

  1. 同步双写,即在程序更新完MySQL之后后立即同步更新redis

  2. 异步监听,即通过Canal监听MySQL的binlog日志变化,然后再通过程序将变化的数据更新数据到 Redis

  3. MQ异步,即程序在更新完MySQL后,发送一条消息到MQ中,然后在通过一个程序监听MQ,获取到消息,然后更新Redis

4.什么是缓存预热

缓存预热是指系统上线后,提前将相关的缓存数据加载到缓存系统。

避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题,用户直接查询事先被预热的缓存数据。

如果不进行预热,那么 Redis 初始状态数据为空,系统上线初期,对于高并发的流量,都会访问到数据库中,对数据库造成流量的压力。

缓存预热解决方案主要有下面几个:

  • 数据量不大的时候,工程启动的时候进行加载缓存动作

  • 数据量大的时候,设置一个定时任务脚本,进行缓存的刷新

  • 数据量太大的时候,优先保证热点数据进行提前加载到缓存

5.什么是缓存穿透, 怎么解决

在我们的项目中会将缓存放到数据库前面,查询的时候先查缓存,缓存有了就不用再去查数据库了,这样可以大大减轻数据库的访问压力

而缓存穿透指的是请求一直在查询一个数据库中不存在的数据,这样缓存中没有,请求就会到达数据库,而数据库也没有,也就没法缓存

所以每一次请求都会直接到数据库中查询,这就极有可能导致数据库被压垮

常用的解决方案有两个:

  1. 查询返回的数据为空,仍把这个空结果进行缓存,但过期时间尽量设置稍短一些

  2. 使用布隆过滤器:将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对DB的查询

6.什么是缓存击穿,怎么解决

在我们的项目中会将缓存放到数据库前面,查询的时候先查缓存,缓存有了就不用再去查数据库了,这样可以大大减轻数据库的访问压力

缓存击穿指的是对于一个设置了过期时间的key,在其缓存失效的瞬间,有大量的请求访问这个它,这些请求在缓存找不到就会直接到数据,导致数据库被压垮

常用的解决方案有两个:

  1. 使用互斥锁:当缓存失效时,不立即去数据库查询,而是先去获取一把全局锁,那个线程获取到了,就去数据库查询,获取不到的就等待重试查询缓存

  2. 修改设置key有效期的逻辑,大体如下:

    在设置key的时候,不给它设置过期时间,而是单独设置一个过期时间字段一块存入缓存中

    当查询的时候,从redis取出数据后判断时间是否过期,如果过期则开通另外一个线程进行数据同步,当前线程正常返回数据

两种方案对比:

解决方案优点缺点
互斥锁没有额外的内存消耗 ,保证一致性线程需要等待,性能受影响
逻辑过期线程无需等待,性能较好不保证一致性,有额外内存消耗

7.什么是缓存雪崩,怎么解决

在我们的项目中会将缓存放到数据库前面,查询的时候先查缓存,缓存有了就不用再去查数据库了,这样可以大大减轻数据库的访问压力

缓存雪崩指的是大量的key在某一时刻同时失效,这样大量的请求全部转发到DB,DB 瞬时压力过重雪崩

解决方案也很简单,就是在设置key的过期时间的时候,尽量加一些随机值,这样缓存过期时间的重复率就会降低

8.用过Redis的事务吗

Redis中本身是没有事务的概念的,但是他有几个命令组合起来能实现类似于事务的效果。也就是说,Redis事务的本质是一组命令的集合。

这里用到的命令主要有5个,分别是:

  1. MULTI:用来组装一个事务

  2. EXEC:执行一个事物

  3. DISCARD:取消一个事务

  4. WATCH:用来监视一些key,一旦这些key在事务执行之前被改变,则取消事务的执行

  5. UNWATCH:取消 WATCH 命令对所有key的监视

总结说:Redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。Reids中,单条命令式原子性执行的,但事务不保证原子性,且没有回滚。

  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啵啵薯条

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值