Redis篇(一):概述

Redis篇(一):概述 一、Redis 是什么为什么它能成为缓存领域的顶流RedisRemote Dictionary Server是一个开源的、基于内存的高性能键值存储数据库。它不仅仅是一个简单的缓存中间件更是一个功能丰富的数据结构服务器支持字符串、哈希、列表、集合、有序集合等多种数据类型同时提供了持久化、发布订阅、Lua 脚本、事务、主从复制、哨兵模式、集群等高级特性。与传统的关系型数据库 MySQL 相比Redis 的核心优势在于将数据存储在内存中使得读写操作的延迟降低到了微秒级别。在典型的互联网架构中Redis 通常作为 MySQL 的前置缓存层承担着热点数据加速、会话管理、分布式锁、排行榜、计数器、消息队列等多种职责。二、Redis 高性能的五大核心密码Redis 单机 QPS 可达10万平均延迟低于1ms这样的性能表现并非偶然。下面我们从五个维度拆解 Redis 的高性能密码2.1 基于内存的操作Redis 的所有数据都存储在内存中读写操作直接在内存完成避免了磁盘 I/O 的瓶颈。内存访问的速度大约是磁盘访问的10万倍这是 Redis 高性能的根基。内存访问延迟~100ns SSD 随机读取~100μs 机械磁盘随机读取~10ms需要注意的是Redis 的内存是有限的当内存使用达到上限时需要通过内存淘汰策略如 LRU、LFU、TTL 等来释放空间。2.2 单线程模型化繁为简的智慧Redis 的核心命令执行采用单线程模型这一设计看似反直觉实则蕴含深意避免上下文切换多线程频繁切换会消耗大量 CPU 时间单线程消除了这一开销无锁竞争不需要加锁来保护共享数据避免了死锁和竞态条件原子性保证所有命令都是原子操作天然支持事务语义代码简洁单线程模型大幅降低了代码复杂度提升了可维护性面试高频考点Redis 是单线程的为什么还这么快答案Redis 的单线程指的是命令执行是单线程的但网络 I/O 采用了多路复用机制。内存操作本身极快单线程足以满足需求且避免了多线程带来的上下文切换和锁竞争开销。2.3 I/O 多路复用单线程处理万级连接Redis 使用epollLinux/ kqueueBSD实现 I/O 多路复用单个线程可以同时监听成千上万个 Socket 连接。当某个 Socket 有数据到达时事件驱动机制会通知 Redis 进行处理而不是为每个连接创建一个线程。// Redis 事件循环的核心伪代码while(!stop){// 1. 等待文件事件epoll_waitready_socketsepoll_wait(epfd,events,maxevents,timeout);// 2. 处理就绪的 Socketfor(i0;iready_sockets;i){handle_file_event(events[i]);}// 3. 处理时间事件如过期 key 清理handle_time_events();}2.4 高效的数据结构Redis 并非简单地使用 C 语言的字符串和数组而是设计了专门优化的数据结构数据结构内部实现优化点StringSDSSimple Dynamic String预分配空间、O(1) 获取长度、二进制安全ListQuickList3.2结合双向链表和压缩列表平衡插入和遍历性能Hashziplist / hashtable小数据用压缩列表节省内存大数据自动转哈希表ZSetskiplist hashtable跳表保证范围查询 O(logN)哈希表保证单点查询 O(1)Setintset / hashtable整数集合节省内存大数据自动转哈希表2.5 多线程优化Redis 6.0Redis 6.0 引入了多线程 I/O但这并不意味着命令执行变成了多线程。其核心设计是网络 I/O 多线程多个 IO 线程并行处理 Socket 的读写和协议解析命令执行仍单线程保证原子性和一致性配置开启通过io-threads和io-threads-do-reads参数控制# redis.conf 配置示例io-threads4# 开启 4 个 IO 线程io-threads-do-readsyes# IO 线程也处理读操作实测表明在 4 核 CPU 环境下开启多线程 I/ORedis 的吞吐量可提升2~3 倍。三、为什么用 Redis 作为 MySQL 的缓存在典型的互联网架构中Redis MySQL 的组合已经成为标配。这种架构的核心价值在于读写分离、冷热分层3.1 缓存的核心价值场景说明热点数据缓存将高频访问的数据商品详情、用户信息缓存到 RedisQPS 从 MySQL 的千级提升到 Redis 的十万级会话缓存用户登录状态存储在 Redis支持分布式会话共享排行榜/计数器利用 ZSet 实现实时排行榜利用 INCR 实现原子计数分布式锁通过 SETNX Lua 脚本实现互斥锁避免并发冲突消息队列List 实现简单队列Stream 实现复杂消息流3.2 缓存三大问题及解决方案问题现象解决方案缓存穿透查询不存在的数据绕过缓存直达 DB布隆过滤器拦截非法请求缓存击穿热点 key 过期瞬间大量请求打穿到 DB互斥锁重建缓存 / 逻辑过期缓存雪崩大量 key 同时过期DB 压力骤增随机过期时间 多级缓存3.3 数据一致性策略缓存与数据库的数据一致性是架构设计的难点常用策略有三种Cache Aside旁路缓存先更新 DB再删除缓存 ——最常用推荐Read/Write Through由缓存层代理读写对应用透明Write Behind异步写回 DB高性能但一致性弱最佳实践采用 Cache Aside 延时双删策略配合消息队列保证最终一致性。四、持久化机制RDB vs AOFRedis 作为内存数据库数据在重启后会丢失。为了保证数据安全Redis 提供了两种持久化机制4.1 RDBRedis DatabaseRDB 通过快照机制将某一时刻的内存数据保存为二进制文件。触发方式SAVE阻塞主线程生产环境不推荐BGSAVEfork 子进程执行主线程继续处理请求自动触发配置save 900 1900 秒内 1 次修改则触发优点文件紧凑体积小适合备份和传输恢复速度快直接加载到内存对性能影响小BGSAVE 子进程执行缺点可能丢失最后一次快照后的数据大数据量时 fork 子进程可能耗时较长4.2 AOFAppend Only FileAOF 通过日志追加的方式记录每个写操作命令。同步策略always每次写入都同步最安全但最慢everysec每秒同步一次推荐平衡安全与性能no由操作系统决定同步时机最快但最不安全优点数据安全性高最多丢失 1 秒数据日志可读便于审计和故障排查缺点文件体积大恢复速度慢同步写入可能影响性能AOF 重写机制AOF 文件会随着写操作不断增长Redis 提供了AOF 重写功能通过BGREWRITEAOF命令 fork 子进程将当前内存数据生成新的精简 AOF 文件。4.3 混合持久化Redis 4.0Redis 4.0 引入了混合持久化兼顾 RDB 的恢复速度和 AOF 的数据安全性# 开启混合持久化aof-use-rdb-preambleyes文件结构文件开头RDB 格式的全量数据快照文件后续AOF 格式的增量写命令恢复流程先加载 RDB 部分快速恢复再重放 AOF 增量命令兼顾速度与安全性。4.4 持久化配置建议场景推荐配置数据可丢失纯缓存关闭持久化最大化性能允许少量数据丢失RDB 定期备份 AOF everysec数据不可丢失AOF always 主从复制 哨兵通用生产环境RDB AOF 混合持久化五、Redis vs Memcached如何选择特性RedisMemcached数据结构支持字符串、哈希、列表、集合、有序集合等仅支持简单的键值对字符串持久化支持 RDB 和 AOF不支持持久化数据仅存储在内存中内存管理支持多种内存淘汰策略LRU、LFU 等使用 Slab Allocation 机制管理内存集群支持支持主从复制和集群模式需要客户端实现分布式如一致性哈希事务支持支持事务MULTI/EXEC不支持事务Lua 脚本支持 Lua 脚本可以实现复杂逻辑不支持脚本数据分片支持数据分片Cluster 模式需要客户端实现数据分片性能单线程模型性能较高多线程模型性能更高适用场景适合需要丰富数据结构和持久化的场景适合简单的键值缓存场景选型建议需要复杂数据结构排行榜、计数器、分布式锁→Redis需要持久化保证数据安全 →Redis仅需简单的键值缓存追求极致吞吐量 →Memcached已有 Memcached 集群仅需简单缓存 → 可继续使用 Memcached