Redis扫盲
Redis
缓存中间件
基础篇
键值数据库 key Value
是NoSql数据库
非结构化、无关联的、非SQL、BASE(无法满足ACID)
命令执行是单线程,符合原子性。
低延迟、速度块(基于内存,IO多路复用,良好的编码)
支持数据的持久化(定期把数据写到磁盘)
支持主从集群、分片集群
支持多语言客户端
一、常用命令
1.停止服务
停止 Redis 服务
sudo systemctl stop redis检查服务状态
sudo systemctl status redis
2.启动服务
redis-server#指定配置文件启动
redis-server redis.conf
3.查看运行状态
ps -ef | grep redis
4.打开客户端
redis-cli -a 200112
5.通常命令
#查看符合模板的所有key
keys
#删除指定的一个key
DEL
#判断key是否存在
exists
#给key设置一个有效期
EXPIRE
#查看key的剩余有效期
TTL
二、常见数据类型
Redis 支持多种数据类型,每种类型针对不同的使用场景设计,以下是常见的五种核心数据类型及其特点:
String(字符串)
• 特点:二进制安全的字符串,可存储文本、序列化数据或数字。
• 常用命令:
• SET key value
/ GET key
• INCR key
(原子性递增)
• MSET
/ MGET
(批量操作)
• 应用场景:
• 缓存HTML片段、用户会话(Session)。
• 计数器(如文章阅读量)。
• 分布式锁(通过 SETNX
)。
最大是512M
SET、GET、MSET、MGET。增减删除
INCR。让整型key+1
java对象序列化为json字符串,然后存储。
Hash(哈希表)
• 特点:键值对集合,适合存储对象。
• 常用命令:
• HSET key field value
/ HGET key field
• HGETALL key
(获取所有字段和值)
• HINCRBY
(字段数值增减)
• 应用场景:
• 存储用户信息(如用户ID为Key,字段为姓名、年龄等)。
• 商品详情页的属性存储。
可以对字段做CRUD
List(列表)
• 特点:有序的字符串列表,支持双向操作(类似双向队列)。
• 常用命令:
• LPUSH key value
/ RPOP key
(左右插入和弹出)
• LRANGE key start end
(范围查询)
• BLPOP
(阻塞式弹出)
• 应用场景:
• 消息队列(生产者-消费者模型)。
• 最新消息排行(如朋友圈动态)。
• 历史记录(如用户浏览日志)。
Set(集合)
• 特点:无序且唯一的字符串集合,支持交并差运算。
• 常用命令:
• SADD key member
/ SMEMBERS key
• SINTER key1 key2
(交集)
• SISMEMBER key member
(判断存在性)
• 应用场景:
• 标签系统(如文章标签)。
• 共同好友(交集运算)。
• 去重(如UV统计)。
Sorted Set(有序集合)
• 特点:成员关联一个分数(score),按分数排序且唯一。
• 常用命令:
• ZADD key score member
/ ZRANGE key start end
• ZRANK key member
(获取排名)
• ZRANGEBYSCORE
(按分数范围查询)
• 应用场景:
• 排行榜(如游戏分数排名)。
• 延迟队列(用时间戳作为分数)。
• 范围查询(如价格区间筛选)。
其他扩展类型(需Redis模块支持)
• Bitmaps:通过位操作实现布隆过滤器、用户签到。
• HyperLogLog:基数统计(如UV去重)。
• Streams:消息流(类似Kafka,用于时序数据)。
选择依据
• 读写模式:高频写入用List,需排序用Sorted Set。
• 查询需求:精确查询用Hash,范围查询用Sorted Set。
• 数据量:小对象用String,大对象用Hash分字段存储。
合理利用这些类型能显著提升Redis性能和资源利用率。
常见面试题
一、缓存穿透
缓存穿透说简单点就是大量请求的 key 是不合理的,根本不存在于缓存中,也不存在于数据库中。这就导致这些请求直接到了数据库上,根本没有经过缓存这一层,对数据库造成了巨大的压力,可能直接就被这么多请求弄宕机了
解决办法
1.缓存无效 key
表名:列名:主键名:主键值作为key
2.布隆过滤器
把所有可能存在的请求的值都存放在布隆过滤器中,当用户请求过来,先判断用户发来的请求的值是否存在于布隆过滤器中。不存在的话,直接返回请求参数错误信息给客户端,存在的话才会走下面的流程。
3.接口限流
二、缓存击穿
缓存击穿中,请求的 key 对应的是 热点数据,该数据 存在于数据库中,但不存在于缓存中(通常是因为缓存中的那份数据已经过期)。这就可能会导致瞬时大量的请求直接打到了数据库上,对数据库造成了巨大的压力,可能直接就被这么多请求弄宕机了。
举个例子:秒杀进行过程中,缓存中的某个秒杀商品的数据突然过期,这就导致瞬时大量对该商品的请求直接落到数据库上,对数据库造成了巨大的压力。
解决办法
- 永不过期(不推荐):设置热点数据永不过期或者过期时间比较长。
- 提前预热(推荐):针对热点数据提前预热,将其存入缓存中并设置合理的过期时间比如秒杀场景下的数据在秒杀结束之前不过期。
- 加锁(看情况):在缓存失效后,通过设置互斥锁确保只有一个请求去查询数据库并更新缓存
三、缓存雪崩
缓存在同一时间大面积的失效,导致大量的请求都直接落到了数据库上,对数据库造成了巨大的压力。 这就好比雪崩一样,摧枯拉朽之势,数据库的压力可想而知,可能直接就被这么多请求弄宕机了
缓存中的大量数据在同一时间过期,这个时候突然有大量的请求需要访问这些过期的数据。这就导致大量的请求直接落到数据库上,对数据库造成了巨大的压力。
针对 Redis 服务不可用的情况:
- Redis 集群:采用 Redis 集群,避免单机出现问题整个缓存服务都没办法使用。Redis Cluster 和 Redis Sentinel 是两种最常用的 Redis 集群实现方案
- 多级缓存:设置多级缓存,例如本地缓存+Redis 缓存的二级缓存组合,当 Redis 缓存出现问题时,还可以从本地缓存中获取到部分数据。
针对大量缓存同时失效的情况:
- 设置随机失效时间(可选):为缓存设置随机的失效时间,例如在固定过期时间的基础上加上一个随机值,这样可以避免大量缓存同时到期,从而减少缓存雪崩的风险。
- 提前预热(推荐):针对热点数据提前预热,将其存入缓存中并设置合理的过期时间,比如秒杀场景下的数据在秒杀结束之前不过期。
- 持久缓存策略(看情况):虽然一般不推荐设置缓存永不过期,但对于某些关键性和变化不频繁的数据,可以考虑这种策略