Skip to content

Redis

使用场景

  • 缓存
    • 穿透,击穿,雪崩
    • 双写一致,持久化
    • 数据过期,淘汰策略
  • 分布式锁
    • setnx,redisson
  • 计数器
  • 保存token:String类型
  • 消息队列
  • 延迟队列:
  • 集群
  • 事务
  • Redis为啥这么快

常见面试题

image-20230807083712638

缓存-缓存穿透

image-20230807084040646

原因是有人恶意伪造id来获取文章信息。

解决方案:

  1. 缓存空数据,查询返回的数据为空,仍把这个空数据进行缓存

    优点:简单

    缺点:消耗内存,可能存在数据不一致的问题

  2. 使用布隆过滤器

    优点:内存占用较少,没有多余的key

    缺点:实现复杂,存在误判

    image-20230807084359517

    缓存预热时,预测布隆过滤器

    布隆过滤器知识

    image-20230807084833358

    存在的问题-有缺失率,如下图所示

    image-20230807085455609

    误判率:数组越小误判率就越大,数组越大误判率就越小,但是同时带来更多的内存消耗。

    布隆过滤器实现方案:Redisson,Guava

缓存-击穿

缓存击穿:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把DB压垮

image-20230807090403703

解决方案

互斥锁:强一致,性能差

逻辑过期:高可用,性能优,不能保证数据绝对一致

image-20230807090802872

缓存雪崩

缓存雪崩是指在同一时间段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。

image-20230807091433098

解决方案:

  • 给不同的key的TTL添加随机值
  • 利用redis集群提高服务的可用性,哨兵模式,集群模式
  • 给缓存业务添加降级限流策略,ngnix
  • 给业务添加多级缓存,Guava或者Caffaie

《缓存三兄弟》

  • 穿透无中生有key,布隆过滤null隔离。
  • 缓存击穿过期key,锁与非期解难题。
  • 雪崩大量过期key,过期时间要随机。
  • 面试必考三兄弟,可用限流来保底。

双写一致性

前提需求:一致性要求,允许延迟一致性

双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致

image-20230807092249697

不管是先删除缓存,还是先修改数据库,都会出现问题。

image-20230807092619196

解决方案:

image-20230807092929730

上面的方案,依旧不高。

image-20230807094037434

阿里给的双写一致性方案

image-20230807094248015

面试题

image-20230807094702882

持久化

在Redis中提供了两种数据持久化的方式:1.RDB 2.AOF

RDB全称Redis Database Backup file (Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。

bgsave开始时会fork主进程得到子进程,子进程共享主进程的内存数据。完成fork后读取内存数据并写入RDB 文件。

image-20230807100209049

AOF

AOF全称为Append Only File (追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件。

image-20230807100304072

AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF

image-20230807100411378

因为是记录命令,AOF文件会比RDB文件大的多。而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果。

image-20230807100722140

数据过期策略

加入redis的key过期后,会立即删除吗?

Redis对数据设置数据的有效时间,数据过期以后,就需要将数据从内存中删除掉。可以按照不同的规则进行删除,这种删除规则就被称之为数据的删除策略(数据过期策略)。

Redis数据删除策略-惰性删除

惰性删除:设置该key过期时间后,我们不去管它,当需要该key时,我们在检查其是否过期,如果过期,我们就删掉它,反之返回该key

优点∶对CPU友好,只会在使用该key时才会进行过期检查,对于很多用不到的key不用浪费时间进行过期检查 缺点∶对内存不友好,如果一个key已经过期,但是一直没有使用,那么该key就会一直存在内存中,内存永远不会释放

Redis数据删除策略-定期删除

定期删除:

每隔一段时间,我们就对一些key进行检查,删除里面过期的key(从一定数量的数据库中取出一定数量的随机key进行检查,并删除其中的过期key)。

定期清理有两种模式:

  • SLOW模式是定时任务,执行频率默认为10hz,每次不超过25ms,以通过修改配置文件redis.conf的hz选项来调整这个次数
  • FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms

优点:可以通过限制删除操作执行的时长和频率来减少删除操作对CPU的影响。另外定期删除,也能有效释放过期键占用的内存。 缺点:难以确定删除操作执行的时长和频率。

数据淘汰策略

缓存过多,内存是有限的,内存被占满的怎么办?

数据的淘汰策略:当Redis中的内存不够用时,此时在向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。

image-20230807102704511

面试问题

image-20230807105414384

分布式锁

Redis实现分布式锁主要利用Redis的setnx命令。setnxs set if not exists

image-20230807111340410

实现分布式锁-流程

image-20230807142721615

redisson实现的分布式锁-主从一致性吗?

image-20230807143344785

缺点:实现复杂,性能差,运维繁琐。

面试问题

image-20230807143606796

主从复用

Redis集群有哪些方案,知道吗?

  • 主从复制
  • 哨兵模式
  • 分片集群

image-20230807143704125

主从复制的整体架构

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。

image-20230807145650697

主从数据同步原理

  • 主从全量同步
  • 主从增量同步

image-20230807145943515

  • Replication ld:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的rep)lid,slave则会继承master节点的replid
  • offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset.如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。
  1. 从节点请求主节点同步数据(replication id、 offset )
  2. 主节点判断是否是第一次请求,是第一次就与从节点同步版本信息(replication id和offset)
  3. 主节点执行bgsave,生成rdb文件后,发送给从节点去执行
  4. 在rdb生成执行期间,主节点会以命令的方式记录到缓冲区(一个日志文件)
  5. 把生成之后的命令日志文件发送给从节点进行同步

image-20230807150714522

  1. 从节点请求主节点同步数据,主节点判断不是第一次请求,不是第一次就获取从节点的offset值
  2. 主节点从命令日志中获取offset值之后的数据,发送给从节点进行数据同步

哨兵模式

image-20230807170554305

服务状态监控

Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:

  • 主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线
  • 客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quoru m值最好超过Sentinel实例数量的一半。

哨兵选主规则

  • 首先判断主与从节点断开时间长短,如超过指定值就排该从节点
  • 然后判断从节点的slave-priority值,越小优先级越高
  • 如果slave-prority一样,则判断slave节点的offset值,越大优先级越高。
  • 最后是判断slave节点的运行id大小,越小优先级越高。

image-20230807171642068

分片集群

主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:。

  • 海量数据存储问题
  • 高并发写的问题

使用分片集群可以解决上述问题,分片集群特征

  • 集群中有多个master,每个master保存不同数据
  • 每个master都可以有多个slave节点
  • master之间通过ping监测彼此健康状态
  • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

image-20230807171918582

分片集群结构-数据读写

Redis分片集群引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。

面试问题

image-20230807172240746

Redis为啥这么快

image-20230807195611183