图解 Redis 01|String:你以为它是字符串,其实是三种编码的合体
Redis 的 String 被讲成「字符串」,但底层是 int / embstr / raw 三种编码合体。本文讲清楚三种编码各自的内存布局、embstr 的 44 字节是怎么来的,以及为什么用 String 存 JSON 会让内存比预期高出 40%。
从 String 的三种编码开始,拆到数据结构、内存治理、事件循环、持久化、高可用和线上排查。
适合想把 Redis 从命令手册理解到内核机制、容量治理和生产排障的后端工程师。
从 String、List、Hash、Set 到 ZSet、Stream、Bitmap、HLL 和 GEO。
keyspace、过期删除、内存淘汰和碎片问题。
事件循环、Pipeline、Pub/Sub、Stream、Lua 和事务边界。
RDB、AOF、重写和恢复演练。
主从复制、Sentinel 和 Cluster 路由。
Hot Key、Big Key、缓存一致性和排查闭环。
Redis 的 String 被讲成「字符串」,但底层是 int / embstr / raw 三种编码合体。本文讲清楚三种编码各自的内存布局、embstr 的 44 字节是怎么来的,以及为什么用 String 存 JSON 会让内存比预期高出 40%。
List 常被讲成链表,但现代 Redis 用 quicklist + listpack 承载它。本文讲清两端操作为什么快、随机访问为什么不适合,以及大 List 会把延迟问题藏在哪里。
Hash 适合存字段级对象,但省内存不是免费的魔法。本文讲清 listpack 与 hashtable 的编码切换、字段级更新的优势,以及超级 Hash 的风险。
Set 的价值不只是去重,它背后有 intset、listpack、hashtable 多种编码路径。本文讲清集合成员如何存储,以及大集合运算为什么容易拖慢 Redis。
ZSet 同时支持按成员查分和按分数排序,靠的是小对象 listpack 或大对象 dict + skiplist。本文讲清双索引成本、排行榜分页和延迟任务的边界。
Stream 像追加日志,也支持消费组,但它不是 Kafka 平替。本文讲清 ID、rax/listpack、PEL、ACK 和裁剪机制,以及消费者挂掉后的治理。
Bitmap 本质上是 String 的位操作接口。本文讲清 SETBIT 如何按最大 offset 扩容,为什么稀疏用户 ID 会浪费内存,以及签到/活跃统计的边界。
HyperLogLog 不保存成员,只保存估算基数所需的寄存器。本文讲清近似统计的边界,以及为什么它适合 UV、不适合风控和计费。
Redis GEO 把经纬度编码成 geohash 分数,并借 ZSet 做范围检索。本文讲清附近的人/门店检索适合什么,不适合什么。
Redis 的一个 key 不只是字符串和值,还牵涉数据库字典、过期字典、redisObject 和编码元信息。本文把 keyspace 的内存账算清楚。
Redis 的过期删除不是定时器逐个唤醒,而是惰性删除和定期抽样共同工作。本文讲清 TTL 不准时、过期残留和缓存雪崩的机制。
Redis 到达 maxmemory 后会按策略淘汰 key,但 LRU/LFU 都是采样近似。本文讲清 allkeys/volatile/noeviction 的边界,以及混合实例的风险。
Redis 的 used_memory 不等于操作系统看到的 RSS。本文讲清 allocator size class、释放空洞、碎片率和主动碎片整理的边界。
Redis 的单线程指命令执行主路径,而不是所有工作都只有一个线程。本文讲清文件事件、时间事件、命令原子执行和慢命令如何拖住全局延迟。
Pipeline 能显著降低网络往返次数,但不会让命令本身更便宜。本文讲清 RTT、输出缓冲、连接池和无限 pipeline 的风险。
Pub/Sub 是即时广播,Stream 是可追溯日志。本文讲清两者的语义差异、慢消费者风险和关键业务消息该怎么选。
Redis 的 MULTI/EXEC、WATCH、Lua 和 Functions 都能处理批量或原子逻辑,但它们不是数据库事务。本文讲清无回滚、阻塞主线程和脚本边界。
RDB 是紧凑快照,但 BGSAVE 背后的 fork 和 Copy-On-Write 会带来延迟和内存峰值。本文讲清备份、恢复和大实例风险。
AOF 用追加日志提升数据安全,但 fsync 策略决定延迟和丢数据窗口。本文讲清 everysec/always/no 的取舍,以及磁盘抖动如何影响 Redis。
AOF 会不断增长,需要重写压缩历史命令;现代 Redis 还支持多文件 AOF 和混合持久化。本文讲清 rewrite buffer、manifest 和恢复演练的重要性。
Redis 复制靠 replid、offset 和 replication backlog 在全量同步与部分重同步之间切换。本文讲清从库延迟、全量同步风暴和 WAIT 的边界。
Sentinel 负责监控、选主、通知和故障转移,但不负责分片,也不保证零丢写。本文讲清主观下线、客观下线、Leader 选举和新主选择。
Redis Cluster 用 16384 个 slot 做分片,客户端根据 MOVED/ASK 更新路由。本文讲清 hash tag、跨 slot 限制和迁移期间的请求路径。
Hot Key 会让 Cluster 的局部节点 CPU 飙高,其他节点却很闲。本文讲清热点发现、本地缓存、请求合并和读副本扩散的治理路径。
Big Key 会带来网络传输、删除阻塞、迁移失败和内存倾斜。本文讲清如何识别、拆分和删除大 key。
缓存一致性不是一句先删缓存还是先写数据库能解决。本文讲清旁路缓存、并发回填、延迟双删、binlog 订阅和最终一致性的边界。
Redis 排查不能只看一个指标。本文把延迟高、内存涨、连接满、复制延迟和 CPU 飙高串成一张体检表,形成可执行的排查闭环。