Redis
type
Post
status
Published
date
Feb 20, 2026
slug
redis
summary
tags
category
Java Web
icon
password
Place
数据结构
5大基本数据类型,6大底层结构

- String是最常用的数据结构,一般key-value都会使用他
- List主要可以用来做简易版的消息队列,比如说异步发送邮件、短信提醒
- Hash因为他O(1)的查询和插入,适合需要对字段频繁查询或者改动的情况,比如说购物车
- Set是一个无序唯一集合,并且他可以进行交并差集,他主要适用于统计方面的,比如说今日新增用户,今日留存用户等
- Zset他因为有个权重,所以他适合对特定条件进行排序的情况嘛,比如说按时间排序
跳表
- 是以空间换时间的方式优化了查询效率
- 跳表是一种多层次的链表结构
- 我们要查询一个数时,先在最上层进行查找,在通过down指针逐层向下,其查询的平均时间复杂度为O(logn)
缓存读写
3中常见的缓存读写
只读:旁路缓存
读写:同步写回,异步写回
旁路缓存
读 :从 cache 中读取数据,读取到就直接返回,cache 中读取不到的话,就从 db 中读取数据返回,再把数据放到 cache 中。
写:先更新 db然后直接删除 cache 。
Q1: 在写数据的过程中,可以先删除 cache ,后更新 db 么?
答:不行,在这两个操作之间,如果有查询的话,那么脏数据会被写会缓存。
Q2: 在写数据的过程中,先更新 db,后删除 cache 就没有问题了么?
答:会有问题,但是因为缓存的更新比数据库快多了,所以几率小很多。
同步写回
读是一样的。
写请求发给缓存的同时,也会发给后端数据库进行处理,等到缓存和数据库都写完数据,才给客户端返回。
这样保证了数据一致性,但是同步直写会降低缓存的访问性能。
异步写回
读是一样的
所有写请求都先在缓存中处理。等到这些数据要被从缓存中淘汰出来时,缓存将它们写回后端数据库。
这样一来,处理这些数据的操作是在缓存中进行的,很快就能完成。只不过,如果服务器宕机就会有数据丢失的风险了。
如何保证双写一致性
- 旁路缓存就是一个非常好的操作
- 延迟双删:即在删缓存,更新数据库之后休眠一段时间,再删除缓存
生产问题
缓存穿透
造成原因:请求的数据在缓存和数据库中都不存在
解决方法:
- 后端代码逻辑中做好参数校验
- 缓存空值,当查询数据库发现值不存在时,那么往缓存中塞入过期时间较短的标识,防止同一个 ID 反复穿透
缓存雪崩
造成原因:缓存中大量Key同时到了过期时间
解决方法:
- 我们可以在设置过期时间时,加一个较小的随机数
缓存击穿
造成原因:某个热点Key过期了,导致一瞬间大量流量打到数据库。
解决方案:
- 逻辑过期,设置缓存时,不给 Redis 设置真正的 TTL,而是在 Value 内部字段里写一个“过期时间”。线程发现逻辑过期了,主线程会尝试获取锁,这个锁是防止多个冗余的异步线程去同时更新数据。当前线程以及在更新完成前的其他线程直接返回旧数据(脏数据)
内存管理(过期淘汰)

用的最多的就是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...