Redis

type
Post
status
Published
date
Feb 20, 2026
slug
redis
summary
tags
category
Java Web
icon
password
Place

数据结构

5大基本数据类型,6大底层结构
notion image
  1. String是最常用的数据结构,一般key-value都会使用他
  1. List主要可以用来做简易版的消息队列,比如说异步发送邮件、短信提醒
  1. Hash因为他O(1)的查询和插入,适合需要对字段频繁查询或者改动的情况,比如说购物车
  1. Set是一个无序唯一集合,并且他可以进行交并差集,他主要适用于统计方面的,比如说今日新增用户,今日留存用户等
  1. Zset他因为有个权重,所以他适合对特定条件进行排序的情况嘛,比如说按时间排序

跳表

  1. 是以空间换时间的方式优化了查询效率
  1. 跳表是一种多层次的链表结构
  1. 我们要查询一个数时,先在最上层进行查找,在通过down指针逐层向下,其查询的平均时间复杂度为O(logn)

缓存读写

3中常见的缓存读写

只读:旁路缓存
读写:同步写回,异步写回

旁路缓存

:从 cache 中读取数据,读取到就直接返回,cache 中读取不到的话,就从 db 中读取数据返回,再把数据放到 cache 中。
:先更新 db然后直接删除 cache 。
Q1: 在写数据的过程中,可以先删除 cache ,后更新 db 么?
答:不行,在这两个操作之间,如果有查询的话,那么脏数据会被写会缓存。
Q2: 在写数据的过程中,先更新 db,后删除 cache 就没有问题了么?
答:会有问题,但是因为缓存的更新比数据库快多了,所以几率小很多。

同步写回

读是一样的。
写请求发给缓存的同时,也会发给后端数据库进行处理,等到缓存和数据库都写完数据,才给客户端返回。
这样保证了数据一致性,但是同步直写会降低缓存的访问性能。

异步写回

读是一样的
所有写请求都先在缓存中处理。等到这些数据要被从缓存中淘汰出来时,缓存将它们写回后端数据库。
这样一来,处理这些数据的操作是在缓存中进行的,很快就能完成。只不过,如果服务器宕机就会有数据丢失的风险了。

如何保证双写一致性

  • 旁路缓存就是一个非常好的操作
  • 延迟双删:即在删缓存,更新数据库之后休眠一段时间,再删除缓存

生产问题

缓存穿透

造成原因:请求的数据在缓存和数据库中都不存在
解决方法:
  1. 后端代码逻辑中做好参数校验
  1. 缓存空值,当查询数据库发现值不存在时,那么往缓存中塞入过期时间较短的标识,防止同一个 ID 反复穿透

缓存雪崩

造成原因:缓存中大量Key同时到了过期时间
解决方法:
  1. 我们可以在设置过期时间时,加一个较小的随机数

缓存击穿

造成原因:某个热点Key过期了,导致一瞬间大量流量打到数据库。
解决方案:
  1. 逻辑过期,设置缓存时,不给 Redis 设置真正的 TTL,而是在 Value 内部字段里写一个“过期时间”。线程发现逻辑过期了,主线程会尝试获取锁,这个锁是防止多个冗余的异步线程去同时更新数据。当前线程以及在更新完成前的其他线程直接返回旧数据(脏数据)

内存管理(过期淘汰)

notion image
用的最多的就是allkeys-lru。还是依据不同业务不同需求来确定

持久化

RDB快照机制

rdb是一个快照文件,记录的是某一时刻的内存数据
RDB 快照可以通过手动命令(如 SAVE 或 BGSAVE)或配置文件中的时间策略(一定是bgsave)来生成。

AOF追加机制

Redis 就会将该命令写入到 AOF 文件中

Redis操作对象

yml文件,才发现不和mysql一样,不需要账号和密码,离谱呀。说是上线之后
3个操作对象,StringRedisTemplate,RedisTemplate,Redission。
Redission需要单独在来个依赖
RedisTemplate一般需要配置文件,但StringRedisTemplate就不用,因为他key和value规定了只能用字符串
配置好两个就直接用
  • 99%的生产环境:优先选择 Redisson
  • 学习/测试环境:可以用 RedisTemplate 理解原理
上一篇
Java
下一篇
MySQL
Loading...