1 Redis 概念 —— 谈谈什么是 Redis
Redis是 内存 中的以 key-value 形式存储的非关系型数据库,它用作数据库、缓存、和消息中间件。
【数据库】说明 Redis 支持持久化技术
【缓存】涉及 5 种数据类型
【消息中间件】涉及 Redis 消息发布订阅模式 (通过 SUBSCRIBE 与 PULISH 命令)

2、Redis 的特点/优点
1)存储于内存,数据读取速度快;
2)Redis 支持数据备份与恢复,即持久化技术
3)Redis 提供丰富的数据存储类型,分别是 string list hash set zest
【字符串(普通)、链表(时间线朋友圈)、哈希(通讯录)、集合(共同好友--支持交并比操作)、权重集合】
4)操作的原子性。

Redis 的每个操作都是原子性的,但 Redis 事务并不是原子性。Redis 的一个事务以 MULTI 为开始, 中间是命令语句入队,最后以 EXEC 命令执行。
可以理解为 Redis 的事务就是一个批量处理语句,某个命令的执行失败,不会影响到其他命令。

3、谈谈 Redis 的 5 种数据类型及应用场景
Redis 支持 5 种 数据类型:
string(字符串);hash(哈希);list(列表);set(集合);zset(sorted set:有序集合)
1)string:二进制安全。可以包含任何数据,比如jpg图像或序列化的对象,一个键最大能支持512M

  • 应用场景:图片、视频、音频的存取

2)Hash:一个 Hash,就是一个 field 与 value 的映射表

  • 应用场景:在通讯录场景中,每个用户可以用一个哈希表表示,用户的属性与值进行映射。

3)List:列表,底层用双向链表实现。

  • 场景:最新消息排序功能(如朋友圈的时间线)

4)Set:哈希表实现,增删改查时间复杂度均为O(1),为集合提供交集、并集、差集等操作

  • 应用场景:1)寻找共同好友。2)利用唯一性,寻找访问网站的所有独立ip

5)zset(有序集合):与set相同,是string类型的集合,特点是给每个元素关联一个double类型的分数。通过分数对元素进行从小到大排序。

  • 应用场景:排行榜

4、Redis的应用场景
在上述 5 种数据类型分别对应的典型应用场景外,还有:
1)针对热点数据进行缓存:【内存】;
2)对于特定限时数据的存放【设置 Redis 分布式锁的过期时间】

5、谈谈 Redis 分布式锁

5.1 概念:Redis 分布式锁是一种控制分布式系统不同进程对共享资源的排他性访问的锁。(通过 setnx (set if not exists) 来获取一个分布式锁)
5.2 应用场景:抢红包、商品秒杀等,用来防止库存超卖。(在这些场景下,除了需要设计限流、异步、排队等优化方式外)
5.3 分布式锁特征:
1)互斥性:任意时刻只有一个客户端持有锁;
2)锁超时释放:持有锁超时可以释放,防止不必要的资源浪费,也防止死锁;
3)安全性:锁只能被持有的客户端删除,不能被其他客户端删除;
4)可重入性:一个线程若获取了锁之后,可以再次对其请求加锁。

5.4 Redis分布式锁方案:Redisson框架
只要线程加锁成功,就会启动看门狗后台线程,这个后台线程会每隔10s检查一下,若线程还持有锁,就不断延长锁key的生存时间【以哈希映射结构存储于Redis】。因此,Redisson解决了锁过期释放、业务没执行完的问题。

6 Redis 与 Memcache 的区别
什么是Redis?什么是 Memcache?
Redis是内存中的数据结构存储系统,它用作数据库、缓存、和消息中间件。
Memcache是高性能、分布式内存对象缓存系统。
区别:
(1)数据结构:Memcache仅能支持简单的K-V形式,Redis支持的数据类型更多
(2)Memcache 支持多线程,Redis 支持单线程
(3)Memcache 不支持持久化,Redis 支持持久化
(4)Memcache 服务器需要通过 hash 一致化来支撑主从结构,Redis 做主从结构
(5)Memcache 更多是作为一个数据缓存系统以提升数据的提取效率,Redis 更多是通过数据的持久化、主从架构、数据备份等策略保证数据安全以及高可用。

总结:1)对于简单的 key-value 存储应该选择 MemCache;2)若对数据有持久化要求或对数据类型及处理有要求,应该选择 Redis。

7 Redis 的 2 种持久化技术 / Redis 的 2 种数据备份方式

7.1 RDB 持久化
RDB 保存某一个时间点之前的快照数据。
7.1.1 RDB持久化机制:它将数据库的快照保存在 RDB 二进制文件中。RDB 模式实际上是一个定时器事件,当满足触发条件时,会通过fork()子进程来完成持久化操作。
7.1.2 RDB触发策略
(1)手动触发策略:通过SAVAE 或 BGSAVE命令将内存数据保存到磁盘文件
(2)自动触发策略:
2-1)事件触发:设置一定事件后自动执行RDB(例如在一定时间内至少更新了多少条数据就自动执行);
2-2)主从复制触发:如采用主从复制过程,会自动执行 RDB 持久化

7.1.3 RDB持久化劣势
(1)将数据保存到RDB文件,即执行一次IO操作,资源与时间开销大,若频繁操作,会降低服务器的性能。
(2)如果在持久化过程,服务器突然宕机,可能会导致最后一次持久化数据丢失。
【适用场景】RDB数据持久化适合于大规模的数据恢复,并且还原速度快。

7.2 AOF 持久化。
AOF即追加模式或日志模式,存储的是Redis服务器已经执行过对内存有过修改的命令。这种模式称为“增量复制”。这种持久化方式实时性更好。

7.2.1 AOF 持久化机制 — 类似MySQL 的 redo log
包括写入机制与重写机制。
写入机制:Redis收到修改命令后,会立刻将命令写入内存缓冲区,等到满足触发条件时才将命令从内存写入磁盘。
重写机制:当AOF文件过长时,针对目前数据库中的数据,在不读取原有AOF文件的基础上,重写了一个新的AOF文件,减少文件大小,提高文件“重演”的速度。

7.2.2 AOF持久化策略
(1)每条命令执行一次——always。每执行一次数据修改命令就将命令写入磁盘文件;宕机不丢失任何数据。
(2)每秒的命令执行一次——everysec。每秒将命令写入到磁盘日志文件;宕机只丢失1s的数据。【最常用】

7.2.3 AOF触发策略
(1)手动自动触发策略:BGREWRITEAOF命令
(2)自动自动触发策略:通过配置文件,设置满足一定条件时自动执行AOF重写【例如当AOF文件超过多大时就执行一次重写】

7.3 RDB与AOF持久化技术优缺点对比
(1)RDB全量备份,一次保存整个数据库;AOF增量备份,一次只保存一个修改命令;
(2)RDB每次执行持久化操作的间隔时间较长;AOF默认执行持久化操作的间隔时间为1s
(3)RDB数据保存为二进制格式,还原速度快;AOF以文本格式保存命令,还原速度慢

8 Redis 的3 种高可用架构 / Redis 3 种集群架构
(1)主从复制架构;(2)哨兵架构;(3)Cluster集群架构

8.1 主从模式
一主多从。Redis主机会将自己的数据复制给Redis从机,从而实现主从同步。只有master主机可执行写指令,slave从机只可执行读命令,这种读写分离的模式可以大大减轻Redis主机的数据读取压力,从而提高Redis效率。

主从模式框架图:

redis事务的特殊性 redis事物三大特性_数据

8.1.2 主从架构缺点
1)【最大缺点】不具备自动容错功能,可用性低。若主节点宕机,Redis集群将无法工作,除非人为将从节点提升为主节点。不适合线上生产环境;
2)只有一个主节点,写入能力受到限制;
3)存在数据未能同步的风险,降低了系统的可用性。若主机宕机前有部分数据未能及时同步到从服务器,即使切换主机也无法解决数据不一致问题。

8.2 哨兵架构
哨兵模式是对主从模式不具备自动容错功能的改进。主从模式最大的缺点是不具备自动容错功能,可用性低。哨兵模式通过哨兵监控获取主机的工作状态。当主机发生故障时,哨兵Sentinel会将受监控的从机提升为主服务器。

哨兵模式框架图:

redis事务的特殊性 redis事物三大特性_Redis_02

8.3 Cluster集群架构
Cluster 模式是对主从模式只有一个主节点,写入能力弱的改进。引入 Cluster 可以实现多个节点同时写数据,每个节点实际就是一个主从结构。【考虑 Elasticsearch 的节点概念】

9 Redis 集群的主从复制/主从同步
redis 主从复制是指将主服务器的数据拷贝到从服务器。

9.1 主从复制/主从同步的作用
(1)数据冗余:主从复制实现了数据的热备份,是持久化技术之外的一种数据荣誉方式
(2)故障恢复(服务冗余):当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复。可视为一种服务的冗余
(3)负载均衡:主节点提供写服务,从节点提供读服务,分担服务器负载。尤其在写少读多的场景下,可以大大提高 Redis 服务器的并发量
(4)高可用基石:主从复制是哨兵和集群模式能够实施的基础,因此主从复制是 Redis 高可用的基础。

9.2 主从同步有哪几种方式及具体实现原理
1)全量同步:RDB文件【即将当期数据生产快照,并保存于硬盘】

  • 具体实现原理:
    从服务器先发送连接请求,与主服务器建立连接,然后发送同步信号给主服务器。主服务器生成并发送RDB文件给从服务器,并将缓冲区里的命令同步给从服务器。从服务器接收到RDB文件后,清空自己的数据库,并将RDB文件读取到自己的数据库中。

2)增量同步:主服务器只需将写命令及offset同步给从服务器

9.3 主从复制原理
【主从复制是命令传输或文件传输的过程,涉及两个服务器建立连接的过程,同时传输过程是异步过程,因此很难实现完全实时同步。】
(1)保存主节点信息:从节点服务器内部维护 2 个字段,用于存储主节点的 ip 和 port 信息;
(2)建立 socket 连接:从节点与主节点进行 socket 连接,从节点并未该 socket 建立一个文件事件处理器,负责接收 RDB 文件、命令传播等;
(3)发送 ping 命令:从节点向主节点发送 ping 命令,目的是检查 socket 连接是否可用,以及主节点当前是否能够处理请求。
[1] 若主节点返回 pong:说明socket可用,且主节点可以处理请求,复制过程继续;
[2] 若主节点返回不返回 pong:断开连接并重连
(4)身份验证:从节点向主节点进行身份验证
(5)数据同步阶段【主从复制核心】:从节点向主节点发送 sync 命令,开始同步
(6)命令传播阶段:主节点将自己执行的写命令发送给从节点,从节点接收并执行,从而保证从节点数据的一致性。由于命令传播是异步过程,主从节点很难保持数据实时的一致性。

10 缓存雪崩、缓存穿透、缓存预热、缓存击穿、缓存降级的区别是什么?及解决方案分别是什么?
10.1 缓存穿透
缓存穿透是指用户请求的数据在缓存中不存在即没有命中,在数据库中也不存在,导致用户请求该数据都要去数据库中查询一遍,然后返回空。
若有恶意攻击者不断请求系统中不存在的数据,会导致短时间大量请求落在数据库上,造成数据库压力过大,甚至击垮数据库系统。

  • 解决方案
    (1)布隆过滤器:专门检测集合中是否存在特定的元素【黑名单】
    总结:布隆过滤器认为不在的,一定不会在集合中;布隆过滤器认为在的,可能不在集合中;
    设计思想:布隆过滤器由一个长度为m比特的位数组与k个哈希函数组成的数据结构组成。当向布隆过滤器插入一个元素时,该元素经过k个哈希函数计算产生k个哈希值,以哈希值作为位数组的下标,将所有k个对应的比特值由0置为1。
    (2)返回空对象
    将返回的空对象写到缓存中

10.2 缓存击穿
缓存击穿是指一个热点key在失效的瞬间,被大量的并发请求访问,此时请求穿破缓存,直接请求数据库,就像在屏障(缓存)中凿开了一个洞(到数据库)。
危害:数据库瞬时压力骤增,造成大量请求阻塞。

  • 解决方案:设置热点数据永不过期;加互斥锁

10.3 缓存雪崩 【缓存雪崩是发生了大量的缓存击穿】
缓存雪崩是指缓存中数据大批量到达过期时间,而查询量巨大,请求落到数据库上,引起数据库压力过大甚至宕机。

  • 解决方案:均匀过期(在过期时间上加一个随机数,让过期时间尽量分散);加互斥锁;
    【过期时间的设置作用:1)防止冷数据占用内存开销;2)数据库-缓存数据一致性的保证。在高并发场景下,数据经常被修改。
    10.4 缓存预热
    缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。【shidaxing的elasticsearch也有缓存预热的操作】如果不进行预热,那么 Redis 初始状态数据为空,系统上线初期,对于高并发的流量,都会访问数据库,对数据库造成流量的压力。**优先保证热点数据进行提前加载到缓存。

10.5 缓存降级

【降级、熔断、限流、分流】一起看 。

缓存降级是指缓存失效或缓存服务器挂掉的情况下,不访问数据库,直接放回 默认数据 或访问服务的内存数据。一般会将部分热点数据缓存到服务的内存中。

所谓“降级”是指缓存服务不可用,又不可拒绝服务,所以返回默认值,这种丧失部分功能的操作就是降级

11 Redis 的内存淘汰策略
分为两类数据(设置了过期时间的数据、所有数据),两种淘汰算法(随机淘汰、LRU算法淘汰),共 4 种策略。
当 Redis 最大占用内存用完后,需要进行淘汰处理,才能继续添加数据。
(1)noeviction:对于写请求直接返回错误,不淘汰
(2)allkeys-LRU:从所有的 key 中使用 LRU 算法进行淘汰
(3)volatile-LRU:从设置了过期时间的 key 中使用 LRU 算法进行淘汰
(4)allkeys-Random:对所有的 key 随机淘汰
(5)volatile-Random:对设置了过期时间的 key 中进行随机淘汰

12 分布式ID —— Redis 解决办法

https://zhuanlan.zhihu.com/p/107939861 12.1 什么是分布式 ID
当业务数据量增长到很大的时候,MySQL 主从同步读写分离难以应付,需要对数据库进行分库分表。多个库多个表需要一个全局唯一 ID 来标识一条数据,这个 ID 就叫分布式ID。

12.2 基于 Redis 模式的解决办法
利用 redis 的 incr 命令实现 ID 的原子性自增。
缺点:要考虑到 redis 的持久化问题
1)若是使用 RDB 持久化:RDB 会定时打一个快照进行持久化,但若连续自增,但未来得及持久化,重启 Redis 后会出现 ID 重复的情况,如果业务端用重复的 ID 存数据就会出现问题;
2)若是使用 AOF 持久化:AOF 会对每条命令进行持久化,所以避免了 ID 重复的情况。由于 incr 命令的特殊性,会导致 Redis 重启恢复的数据时间过长。

13 Redis 的网络请求处理方式 / Redis 为什么快
1)Redis 使用的是非阻塞 IO + IO 多路复用 + 单线程轮询方式实现网络请求处理,IO 多路复用同时监听多个读写请求事件,使用单线程避免了线程切换的上下文切换开销。
2)Redis 的底层模型不同,它构建了自己的 VM 机制,对数据的调用会更快。

13.1 Redis 为什么单线程处理?为什么不是多线程?
并不是所有单线程的效率就比多线程效率低。多线程的好处是并发,在一段时间内同时推进多个任务的执行,缺点是需要加锁机制及线程上下文切换开销。
由于 Redis 的数据存储在内存,不存在内存-磁盘交换的过程,因此完全没必要使用多线程,使用多线程反而需要承担线程切换的开销。

14 MySQL 和 Redis 的数据一致性问题
如果涉及到数据更新问题,容易出现缓存和数据库间的数据一致性问题。
1)若先写数据库,再删除缓存。写线程宕机,没有删掉缓存,会导致数据不一致;
2)若先删除缓存,再写数据库。如果还没来得及写数据库,另外个线程读不到缓存,去访问数据库,然后这个数据又会读到缓存,就导致了数据不一致。
策略:
1)延时双删策略
先删除缓存,再写数据库,休眠一段时间,再删除缓存。
优点:保证了数据库-缓存的数据一致性问题;
缺点:增加了写数据库的操作。
2)设置过期时间
设置过期时间是保证一致性的最终解决方案。

Redis 3 种过期策略
1)定时删除
在设置 key 的过期时间的同时,为该 key 创建一个定时器,到期即删除
优点:保证内存尽快被释放;
缺点:1)CPU 时间消耗:若过期 key 很多,删除 key 需要占用 CPU 时间。在 CPU 时间紧张的情况下,应该把 CPU 执行要紧的任务,而不是非要紧的删除 key 操作;2)内存消耗:定时器的创建销毁需要开销
2)惰性删除
key 过期的时候不删除,每次从数据库取 key 的时候检查是否过期,若过期,则删除,返回 null。
优点:(CPU 时间消耗)只在必要时候才执行删除操作,对 CPU 占用少;
缺点:(内存消耗)若大量的 key 都超过过期时间,且在较长一段时间都未被访问,会导致内存泄漏问题
3)定期删除:
每隔一段时间执行一次删除操作,它是定时删除与惰性删除的折中。
优点:1)通过限制删除操作的频率,减少操作对 CPU 的占用;2)避免内存泄漏
缺点: 在内存友好方面,不及定时删除;在 CPU 时间友好方面,不如惰性删除。