一张思维导图理清【Redis】

数据结构

Redis 提供了丰富的底层数据结构,且对部分结构的实现细节做了深度优化:

  • String
    • 底层基于 SDS(简单动态字符串) 实现,SDS 记录了字符串长度(获取长度 O (1))、预留空间(避免频繁扩容)、二进制安全(可存储任意字节)。
    • 衍生结构:BitMap(位操作,如统计用户活跃天数)、HyperLogLog(基于伯努利试验的基数统计,误差约 0.81%)、GEO(存储地理位置,用 GeoHash 编码实现距离计算)、Stream(消息队列,支持多消费者组、消息持久化)。
  • List
    • 底层是双向链表 + 压缩列表(小数据量时用压缩列表节省内存,大数据量时转双向链表)。
    • 操作:lpush/rpush(头 / 尾插入)、lpop/rpop(头 / 尾弹出)、lrange(范围查询)等,支持 "栈""队列""阻塞队列" 等模式。
  • Hash
    • 底层是哈希表 + 压缩列表(字段少且值小时用压缩列表)。
    • 优势:存储对象时更节省内存(相比 String 存 JSON 字符串),支持 hset(设字段)、hget(获取字段)、hdel(删除字段)等操作。
  • Set
    • 底层是哈希表 + 整数集合(元素是整数且数量少时用整数集合)。
    • 支持交集(sinter)、并集(sunion)、差集(sdiff)操作,常用于 "共同好友""标签去重" 场景。
  • ZSet
    • 底层是跳表 + 压缩列表(元素少且值小时用压缩列表)。
    • 跳表原理:通过多层链表加速查询,插入、删除、查询复杂度均为 O (logN);压缩列表用 listpack 优化(无节点长度冗余,查询更高效)。
    • 核心操作:zadd(添加带分数元素)、zrange(按分数范围查询)、zrank(查元素排名)等,适用于 "排行榜""延迟任务" 场景。

线程模型

  • 单线程核心逻辑 :Redis 主线程处理命令解析、执行、响应,避免了多线程的上下文切换和锁竞争开销。
  • 多线程辅助场景
    • AOF 刷盘:6.0+ 版本用多线程异步刷盘,主线程写 AOF 缓冲区后,由子线程将缓冲区数据刷到磁盘。
    • lazyfree 操作 :如 unlink(异步删除大 key)、flushdb async(异步清空数据库),主线程仅标记 key 为待删除,子线程负责实际内存释放。
    • 网络 IO(6.0+):多线程处理 "socket 读取、解析命令、发送响应",但命令执行仍由主线程完成(保证原子性)。
  • IO 多路复用 :基于 Reactor 模型,通过 epoll(Linux)/kqueue(BSD)等系统调用,让单线程能同时监听多个 socket 的 IO 事件,避免阻塞。

事务

Redis 事务通过 lua 脚本和自身事务机制保证原子性,执行错误时(如语法错)会在 EXEC 阶段回滚。

日志

对比了两种持久化方式的优劣:

  • RDB 快照
    • 触发方式:save(主线程同步执行,阻塞业务)、bgsave(fork 子进程执行,不阻塞主线程)、配置 save <秒> <修改次数>(自动触发)。
    • 优势:恢复速度快、文件体积小;劣势:可能丢失 "最后一次快照后" 的数据,fork 子进程时若内存大,会有短暂卡顿。
  • AOF 日志
    • 同步策略:appendfsync always(每次命令都刷盘,最安全但最慢)、everysec(每秒刷盘,平衡安全与性能)、no(由操作系统决定刷盘时机,最快但最不安全)。
    • 重写机制:bgrewriteaof 会 fork 子进程,遍历内存中 key-value 生成新 AOF 文件(仅记录最终状态),解决 AOF 文件膨胀问题。

缓存淘汰和过期删除

    • 不淘汰:内存满时返回 OOM 错误(maxmemory-policy noeviction)。
    • 淘汰类型:
      • 过期键淘汰:volatile-ttl(选过期时间最短的)、volatile-random(随机选过期键)、volatile-lru(LRU 淘汰过期键)、volatile-lfu(LFU 淘汰过期键)。
      • 全库键淘汰:allkeys-lru(全库 LRU 淘汰)、allkeys-random(全库随机淘汰)、allkeys-lfu(全库 LFU 淘汰)。
  • 过期删除机制
    • 惰性删除:访问 key 时检查 TTL,若过期则删除(避免无意义内存占用)。
    • 定时删除:每秒随机选 20 个 key 检查过期,若过期 key 占比超 25%,则循环此操作(防止大量过期 key 堆积)。

集群

  • 主从同步
    • 全量同步:从节点初次连接主节点时,主节点生成 RDB 快照并发送,从节点加载 RDB 后再同步增量命令(repl_backlog_buffer 环形缓冲区记录)。
    • 增量同步:主节点写命令同步到从节点,从节点执行命令保持数据一致(基于 replication offset 标记同步进度)。
  • 哨兵机制
    • 节点监控:哨兵进程定时 ping 主从节点,判断节点是否存活。
    • 故障转移:主节点主观下线后,哨兵选举 leader 并推选新主节点,通知从节点切换主节点(保证服务不中断)。
  • 集群模式(哈希槽)
    • 16384 个哈希槽分片数据,节点负责部分槽位;客户端通过 MOVED/ASK 重定向找到目标节点。
    • 优势:支持水平扩容、故障自动转移;劣势:运维复杂、跨槽操作(如多 key 事务)需额外处理。

场景

  • Redis 优势:高性能、高并发、内存存储、数据结构丰富、单线程模型(对比 MySQL 有明显 QPS 优势,Redis 可达 10w+ qps,MySQL 约 5000 qps)。
  • 经典问题与解决方案:
    • 大 key 问题:危害是内存占用过高、性能下降等;解决方案包括拆分 key、清理非 Redis 适配数据、监控内存水位、过期数据定时清理。
    • 热 key 问题:定义是 QPS 集中、带宽 / CPU 占用高的 key;解决方案是集中热 key 复制、读写分离。
    • 数据一致性(Redis + MySQL):可通过 "缓存预热 + cache 读、数据库写""写数据库后删缓存""删除缓存失败时用消息队列重试(如 Canal 监控 binlog)" 等方案保障。
    • 缓存策略(击穿、雪崩、穿透)
      • 击穿:热点 key 过期后被大量请求打穿,可通过互斥锁(同一时间仅一个请求重建缓存)解决。
      • 雪崩:大量 key 同时过期,可通过随机过期时间避免。
      • 穿透:请求不存在的 key 穿透到数据库,可通过布隆过滤器(判断 key 是否可能存在,过滤无效请求)解决。
相关推荐
q***33372 小时前
mysql查看binlog日志
数据库·mysql
q***51892 小时前
MYSQL批量UPDATE的两种方式
数据库·mysql
x***01062 小时前
SQL 注入漏洞原理以及修复方法
网络·数据库·sql
百***81273 小时前
【HTML+CSS】使用HTML与后端技术连接数据库
css·数据库·html
6***3493 小时前
MySQL项目
数据库·mysql
木井巳3 小时前
【MySQL数据库】数据库基础
数据库·mysql
Wang's Blog3 小时前
MySQL: 查询全流程深度解析与性能优化实践指南
数据库·mysql·性能优化
一 乐3 小时前
宠物管理|宠物共享|基于Java+vue的宠物共享管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·springboot·宠物
Wang's Blog3 小时前
MongoDB小课堂: 高级查询操作符与游标管理综合指南之深度整合逻辑操作符、字段处理、数组查询与游标控制的最佳实践
数据库·mongodb