1、什么是Redis

Redis本质上是一个Key-Value类型的内存数据库,整个数据库加载在内存当中操作,定期通过异步操作把数据库中的数据flush到硬盘上进行保存。因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value 数据库。

高性能:Redis能读的速度是110000次/s,写的速度是81000次/s 内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。

2、Redis的基本类型

String字符串类型:存储一些数字,验证码、时间戳、一些配置项字典表的数据 Hash(HashMap):可以存储实体类型的数据,比如存储用户的登陆信息 List(链表类型):存储一些集合数据,可重复 Set(集合元素不重复):存储一些集合数据,不可重复 SortedSet(集合元素不重复,排序):存储一些集合数据,不可重复,可以排序,比如榜单,投票排行

3、Redis的缓存雪崩、穿透、击穿

3.1、缓存雪崩

缓存雪崩是指缓存中的key大批量到达了过期时间,这个时候这个大量的请求都需要到数据库请求去拿数据,这个时候数据的压力暴增引起down机。

解决办法:

  1. 平时设置key过期时间的时候,避免让过期时间一致,最好加一个范围数字的随机数来设置过期时间。
  2. 采用预热处理,在即将大量访问之前,手动加入缓存,设置不同的过期时间,尽量让缓存失效时间不在一个时间点。
  3. 设置热点数据永远不过期,定时任务定时更新

如果Redis在途中突然down机,这个时候也可能导致雪崩。 解决办法:1、针对小业务量级,我们可以采用 redis 的 sentinel 哨兵机制 2、针对大业务量级,我们可以采用 redis 的 cluster 集群方案

3.2、缓存穿透(查询不存在数据)

缓存中没有,数据库中也没有 缓存穿透是指恶意频繁查询一个缓存中不存在的数据。缓存中不存在这个数据,所以请求就会访问数据库,数据库中也没有这个数据,也就不会把数据存入到缓存,所以如果恶意访问数据量大的话就会一直增大数据库的压力,从而导致数据库down机。

解决办法:

  1. 不管数据实际上存不存在,我们都把这个键存到缓存中,设置一个随机比较短的过期时间。

3.3、缓存击穿 (某个热点key缓存失效了)

缓存中没有,数据库有 缓存中没有但数据库中有的数据,假如是热点数据,那key在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力增大。

  • 和缓存雪崩的区别在于这里针对某一key缓存,后者则是很多key。

  • 解决办法

    • 设置热点数据不过期
    • 定时任务定时更新缓存
    • 设置互斥锁

4、redis常用的缓存策略(保证数据库与缓存的一致性)

1、先更新数据库,在更新缓存 2、先更新缓存在更新数据库 3、先删除缓存在更新数据库 4、先更新数据库在删除缓存(推荐) 四种策略都可能会导致数据的不一致,所以在第四种策略添加一个过期时间,就可以完美解决数据不一致问题,达到最终一致性。 或者通过mq去监听数据库binlog日志如果发生修改或者新增删除都去更新redis缓存。

4.1 redis缓存是如何淘汰的

lru/lfu/random/ttl

  • lru
    • 链表,当前访问k,放在链表头部。没有访问就放到尾部
  • lfu
    • 最近使用次数少的key进行一个数据删除
  • random
    • 随机淘汰
  • ttl
    • 设置过期事件的key进行优先淘汰 默认直接报错,异常,这是一个默认的处理策略 redis.config(maxmemory)都可以修改 可以订阅这个redis的缓存策略,进行数据保护。

4.2 redis如何进行缓存预热

  1. 提前把数据塞入redis
  2. 在开发逻辑上也要规避差集,避免redis的穿透击穿,雪崩。

5、redis实现持久化

Redis是一个内存数据库,如果没有配置持久化,redis重启后数据就全丢失 因此开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。

5.1、RDB (Redis DataBase)

在指定的时间间隔内将内存中的数据集快照写入磁盘。 优点

  1. RDB文件紧凑,全量备份,适合用于进行备份和灾难恢复
  2. 在恢复大数据集时的速度比 AOF 的恢复速度要快
  3. 生成的是一个紧凑压缩的二进制文件

缺点

  1. 每次快照是一次全量备份,fork子进程进行后台操作,子进程存在开销
  2. 在快照持久化期间修改的数据不会被保存,可能丢失数据

5.2、AOF

默认情况下 Redis 没有开启 AOF(append only file)方式的持久化,可以 通过 appendonly 参数开启:appendonly yes。 开启 AOF 持久化后每执行一条会更改 Redis 中的数据的命令,Redis 就会将 该命令写入硬盘中的 AOF 文件。AOF 文件的保存位置和 RDB 文件的位置相同,都 是 通 过 dir 参 数 设 置 的 , 默 认 的 文 件 名 是 appendonly.aof , 可 以 通 过 appendfilename 参数修改:appendfilename appendonly.aof.

优点:

  1. 数据更加安全
  2. 当Redis AOF文件太大时,Redis能够在后台自动重写AOF
  3. AOF以易于理解和解析的格式,一个接一个地包含所有操作的日志

缺点:

  1. AOF文件通常比同一数据集的等效RDB文件大
  2. 根据确切的fsync策略,恢复的时候AOF可能比RDB慢

6、集群Redis Cluster

引入:单个Redis如果因为某种原因宕机的话,可能会导致Redis服务不可用,可以使用主从复制实现一主多从,主节点负责写的操作,从节点负责读的操作,主节点会定期将数据同步到从节点中,保证数据一致性的问题。

原理:redis cluster 集群默认 16384 个 hash 槽,集群搭建成功之后,需要给每一个 主节点,分配 hash 槽。当外部数据插入的时候,会对 key 进行 crc16 然后对 16384 取模,这样就计算出哪个节点对该数据进行管理。 在项目当中可以采用的 3 主 3 从的结构,主从之间通过哨兵,出现故障自动切换.

7、分布式锁

为了防止分布式系统中的多个进程之间相互干扰,我们需要一种分布式协调技术来对这些进程进行调度,利用互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题

7.1 Redission

Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而是开发者能将精力更集中地放在业务上。 Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格(In-Memory Data Grid)。 Redission作为redis的分布式客户端,同样基于netty采用异步非阻塞式IO,是线程安全的,优点是提供了很多redis的分布式操作和高级功能,缺点是api抽象,学习成本高。

7.2 redis setnx命令

setnx 的含义就是 SET if Not Exists,有两个参数 setnx(key, value),该方法是原子性操作。 如果 key 不存在,则设置当前 key 成功,返回 1; 如果当前 key 已经存在,则设置当前 key 失败,返回 0; 需要注意加锁key的粒度,解锁需要注意锁的线程必须是当前线程的锁。锁续期需要主要给锁分配的时间。

7.3 采用 lua脚本+redis

使用 lua脚本+redis可以保证业务的原子性。

8. 线程安全

8.1 redis是单线程还是多线程

无论是哪个版本redis的工作线程都是一条。 在6.x以后io有多线程。

8.2 redis存在线程安全问题吗?问什么?

redis可以保障内部串型,外界使用的要自行保障线程安全。

8.3 redis多路复用

select poll都是基于连接轮训的方式完成多路复用的

  • select
    • 最大1024
  • poll
    • 无限
  • epoll
    • 基于事件驱动来做多路复用
    • 比如创建一个内存快,创建一个事件收集器(selector)
    • redis在启动的时候会向我们的事件收集器注册(accept)
    • 在有客户端连接的时候会有事件收集器通知redis,建立连接
    • 在客户端发数据的时候,也会有一个io的事件,事件收集器会返回一个数组给redis