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机。
解决办法:
- 平时设置key过期时间的时候,避免让过期时间一致,最好加一个范围数字的随机数来设置过期时间。
- 采用预热处理,在即将大量访问之前,手动加入缓存,设置不同的过期时间,尽量让缓存失效时间不在一个时间点。
- 设置热点数据永远不过期,定时任务定时更新
如果Redis在途中突然down机,这个时候也可能导致雪崩。 解决办法:1、针对小业务量级,我们可以采用 redis 的 sentinel 哨兵机制 2、针对大业务量级,我们可以采用 redis 的 cluster 集群方案
3.2、缓存穿透(查询不存在数据)
缓存中没有,数据库中也没有 缓存穿透是指恶意频繁查询一个缓存中不存在的数据。缓存中不存在这个数据,所以请求就会访问数据库,数据库中也没有这个数据,也就不会把数据存入到缓存,所以如果恶意访问数据量大的话就会一直增大数据库的压力,从而导致数据库down机。
解决办法:
- 不管数据实际上存不存在,我们都把这个键存到缓存中,设置一个随机比较短的过期时间。
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如何进行缓存预热
- 提前把数据塞入redis
- 在开发逻辑上也要规避差集,避免redis的穿透击穿,雪崩。
5、redis实现持久化
Redis是一个内存数据库,如果没有配置持久化,redis重启后数据就全丢失 因此开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。
5.1、RDB (Redis DataBase)
在指定的时间间隔内将内存中的数据集快照写入磁盘。 优点
- RDB文件紧凑,全量备份,适合用于进行备份和灾难恢复
- 在恢复大数据集时的速度比 AOF 的恢复速度要快
- 生成的是一个紧凑压缩的二进制文件
缺点
- 每次快照是一次全量备份,fork子进程进行后台操作,子进程存在开销
- 在快照持久化期间修改的数据不会被保存,可能丢失数据
5.2、AOF
默认情况下 Redis 没有开启 AOF(append only file)方式的持久化,可以 通过 appendonly 参数开启:appendonly yes。 开启 AOF 持久化后每执行一条会更改 Redis 中的数据的命令,Redis 就会将 该命令写入硬盘中的 AOF 文件。AOF 文件的保存位置和 RDB 文件的位置相同,都 是 通 过 dir 参 数 设 置 的 , 默 认 的 文 件 名 是 appendonly.aof , 可 以 通 过 appendfilename 参数修改:appendfilename appendonly.aof.
优点:
- 数据更加安全
- 当Redis AOF文件太大时,Redis能够在后台自动重写AOF
- AOF以易于理解和解析的格式,一个接一个地包含所有操作的日志
缺点:
- AOF文件通常比同一数据集的等效RDB文件大
- 根据确切的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