1、Redis简介
1.1、什么是Redis?
Redis是现在最受欢迎的NoSQL数据库之一,Redis是一个使用ANSI C编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库,其具备如下特性:
- 基于内存运行,性能高效
- 支持分布式,理论上可以无限扩展
- key-value存储系统
- 开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
- 定期通过异步操作把数据库数据Flush到硬盘进行保存
1.2、Redis的优势?
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
2、Redis如何做持久化?
2.1、RDB(Redis DataBase)
RDB:RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。 这是Redis的默认方式。
优点:保存多份完整备份,对 IO 影响小,适合做冷备,并且在宕机后恢复更加快
缺点:一般快照文件生成的间隙在 5min,一旦宕机,就会丢失 5min 的数据。同时如果快照文件过大,会让服务暂停几毫秒甚至一秒
2.2、AOF(Append Only File)
AOF: 以独立日志的方式记录每次写命令,重启时在重新执行AOF文件中的命令达到恢复数据的目的。主要作用:解决了数据持久化的实时性。
优点:一般 1s 同步一次,最多丢失 1s 的数据。同步日志是使用 append-only 模式,写入快,并且日志文件不易破损,尾部破损也容易恢复。并且 AOF 文件大小不会影响性能。
缺点:AOF 日志一般比 RDB 文件大,同时以前 AOF出过 Bug导致数据没有完整的恢复。
一般我们选择的话,不能单单使用 RBD 会丢失许多数据,也不能单单使用 AOF 恢复速度比较慢,也容易有 bug。推荐同时使用,AOF 保证数据不丢失,RBD 做冷备,一旦 AOF 丢失或者不可用的时候可以用于快速恢复。
3、Redis过期策略有哪些?
3.1、Redis的过期策略
我们都知道,Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间。Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理。
过期策略通常有以下三种:
- 定时过期:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好;但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。
- 惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
- 定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。(expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。)
3.2、AOF和RDB对过期key的处理
1、RDB对过期key的处理
过期key对RDB没有任何影响
- 从内存数据库持久化数据到RDB文件
持久化key之前,会检查是否过期,过期的key不进入RDB文件。 - 从RDB文件恢复数据到内存数据库
数据载入数据库之前,会对key先进行过期检查,如果过期,不导入数据库(主库情况)Redis中同时使用了惰性过期和定期过期两种过期策略。
2、AOF对过期key的处理
过期key对AOF没有任何影响
- 从内存数据库持久化数据到AOF文件:
当key过期后,还没有被删除,此时进行执行持久化操作(该key是不会进入aof文件的,因为没有发生修改命令)。
当key过期后,在发生删除操作时,程序会向aof文件追加一条del命令(在将来的以aof文件恢复数据的时候该过期的键就会被删掉)。 - AOF重写
重写时,会先判断key是否过期,已过期的key不会重写到aof文件。
4、Redis的内存淘汰策略?
Redis的内存淘汰策略是指在Redis的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。
- noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。
- allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。
- allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。
- volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
- volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
- volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。
5、缓存穿透、缓存击穿、缓存雪崩解决方案?
5.1、缓存穿透
访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB会挂掉。
解决方案:
- 采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤;
- 访问key未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间。
5.2、缓存击穿
一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。
解决方案:
在访问key之前,采用SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key。
5.3、缓存雪崩
大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。
解决方案:
可以给缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效。
6、缓存和数据库不一致、主从不一致怎么办?
6.1、缓存和数据库不一致?
最经典的缓存+数据库读写的模式,就是 Cache Aside Pattern。
- 读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
- 更新的时候,先更新数据库,然后再删除缓存。
6.2、主从库不一致?
(1)强制读主,高可用主库,用缓存提高读性能
(2)在cache里记录哪些记录哪些必须读主库,如果缓存中没有主键,则到对应的从库读取。
7、Redis的主从复制如何实现?
- 命令slaveof。
优点:无需重启。缺点:不便于管理
// 命令行使用
slaveof ip port // 使用命令后自身数据会被清空,但取消slave只是停止复制,并不清空
- 修改配置。
优点:统一配置。缺点:需要重启
// 配置文件中配置
slaveof ip port
slave-read-only yes //只允许从节点进行读操作
7.1、全量复制
用于初次复制或其它无法进行部分复制的情况,将主节点中的所有数据都发送给从节点,是一个非常重型的操作,当数据量较大时,会对主从节点和网络造成很大的开销 。
7.2、部分复制
部分复制是Redis 2.8以后出现的,用于处理在主从复制中因网络闪断等原因造成的数据丢失场景,当从节点再次连上主节点后,如果条件允许,主节点会补发丢失数据给从节点。因为补发的数据远远小于全量数据,可以有效避免全量复制的过高开销,需要注意的是,如果网络中断时间过长,造成主节点没有能够完整地保存中断期间执行的写命令,则无法进行部分复制,仍使用全量复制。
8、redis的集群模式如何实现?redis的key是如何寻址的?
https://blog.csdn.net/weixin_43145146/article/details/101065717