Redis的核心是单线程事件驱动模型,使用epoll/kqueue/select实现高并发IO,默认持久化机制RDB和AOF结合使用,RDB通过fork子进程后台快照内存数据优化性能,避免阻塞主线程;AOF日志追加方式记录每条写操作,支持fsync策略everysec(每秒同步)平衡性能与数据安全;内存管理采用jemalloc分配器,减少碎片;键值存储底层skiplist和hash表实现有序集合和哈希高效查询;性能优化包括惰性删除和主动过期机制,过期键不立即释放而标记,后台定时扫描回收;管道化和多路复用减少网络往返,集群模式下分片提升吞吐量。实践应用中,设置maxmemory-policy allkeys-lru自动淘汰最小使用键,结合pipeline批量操作可达10万QPS。
Redis单线程模型详解
Redis使用单线程处理客户端请求,避免了上下文切换和锁竞争的开销。它的I/O多路复用机制(epoll/select)允许同时监听多个socket事件,主循环不断检查就绪事件并处理,极大提升了性能。默认情况下,所有命令都在这个单线程中串行执行,确保原子性和一致性。
RDB持久化原理
RDB(Redis DataBase)是Redis默认的持久化方式,通过bgsave命令fork一个子进程执行内存快照,父进程继续服务客户端,避免阻塞。快照文件是二进制格式,紧凑高效,save策略如save 900 1表示900秒内至少1个键变化时触发。性能优化点在于fork后copy-on-write机制,只复制修改页。
AOF持久化与混合模式
AOF(Append Only File)将每条写命令追加到日志文件,默认appendfsync everysec,每秒fsync一次,丢失最多1秒数据。重写机制bgrewriteaof压缩日志,减少体积。Redis 4.0引入混合持久化,RDB头+AOF尾部,启动更快。优化性能时,关闭no-appendfsync-on-rewrite避免重写时阻塞。
内存淘汰机制
Redis默认无内存限制时使用noeviction拒绝新写;实际应用中配置maxmemory并设置eviction policy,如volatile-lru(针对带TTL键的LRU)、allkeys-lru(所有键LRU)。源码中lazyfree-lazy-evict惰性删除,unref键计数为0时异步释放线程池处理,提升高负载下性能。
数据结构底层实现
String用sds简单动态字符串,节省空间;Hash用ziplist/htable,小数据压缩;List用quicklist(链表+ziplist);Set用intset(整数集合)或hashtable;ZSet用ziplist或skiplist+dict,skiplist概率跳表O(logN)查找。默认阈值如hash-max-ziplist-entries 512控制转换,优化小对象内存。
过期键处理
Redis默认键过期用惰性删除(访问时检查)+定时删除(hz=10次/秒随机采样)。源码serverCron函数实现,lazyfree过期键异步删除,避免阻塞。优化时调高hz值增加扫描频率,但消耗CPU。
集群与性能实践
Redis Cluster默认16384槽位哈希分片,gossip协议节点通信。性能优化:pipeline批量、多线程IO(I/O threading),复制异步,主从读写分离。监控info stats和latency doctor工具定位瓶颈。
FAQ
Q: Redis单线程为什么性能高?
A: 因为避免多线程锁和切换,I/O多路复用高效处理并发。
Q: RDB和AOF哪个更好?
A: RDB快照备份好,AOF数据安全高,建议混合用。
Q: 如何避免内存溢出?
A: 设置maxmemory和allkeys-lru策略。
Q: 过期键删除为什么不全即时删?
A: 即时删消耗CPU,惰性+定时平衡性能和准确性。