Day17:Redis 1

目标

1
2
3
4
5
1. Redis 为什么快(★★★★★)
2. Redis 的五种基本数据结构(★★★★★)
3. String 底层与应用(★★★★☆)
4. Hash、List、Set、ZSet 的使用场景(★★★★★)
5. 结合你的项目

Redis 快主要有四个原因

  1. 基于内存(★★★★★)
    数据放在内存。不用磁盘 IO。
    而数据库最大的耗时就是磁盘。

  2. 单线程模型(★★★★★)
    Redis 6 之后引入了 I/O 多线程,但:命令执行仍然是单线程。
    因为Redis 操作的是共享内存。
    Redis采用单线程顺序执行没有锁竞争。

  3. I/O 多路复用(★★★★★)
    例如个10000客户端。传统线程模型10000线程。Redis一个线程管理10000连接。Linux提供epoll哪个Socket有数据,Redis处理哪个,所以CPU几乎不空转。

  4. 数据结构设计优秀

例如Hash、ZSet、SkipList、压缩列表(旧版本)、ListPack(新版本)。很多操作都是O(1)。

Redis 五种基本数据结构

类型 场景
String 缓存、计数器
Hash 用户信息
List 消息队列(简单)
Set 去重
ZSet 排行榜

1. Redis 为什么快?

  1. 基于内存,没有磁盘 IO
  2. 采用单线程执行命令,没有线程切换和锁竞争
  3. 使用 I/O 多路复用(epoll),能够高效处理大量网络连接
  4. 内部数据结构设计高效,大部分操作时间复杂度为 O(1)

2. 为什么 Redis 采用单线程?

Redis 的性能瓶颈主要在网络 IO 和内存访问,而不是 CPU。
多线程带来的收益有限,但会引入锁竞争和线程切换成本,因此 Redis 选择单线程执行命令。

3. 五种数据结构分别适合什么场景?

String 缓存、计数器
Hash 用户信息
List 消息队列(简单)
Set 去重
ZSet 排行榜

4. String 为什么最常用?

  1. 适用范围最广

  2. Redis 很多核心命令都是基于 String
    例如:

    1
    2
    3
    4
    5
    6
    7
    SET
    GET
    SETEX
    SETNX
    INCR
    DECR
    APPEND

5. Redis 和 HashMap 有什么区别?

HashMap Redis
JVM内存 独立进程
只能本地访问 支持网络访问
无持久化(默认) 支持 RDB、AOF
无过期机制 支持 TTL
单机 可主从、集群
Java 数据结构 内存数据库

HashMap 是 Java 的内存数据结构;Redis 是独立运行的内存数据库,支持网络访问、持久化、高可用和丰富的数据管理能力。

Day18:Redis 2

目标

1
2
3
4
5
1. 缓存穿透(★★★★★)
2. 缓存击穿(★★★★★)
3. 缓存雪崩(★★★★★)
4. Redis 过期策略(★★★★★)
5. Redis 淘汰策略(★★★★☆)

缓存穿透(Cache Penetration)

缓存穿透指大量请求查询不存在的数据,由于缓存没有命中,请求直接访问数据库,导致数据库压力增大。

解决方案:

方案一:缓存空对象(★★★★★)

方案二:布隆过滤器(★★★★★)
不存在的数据可能说存在,但是存在的数据一定存在。

缓存穿透是大量请求查询不存在的数据,导致请求绕过缓存直接访问数据库。解决方式有缓存空对象和布隆过滤器。

布隆过滤器由位数组和多个Hash函数组成,添加元素时通过多个Hash函数计算位置并置1,查询时检查这些位置是否全部为1。如果有一个为0,则一定不存在;全部为1则可能存在。它空间效率高,但存在哈希碰撞导致的误判问题,通常用于缓存穿透、去重等场景。

缓存击穿(Cache Breakdown)

缓存过期时,突发高并发量请求。

解决方案:

方案一:互斥锁(★★★★★)
只允许一个请求查询数据库。

方案二:热点数据永不过期
例如,热门配置不设置TTL,后台主动更新。

缓存雪崩(Cache Avalanche)

大量缓存同时失效。

解决方案:

方案一:TTL 加随机值

方案二:缓存预热
系统启动提前加载热点数据。

方案三:限流降级

三者区别

问题 原因 重点
缓存穿透 请求缓存不存在的数据 null数据
缓存击穿 缓存过期 互斥锁
缓存雪崩 大量key同时过期 随机TTL

Redis 过期策略

Redis采用惰性删除 + 定期删除。

  1. 惰性删除
    访问这个key发现过期,才删除。
  2. 定期删除
    Redis周期性随机抽取一部分过期key删除。

Redis 淘汰策略(Key eviction)

如果Redis内存满了怎么办?

  1. noeviction:不删除。直接报错

  2. allkeys-lru(★★★★★):通过LRU算法驱逐最久没有使用的键

  3. volatile-lru:首先从设置了过期时间的键集合中驱逐最久没有使用的键

Redis 常用 allkeys-lru,通过 LRU 算法淘汰最近最少使用的数据。

1. 什么是缓存穿透?你的 GIS 平台怎么解决?

缓存穿透是查询一个不存在的key,然后请求落到了数据库。我会使用布隆过滤器先判断key是否存在。或者把null缓存起来。

2. 什么是缓存击穿?为什么需要分布式锁?

缓存过期时,突发高并发请求。当程序分布式部署的时候,只有分布式锁才能真正只允许一个线程访问数据库。

3. 什么是缓存雪崩?为什么 TTL 加随机值?

大量key同时过期。当ttl加了随机值后就不会同时过期了。

4. Redis 为什么不一定立即删除过期 Key?

空间和性能之间的权衡。每个 key到时间立即删除需要大量定时任务。所以采用惰性删除 + 定期删除。

5. 如果你的 GIS 平台 10000 用户同时查询同一个分析结果,Redis过期你怎么设计?

这就是缓存击穿。我会对查询数据库的操作加锁,只允许一个线程去查询数据库,并把数据立刻缓存起来。其他线程要再次检查是否存在缓存。

6. Redis 分布式锁为什么不用 SETNX + EXPIRE 两条命令?

因为不是原子操作,SETNX成功但是服务宕机,EXPIRE没有执行。锁永不过期。

7. Redisson 分布式锁为什么比 SETNX 更好?

  1. 自动续期(看门狗机制)
  2. 可重入(ReentrantLock)
  3. 释放安全,不会删除别人的锁。

Day19:Redis 3

目标

1
2
3
4
5
6
1. Redis 为什么需要持久化(★★★★★)
2. RDB 和 AOF 区别(★★★★★)
3. Redis 主从复制(★★★★★)
4. Redis 哨兵 Sentinel(★★★★☆)
5. Redis Cluster 集群(★★★★☆)
6. Redisson 分布式锁原理(★★★★★)

Redis 为什么需要持久化

Redis本质上是内存数据库。一旦程序崩溃内存就会清空导致丢数据。所以需要持久化

两种持久化方案

  1. RDB(Redis Database)
    类似拍快照,隔一段时间保存一次。
    优点是文件小恢复快,但是可能丢数据。
  2. AOF(Append Only File)
    核心思想是记录命令。重启时把执行过的命令再执行一遍就恢复到原来的状态了。
    AOF 缺点文件会越来越大,恢复慢。

    AOF有三种刷盘策略:
    • 每条命令立即落盘:最安全但是最慢
    • 每秒刷一次:Redis默认推荐
    • 交给操作系统:性能高。风险大。
      生产环境一般采用 everysec,在性能和数据安全之间取得平衡

RDB vs AOF

RDB AOF
方式 快照 记录命令
数据安全
文件大小
恢复速度
性能影响 稍高

RDB 是定期生成数据快照,恢复速度快但可能丢失最近数据;AOF 记录每次写命令,数据安全性更高但文件更大、恢复速度较慢。

集群问题

Redis集群解决单机容量和单机性能瓶颈。

  1. Redis 主从复制
    Master负责写,Slave复制数据,通常读走 Slave。
    第一次同步全量同步,后续增量同步。

  2. Redis Sentinel
    主、从、哨兵。主从继续复制。哨兵(集群管理者)监控,主挂重新选举一个主。(Sentinel 自己也是集群)

    Sentinel主要职责:

    1. 监控
      判断 Master 是否故障。
    2. 选主
      从 Slave 中选择新的 Master。
    3. 通知
      告诉客户端新的 Master 地址。
  3. Redis Cluster
    不同key存到不同机器。只要key相同就还是单线程操作,并发安全还是可以保证。

1. RDB 和 AOF 有什么区别?为什么 Redis 默认不只使用 AOF?

rdb相当于数据库快照,每隔一段时间就生成一个快照。优点是备份恢复速度快。缺点是备份间隔时间服务器宕机会丢数据。

aop是把所有命令都记录下来,当重启后把这些命令都执行一遍就恢复上次的状态。
但是缺点是命令越来越多,文件越来越大,恢复慢。

RDB + AOF 可以结合。RDB 用于快速恢复,AOF 保证更高数据安全。

2. Redis 主从复制解决什么问题?

  1. 读压力
    主从复制主要解决读压力。请求落到不同的服务器。

  2. 高可用基础
    宕机后数据丢失或者无法访问。Master 写,Slave 读。

3. Master 挂了以后,为什么需要 Sentinel?

否则不知道选举谁当新的master,sentinel的职责就是监控,选择新的master。

4. Redis Cluster 为什么需要 Hash Slot?

不同的key分配到不同的机器里。每个节点仍然单线程执行命令。但是不同节点可以并行处理。

5. 你的空间分析任务, 一个任务 ID:1001。两个服务器同时收到执行请求。如何利用 Redisson 防止重复执行?

对请求参数比如任务id作为key,使用redisson加锁。获取到锁的线程再次确认任务状态,然后执行任务。没有获取到锁的放弃执行。

6. 为什么 Redisson 不直接 DEL lock?

怕删除了别人加的锁。

7. Redisson Watch Dog 是干什么?

避免任务没结束锁提前失效。

Redisson看门狗机制用于防止业务执行时间超过锁过期时间导致锁提前释放。
获取锁后,Redisson会启动后台续期线程,默认每10秒自动延长锁有效期,直到业务完成释放锁。