数据库-Redis:常用语法 / Redis 核心知识技能梳理

Redis 是目前最流行的键值存储数据库,因其高性能、丰富的数据结构和原子操作,成为后端开发中不可或缺的组件。下面从基础到高级,系统性地梳理 Redis 的核心知识与技能。

一、Redis 是什么?

维度 说明 补充/细节
全称 Remote Dictionary Server(远程字典服务器) C 语言编写,开源、内存中的数据结构存储系统
定位 内存中的数据结构存储系统,可用作数据库、缓存和消息中间件 核心定位 :高性能的缓存数据结构服务器
核心特点 基于内存(极快)、单线程(6.0之前)+ I/O多路复用、支持持久化、丰富数据结构 原子性 :所有单命令操作都是原子性的;丰富数据结构是其区别于 Memcached 的核心优势
性能 读写速度可达 10万+ QPS 性能瓶颈通常在网络 I/O,而非 CPU(单线程模型下)
适用场景 缓存、会话管理、排行榜、消息队列、分布式锁、实时分析 不适用场景:需要复杂关系查询、海量数据存储(成本高)、强一致性事务(非 ACID)

二、Redis 支持的数据结构(5+4种,含模块扩展)

类型 底层实现 常用命令 使用场景 复杂度(平均)
String SDS(简单动态字符串) SET/GET/INCR/DECR/SETNX/MSET 缓存对象、计数器、分布式锁、Session O(1)
Hash 压缩列表(ziplist) / 哈希表(hashtable) HSET/HGET/HGETALL/HINCRBY 存储对象(如用户信息)、购物车 O(1)
List 压缩列表(ziplist) / 双向链表(linkedlist) LPUSH/RPUSH/LPOP/RPOP/LRANGE 消息队列、最新消息列表、文章评论 O(1) (头尾), O(N) (中间)
Set 整数集合(intset) / 哈希表(hashtable) SADD/SREM/SMEMBERS/SINTER/SUNION 标签系统、共同好友、抽奖、去重 O(1) (增删查), O(N*M) (交集/并集)
Sorted Set 压缩列表(ziplist) / 跳表(skiplist) ZADD/ZRANGE/ZRANK/ZREVRANGE/ZSCORE 排行榜、延迟队列、优先级队列、带权重的消息 O(log N) (增删查)
Bitmaps String 的位操作 SETBIT/GETBIT/BITCOUNT/BITOP 签到统计、在线状态、用户行为分析、布隆过滤器 O(1)
HyperLogLog 概率数据结构 PFADD/PFCOUNT/PFMERGE 独立访客数(UV)统计、基数估算 O(1)
GEO Sorted Set 实现 GEOADD/GEORADIUS/GEODIST/GEOHASH 附近的人、位置距离计算、地理围栏 O(log N)
Stream Radix Tree + Listpack XADD/XREAD/XGROUP/XACK 专业消息队列、事件溯源、日志收集 O(1) (追加)

三、Redis 底层核心机制

1. 内存管理与数据结构

机制 说明 关键细节
SDS (简单动态字符串) Redis 自定义的字符串实现 二进制安全 :可存储图片等二进制数据;O(1) 获取长度len 字段直接记录;杜绝缓冲区溢出free 字段预分配空间,API 会检查;减少内存重分配:空间预分配和惰性释放策略。
跳表 (Skip List) ZSet 底层实现之一 多层链表结构 :通过"快车道"实现快速查找;实现简单 :相比红黑树,实现和维护更简单;范围查询高效ZRANGE 操作性能优异;空间换时间:需要额外指针存储。
压缩列表 (ziplist) 小数据量时使用的连续内存块 节省内存 :无指针开销,数据紧凑;读写性能 :新增/删除元素可能引发连锁更新(cascade update),导致性能下降;配置阈值hash-max-ziplist-entries 等配置决定何时转为哈希表。
整数集合 (intset) Set 在元素为整数时使用 有序、无重复 :元素按升序排列;升级机制:当插入新类型整数(如从 int16 到 int64)时,会升级整个集合并重新分配内存,此操作不可逆。
对象系统 (RedisObject) 所有数据类型的统一封装 每个对象包含 type, encoding, lru (LRU算法), refcount (引用计数) 等元数据,是 Redis 实现多态和内存回收的基础。

2. 单线程模型 vs 多线程模型 (6.0+)

特性 Redis < 6.0 (单线程) Redis >= 6.0 (多线程 I/O)
命令执行 单线程,避免了锁竞争和上下文切换开销 核心命令执行仍是单线程,保证原子性
I/O 处理 单线程处理网络读写和命令执行 多线程处理网络 I/O(读取和写入响应),主线程只负责命令执行
性能瓶颈 CPU 成为瓶颈时,无法利用多核优势 主要解决网络 I/O 瓶颈,对于大数据量、高并发的网络场景性能提升显著
线程安全 天然线程安全,无需考虑锁 命令执行层仍是单线程,核心逻辑保持简单
配置 io-threads-do-reads no (默认) io-threads 4 (建议设置为CPU核心数)

3. I/O 多路复用

技术 说明 Redis 中的应用
select 早期的 I/O 多路复用模型,有连接数限制(1024) Redis 已不再使用
epoll Linux 下的高效 I/O 模型,无连接数限制,基于事件回调 Redis 在 Linux 上的默认实现,性能极高
kqueue macOS/FreeBSD 下的高效 I/O 模型,类似 epoll Redis 在相应系统上的默认实现
工作流程 1. epoll_create 创建实例 2. epoll_ctl 注册/修改 Socket 事件 3. epoll_wait 阻塞等待事件发生 4. 事件返回后,由 Redis 单线程逐个处理 这是 Redis 单线程能处理大量并发连接的基石

四、Redis 持久化机制(深度对比)

RDB(快照) vs AOF(日志) vs 混合持久化

对比维度 RDB (快照) AOF (仅追加文件) 混合持久化 (AOF rewrite)
原理 在指定时间间隔内,将内存数据快照写入磁盘 记录所有写命令到 AOF 文件,重启时重放命令 AOF 重写时:将当前内存数据以 RDB 格式写入 AOF 文件开头,之后的增量命令以 AOF 格式追加
恢复速度 (需重放所有命令) (RDB 部分加载快,AOF 部分增量小)
数据完整性 可能丢失最后一次快照后的数据 (可配置 appendfsync always (同 AOF,但恢复更快)
文件大小 较小,紧凑 较大,随时间增长 较小(RDB 部分紧凑,AOF 部分增量)
性能影响 fork 子进程时有短暂性能影响(内存拷贝) 持续影响写入性能,取决于 fsync 策略 重写时有短暂性能影响,平时同 AOF
适用场景 备份、灾难恢复、对数据完整性要求不高 生产环境首选,追求数据高可靠 Redis 4.0+ 推荐,兼顾恢复速度和数据完整性
配置示例 save 900 1 stop-writes-on-bgsave-error yes appendonly yes appendfsync everysec auto-aof-rewrite-percentage 100 开启 AOF 后,重写机制自动生效

最佳实践 :生产环境强烈建议开启 AOF ,并使用 appendfsync everysec 策略。同时可以开启 RDB 用于定时备份。Redis 4.0+ 默认开启混合持久化,是最佳选择。

五、Redis 高可用与集群方案(详解)

方案对比与选型

方案 工作原理 优点 缺点 适用场景
主从复制 Master 写,Slave 读,单向数据同步 读写分离,提升读性能;数据备份 Master 单点故障;手动故障转移麻烦 读多写少,对高可用要求不高的场景
哨兵模式 (Sentinel) 监控主从节点,自动进行故障转移 高可用 :自动故障转移;监控 :节点健康检查;通知:故障通知 配置相对复杂;主从切换期间服务短暂不可用(秒级);不解决写能力瓶颈 对高可用有要求,但数据量和并发量不是特别巨大的场景
Redis Cluster 数据分片(16384个槽),多主多从,去中心化 高可用 :节点故障自动转移;水平扩展:轻松增加节点提升容量和性能 客户端复杂 :需支持 Cluster 协议,处理 MOVED/ASK 重定向;不支持多键操作 (如 MSET 跨槽位);事务仅支持单节点 海量数据高并发、需要水平扩展的场景

主从复制核心流程与问题

全量同步 (Full Sync)

Slave 发送 REPLCONF listening-portPSYNC ? -1

Master 响应 FULLRESYNC <runid> <offset>,并 fork 子进程生成 RDB 文件。

Master 将 RDB 文件发送给 Slave,Slave 清空旧数据并加载 RDB。

Master 将生成 RDB 期间的写命令存入复制缓冲区 (replication buffer),并发送给 Slave。

Slave 执行这些写命令,达到数据一致。

增量同步 (Partial Sync)

断线重连后,Slave 发送 PSYNC <runid> <offset>

Master 检查 runid 是否匹配,且 offset 是否在复制积压缓冲区 (repl_backlog_buffer) 内。

如果都满足,则只发送从 offset 开始的增量命令。

否则,退化为全量同步。

常见问题

主从数据不一致 :网络延迟、Slave 负载过高、maxmemory 配置不当导致 key 淘汰策略不同。

主从延迟:Master 写压力大、Slave 单线程处理慢、网络带宽瓶颈。

Redis Cluster 核心机制

机制 说明
数据分片 (Sharding) 16384 个槽位 (Slot),通过 CRC16(key) % 16384 计算 key 所属槽位。每个 Master 节点负责一部分槽位。
节点通信 节点间通过 Gossip 协议交换信息(如槽位映射、节点状态),实现去中心化。
请求路由 客户端请求到错误节点时,节点会返回 MOVED (永久) 或 ASK (临时) 重定向指令,客户端需更新槽位映射。
高可用 (Failover) 集群中每个 Master 都有对应的 Slave。当 Master 失效时,其 Slave 会被选举为新的 Master(通过 Raft 类似的共识算法),并接管其负责的槽位。
不支持的操作 涉及多个 key 的操作(如 MSET key1 val1 key2 val2),如果 key 不在同一个槽位,会报错。需使用 hash tag(如 {user}1001)强制 key 分配到同一槽位。

六、Redis 缓存三大问题与解决方案(方案对比)

问题 核心原因 解决方案 方案对比与选型
缓存穿透 查询一个不存在的数据,请求绕过缓存直击数据库。 1. 缓存空对象 :将 null 也缓存,设短过期时间。 2. 布隆过滤器:在缓存前加一层过滤器,拦截不存在的 key。 缓存空对象 :简单,但会占用少量内存,且数据不一致时需主动删除。 布隆过滤器 :高效,内存占用小,但有误判率(可调),且不支持删除。生产环境常组合使用
缓存击穿 一个热点 Key 在失效瞬间,大量并发请求直击数据库。 1. 互斥锁 (Mutex) :只允许一个线程去数据库加载数据,其他线程等待。 2. 逻辑过期 (永不过期):Key 物理上不过期,通过后台线程异步更新。 互斥锁 :实现简单,但高并发下线程等待会增加响应时间。 逻辑过期 :响应快,无等待,但数据一致性较差(可能读到旧数据),实现复杂。推荐互斥锁方案
缓存雪崩 1. 大量 Key 同时失效 。 2. Redis 服务宕机 1. 过期时间加随机值 :打散失效时间。 2. 高可用架构 :哨兵或集群,保证 Redis 不宕机。 3. 服务降级/限流 :数据库前加限流组件。 4. 多级缓存:本地缓存 (Caffeine) + Redis。 过期时间加随机值 是基础,必须做。 高可用架构 是根本保障。 多级缓存限流是最后的防线,用于应对极端情况。

七、分布式锁(深度剖析)

Redis 实现分布式锁的演进

版本 实现方式 优点 缺点
SETNX SET key value NX 简单,原子性 1. 无过期时间,易死锁。 2. 无法保证释放锁的是加锁的客户端(误删)。
SET NX PX SET key value NX PX 30000 1. 原子性。 2. 自动过期,防死锁。 仍有误删他人锁的风险(业务未执行完,锁已过期,被其他客户端获取并删除)。
Lua 脚本 if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end 1. 原子性。 2. 防死锁。 3. 安全释放 :通过 value 校验,只删除自己加的锁。 1. 业务执行时间超过锁过期时间,仍会导致问题。 2. 主从切换时,锁可能丢失。
Redlock 在 N 个独立 Redis 实例上依次加锁,成功超过半数即算成功 1. 解决主从切换锁丢失问题。 2. 容错性更高。 1. 实现复杂,性能开销大。 2. 依赖系统时钟,时钟漂移可能导致问题。 3. 官方文档也建议仅在对强一致性要求极高的场景使用。
Redisson 基于 Redis 的 Java 客户端库,封装了 Redlock 和可重入锁 1. 可重入 :同一线程可多次加锁。 2. 看门狗机制 :自动续期,解决业务超时问题。 3. 公平/非公平锁读写锁 等多种实现。 4. 封装完善,开箱即用。 增加了客户端依赖,但极大地简化了开发。

生产环境推荐

简单场景:使用 SET NX PX + Lua 脚本 的方案,并确保业务逻辑在锁过期时间内能完成。

复杂/高要求场景:直接使用成熟的客户端库,如 Redisson,它内置了看门狗、可重入等高级特性,是事实上的工业标准。

八、Redis 事务与 Pipeline(对比与选择)

特性 事务 (Transaction) Pipeline (管道)
目的 原子性:保证一组命令要么全执行,要么全不执行。 性能:减少网络往返次数 (RTT),批量执行命令。
原子性 不保证 :命令在队列中时不保证,EXEC 后也不保证(某条命令失败不影响其他)。无回滚 无原子性:只是批量发送,不保证原子性。
隔离性 不保证 :执行期间其他客户端的命令可能穿插进来(在 EXEC 前后)。 不保证:同上。
错误处理 1. 语法错误EXEC 前发现,整个事务失败。 2. 运行时错误EXEC 后发现,该命令失败,其他命令继续执行。 每个命令独立返回结果,需客户端自行判断。
主要命令 MULTI, EXEC, DISCARD, WATCH pipeline() 对象,最后 execute()
适用场景 需要将多个操作作为一个逻辑单元 ,但对严格的数据库事务(ACID)要求不高。例如:INCR 一个计数器,然后 LPUSH 一条日志。 需要批量操作 以提升性能,且不关心原子性。例如:一次性 GET 100 个 key 的值。

选择建议

需要保证一组操作的逻辑原子性 (即不希望被其他命令打断),用事务

只是为了提升批量操作的性能 ,用 Pipeline

在很多场景下,两者可以结合使用。

九、Redis 常用性能优化(速查表)

优化方向 问题/现象 排查/解决方案
大 Key 慢查询、内存分布不均、集群迁移困难 1. 发现 :使用 redis-cli --bigkeysmemory doctor。 2. 拆分 :将一个大 Hash 拆成多个小 Hash-Key。 3. 避免 :不要用 GETALL,使用 HSCAN 游标遍历。
热点 Key 单点 QPS 过高,成为性能瓶颈 1. 发现hotkeys 命令(需插件)或监控平台。 2. 拆分 :将热点 Key 拆分为多个,如 hot_key_1, hot_key_2,通过随机数读写。 3. 本地缓存:在应用层加 Caffeine 等本地缓存。
慢查询 命令执行时间过长,阻塞其他请求 1. 发现SLOWLOG GET 10 查看慢查询日志。 2. 分析 :检查慢查询命令(如 KEYS, HGETALL 大 Key)。 3. 解决 :用 SCAN 替代 KEYS;拆分大 Key;优化业务逻辑。
内存溢出 maxmemory 限制,触发淘汰策略 1. 监控INFO memory 查看 used_memory。 2. 分析memory stats 分析内存分布。 3. 解决 :调整 maxmemory-policy(如 allkeys-lru);增加内存;优化数据结构。
连接数过高 CLIENT LIST 显示大量连接 1. 优化 :使用连接池 (JedisPool, Lettuce),复用连接。 2. 排查:检查是否有连接泄漏(未正确关闭)。
CPU 100% 单线程模型下 CPU 跑满 1. 排查INFO commandstats 查看高频命令。 2. 原因 :通常是执行了复杂命令(如 SORT, ZUNIONSTORE)或大量 Key 过期。
持久化开销 fork 子进程时响应变慢 1. 配置repl-diskless-sync yes(无盘复制,适用于主从)。 2. 硬件:使用 SSD 硬盘。

十、企业级最佳实践与场景速查

业务场景 推荐 Redis 数据结构/方案 核心命令/实现 关键点
高并发缓存 String + 本地缓存 (Caffeine) SETEX, GET 缓存穿透/击穿/雪崩防护;热点 Key 预热;数据一致性策略
计数器/排行榜 String (INCR) / Sorted Set INCR, ZINCRBY, ZREVRANGE 原子性操作;Sorted Set 可带成员信息,实现复杂排行
分布式 Session String + Hash SETEX user:session_id json_str, HSET user:1 name "A" Key 需有统一前缀;设置合理过期时间;序列化用 JSON 或 Protobuf
分布式锁 Redisson (推荐) / SET + Lua RLock.lock(), SET key val NX PX 防死锁 (过期时间/看门狗);安全释放 (Lua校验);可重入
消息队列 Stream (专业) / List (轻量) XADD, XREADGROUP, LPUSH, BRPOP Stream 支持消费组消息确认 (ACK)消息回溯,功能完善;List 简单但无ACK
社交关系 Set / Sorted Set SADD, SINTER, ZRANGE 共同好友用 SINTER;关注列表用 SetList
实时统计 (UV/PV) HyperLogLog / Bitmap PFADD, PFCOUNT, SETBIT, BITCOUNT HyperLogLog 基数统计,省内存;Bitmap 用于精确签到、在线状态
地理位置服务 GEO GEOADD, GEORADIUS 基于 Sorted Set 实现,可用于"附近的人"、"打车"等场景
标签/筛选 Set / Bitmap SADD, SISMEMBER, SETBIT 标签用 Set 实现交集/并集筛选;多维筛选可用 Bitmap 实现
配置中心 Hash / String HSET config_key field val, GET config_key 监听 Key 的过期或变更消息(需客户端实现或结合 Pub/Sub)

本文通过多维度的对比表格、深入的机制剖析、方案选型建议以及企业级最佳实践,力求构建一个更加立体和深入的 Redis 知识体系。欢迎交流指正。

相关推荐
wangqiaowq2 小时前
OEE 是 Overall Equipment Effectiveness 的缩写,中文意为设备综合效率
数据库
aLTttY2 小时前
Spring Boot + Redis 实战分布式锁:从入门到精通
spring boot·redis·分布式
2301_816660212 小时前
如何在 Telegram Bot 中正确发送 HTML 格式的用户列表消息
jvm·数据库·python
2401_898717662 小时前
CSS如何使得响应式的侧边抽屉附带遮罩渐暗效果
jvm·数据库·python
weixin_458580122 小时前
如何在网页中完整展示数组中所有对象的全部属性
jvm·数据库·python
木易 士心2 小时前
云数据库 Clouder 认证:SQL 基础开发与应用题型分析
数据库·后端·sql·oracle
2403_883261092 小时前
PHP源码能否在Chromebook上运行_ChromeOS硬件限制说明【解答】
jvm·数据库·python
djjdjdjdjjdj2 小时前
golang如何编写DNS查询工具_golang DNS查询工具编写大全
jvm·数据库·python
·云扬·2 小时前
从0到1理解分库分表:我踩过的坑与实战经验
运维·数据库·mysql