没有理想的人不伤心

Redis

2025/09/03
1
0

入门

为什么要用 redis:(高性能、多功能、高可靠性)

  1. 高性能:redis 是基于内存的数据库,读取速度非常快,远高于磁盘存储的数据库(如 mysql),尤其适合处理高频访问的数据
  2. 丰富的数据结构支持:支持 string、hash、list、set 等多种数据结构
  3. 持久化机制:提供快照(RDB)、日志(AOF)两种持久化方式,保证内存数据的高效访问的同时,又能避免宕机后的数据丢失
  4. 高可用和分布式支持:支持主从复制、哨兵模式(自动故障转移)和 Redis Cluster(分片集群),能轻松实现高可用部署和水平扩展,满足大规模业务的需求。
  5. 提供了原子性操作,避免在了并发场景的竞态问题

怎么用:
核心操作:

  • Stringset key value(存)、get key(取)、incr key(自增),适合存储简单值(如用户 token、计数器)。
  • Hashhset key field value(存字段)、hget key field(取字段),适合存储对象(如用户信息: user:1 {name: "xxx",age:20})。
  • Listlpush key elem(左插)、rpop key(右取),适合实现队列 / 栈(如消息队列、最新消息列表)。
  • Setsadd key elem(添加元素)、sinter key1 key2(交集),适合去重或关系计算(如共同好友)。

redis:键值型数据库,非关系型数据库

1736161060598-b72a4fe3-f6c3-4362-8c7d-259290bb3d08.png

value 的数据类型:

1736249512210-93662fa2-4156-4edd-8273-90c458f08ae0.png

命令行文档:help @组名 就会列出当前组下的命令

当 key 值冲突时,如 user 和 product 都有一个 id 字段,但是在 redis 的一张表中并不能存在两个 id 的键

1736254305265-82a36ce8-289d-4c9c-99ae-19996999eb73.png

通用命令

1736250066441-442212f0-781d-42fd-87f0-77ceba9d8ee7.png

数据类型

是 value 的类型

String 类型

1736252559476-85f1c101-22dd-450e-ba1e-41e40fbe03e2.png

1736252887228-6d7bf6a5-348e-4833-9389-6f0656c3b1fe.png

Hash 类型

v 里套 k-v。

1736335928107-112c4919-3a40-4017-aaad-a9a4d637e44b.png

1736335968768-fd1d6f20-f6e7-4189-81b1-a1ae6a5ed9e9.png

List 类型

双向链表

1736337798507-ed1406fa-8b36-4ff1-9ff3-3159e6a80a2a.png

1736337929973-2ee83c4e-e731-4875-ac16-3251abcc47b1.png

Set 类型

集合

1736338279789-0f168d97-b8bc-4141-8787-8ce4ddceac7c.png

1736338565369-5d0e19ed-033a-4420-b624-bea796af54c8.png

SortedSet

1736338775660-a4aa5ec4-7088-4574-8b98-2b10fec83b53.png

1736338959497-bf347a75-3b57-4de2-a1e8-307b51717a17.png

Redis 的产生

随着数据量增大,存储的压力增大,数据从单表演变为分库分表,MySQL 从单机演变为集群

1732190078020-6561548c-6ca6-4235-977c-ca0477204f7f.png

且数据分冷热,热数据是经常被访问到的数据。那么将热数据存储到内存中能大大提高性能和效率
下图是 redis 的读写操作流程

1732190182076-bbe51864-9af5-4f68-9ed9-8c49e805ac17.png

Redis 的工作原理

既然 redis 将数据存在在内存中,那么系统断电时,数据如何确保不丢失呢?

在 redis 操作数据的同时,会将操作命令追加到AOF文件中,而 AOF 文件存储在磁盘并不会丢失

RDB 文件记录了全部的数据信息(全量数据),启动时 redis 先去读取 RDB 文件加载数据,然后对比 AOF 文件有无数据没有被操作,有就从 AOF 文件中加载对应的操作

这样就保证了 redis 的启动与之前的状态一致。

1732190444179-a46777b4-d49f-4f6a-8323-ca9754fc7364.png

Redis 是单线程处理的系统

1732191025212-c48a197a-0a42-46f4-bdfa-b9138575133e.png

典型场景:

  1. 缓存(最核心场景)

    • 存储高频访问的热点数据(如商品详情、用户信息),减轻数据库压力。
    • 注意:需设计缓存更新策略(如 Cache Aside 模式:更新数据库后删除缓存),避免缓存穿透(缓存和数据库都无数据,用布隆过滤器拦截)、缓存击穿(热点 key 过期,加互斥锁)、缓存雪崩(大量 key 同时过期,加随机过期时间)。
  2. 会话存储

    • 存储用户登录会话(如 token),替代传统的服务器本地 session,支持分布式系统中多服务共享会话(如微服务架构下的单点登录)。

为什么适合会话存储的场景:

  1. 会话(Session)是用户登录后服务器生成的临时凭证,几乎所有用户操作(如页面跳转、接口请求)都需要验证会话有效性,属于高频访问数据
  2. 会话有明确的 “时效性”(如用户 30 分钟无操作自动失效),需要自动清理过期会话以释放资源。Redis 内置了键过期机制expire key seconds命令),支持为会话设置精确的过期时间、
  3. 分布式支持解决会话共享问题
  1. 简易消息队列
    • 用 List 的lpush(生产者发消息)和rpop(消费者取消息)实现简单队列,适合低延迟、非高可靠要求的场景(高可靠需用专业 MQ 如 RabbitMQ)。

常见面试题:

  1. Redis 为什么是单线程的?单线程为什么能支持高并发?
    答题思路:
  • 单线程原因:Redis 的性能瓶颈是内存而非 CPU,单线程可避免多线程切换的开销(上下文切换、锁竞争),简化设计。
  • 高并发原因:
    • 基于内存操作,避免磁盘 IO 阻塞;
    • 采用 IO 多路复用模型(如 epoll/kqueue),单线程可同时处理多个客户端的网络 IO 请求(非阻塞 IO);
    • 核心操作(如 set、get)是原子性的,无需加锁,执行效率高。
  1. Redis 的持久化机制有哪些?RDB 和 AOF 的区别是什么?如何选择?
    答题思路:
  • 两种机制:RDB(快照)和 AOF(Append Only File)。
  • 区别:
    • RDB:按配置的触发条件(如定时、手动 save/bgsave)生成内存数据的二进制快照;优点是体积小、恢复快;缺点是可能丢失最近一次快照后的数(如宕机)。
    • AOF:记录所有写命令(如 set、hset)到日志文件,恢复时重新执行命令;优点是数据安全性高(可配置每秒 / 每次写同步);缺点是文件体积大、恢复慢。
  • 选择:追求性能和快速恢复用 RDB;追求数据安全性(如金融场景)用 AOF;生产环境常两者结合(RDB 做全量备份,AOF 做增量补充)。
  1. Redis 的过期键删除策略是什么?内存满了之后会怎么处理?
    答题思路:
  • 过期删除策略(混合策略):
    • 惰性删除:访问键时才检查是否过期,过期则删除(节省 CPU,可能浪费内存)。
    • 定期删除:每隔一段时间随机扫描部分过期键并删除(平衡 CPU 和内存)。
  • 内存满时(maxmemory限制):触发内存淘汰策略,按配置删除部分键,常见策略:
    • volatile-lru:从过期键中删除最近最少使用的;
    • allkeys-lru:从所有键中删除最近最少使用的;
    • volatile-ttl:删除过期键中剩余时间最短的;
    • 其他(如 LFU、随机等)。
  • 注意:若淘汰策略为noeviction(默认),则不删除键,拒绝所有写操作。