Redis 基础技术总结与核心实践
1. 引言Redis 作为当前互联网架构中最常用的缓存与数据中间件其重要性已无需赘言。这篇博客是个人对 Redis 基础知识的系统性梳理涵盖核心数据结构、持久化机制、内存淘汰策略以及常见踩坑点旨在形成一份可以随时查阅的技术速查手册。文中不会过多罗列概念定义重点放在实际开发中需要关注的技术细节和容易忽略的边界场景。2. Redis 核心数据结构与应用边界Redis 的五大基础数据结构是面试和日常开发的常客但仅仅知道String 存字符串、Hash 存对象远远不够。下面从实际使用角度逐一展开。2.1 String——不只是 Key-ValueString 是 Redis 最基础的类型底层采用 SDS简单动态字符串二进制安全单个 value 上限 512MB。实际开发中几个容易忽视的点数值计算当 value 存储的是整数时incr/decr 操作是原子的适合做计数器、限流计数器等场景无需额外加锁。批量操作mset/mget 能显著减少网络 RTT批量获取几十个 key 时性能差异明显。SETNX 的替代老版本常用 SETNX EXPIRE 做分布式锁但两步操作非原子。现在统一用SET key value NX EX seconds一条命令搞定。2.2 Hash——注意压缩机制Hash 适合存储对象属性每个 Hash 最多存 2^32-1 个字段。这里值得关注的是底层编码切换当字段数量少且单个值较短时底层用 ziplist 紧凑存储超过阈值后转为 hashtable。hash-max-ziplist-entries和hash-max-ziplist-value这两个参数直接影响内存占用数据量大时建议评估是否需要调整。另外hmset 已标记为废弃统一使用 hset 多次调用或 hset 批量形式。2.3 List——阻塞队列的利器List 底层在 3.2 之后统一使用 quicklist兼顾 linkedlist 的插入效率和 ziplist 的内存紧凑。实际场景中LPUSH BRPOP 的组合可以轻松实现生产者-消费者模式的阻塞消息队列超时参数设 0 表示无限等待。需要注意的是List 不支持按消息体确认删除消息可靠性要求高的场景还是优先考虑 RabbitMQ/Kafka。2.4 Set——交集并集的实际用途Set 底层是哈希表值唯一。除基本的增删查外交集SINTER、并集SUNION、差集SDIFF在业务上有实际价值比如共同关注用户列表、标签筛选等。SSCAN 命令可以做分批遍历避免 SMEMBERS 在大集合场景下阻塞主线程。另外SRANDMEMBER 配合 negative count 参数可以实现带重复元素的随机抽取。2.5 Sorted Set——跳表实现的有序集合ZSet 底层是跳表加哈希表每个元素关联一个 score按分值排序。核心应用场景是排行榜、延时队列、权重排序。ZRANGEBYSCORE 配合 LIMIT 做分页查询时注意 offset 越大性能越差建议用 score 范围做滚动翻页。ZADD 的 NX/XX/GT/LT 参数在更新逻辑中很实用NX 仅新增不更新、GT 仅当新分数更大才更新。3. 持久化RDB 与 AOF 的取舍Redis 作为内存数据库持久化是数据安全的关键保障。两种机制各有侧重生产环境通常混合使用。3.1 RDB——全量快照的优缺点RDB 通过 fork 子进程生成某一时刻的全量数据快照文件紧凑、恢复速度快。缺点也很明确两次快照之间发生宕机会丢失这部分数据。save参数的触发规则建议根据写入并发量调整频率不宜过高避免频繁 fork 导致阻塞。手动执行 BGSAVE 或 LASTSAVE 查看最后成功快照时间也是日常运维常用手段。3.2 AOF——日志回放与重写AOF 记录每一条写命令数据安全性比 RDB 更高。appendfsync有三个级别always每条命令刷盘最安全性能最低、everysec每秒刷盘平衡选择、no交给操作系统风险高。实际项目中 everysec 最常用最多丢一秒数据。AOF 文件会随时间膨胀BGREWRITEAOF 在后台进行重写压缩重写过程中新增命令会写入缓冲区完成后追加全程不影响主线程。3.3 混合持久化Redis 4.0 起支持混合持久化AOF 重写时将当前数据以 RDB 格式写入 AOF 文件头部后续追加 AOF 命令。这样既保留了恢复速度又兼顾了数据安全性建议在 4.0 以上版本开启。