Redis是什么?为什么快?
Redis是一个开源的基于内存的、支持多种数据结构的Key-Value存储系统,适用于用来缓存、计数器(点赞、访问量)、排行榜(ZSet)、分布式锁、消息队列/延迟队列场景。
Redis的核心特性
- 高性能:读写操作通常在微秒级完成。
- 丰富的数据结构:支持String、Hash、List、Set、ZSet、Bitmap等。
- 持久化:支持RDB(快照)和AOF(日志)两种方式,重启后数据不丢失(先从AOF恢复,没有再用RDB,都没有就空库启动)
- 扩展功能:支持事务、发布订阅、Lua脚本、主从复制等。
Redis高性能的原因
基于内存操作
数据全部存储在内存中,避免了磁盘I/O的延迟,这是Redis速度快的根本原因。
单线程模型(6.0前)
"单线程"是指 Redis 的网络 I/O 和键值对读写是由一个主线程完成的。Redis 6.0 之前,Redis的瓶颈通常不在CPU,而在于内存和网络带宽,既然CPU不是瓶颈,那么多线程带来的锁竞争和上下文切换反而会成为累赘, 但是 6.0 之后 Redis 为了进一步提升 IO 的性能,引入了多线程机制,减少 Redis 由于网络 IO 等待造成的影响。
I/O多路复用
利用了OS的epoll(Linux)或kqueue( BSD )机制,采用Reactor模式,有一个文件事件分派器,通过epoll监听多个Socket,哪个Socket有数据了就交给主线程处理,实现非阻塞IO
高效协议与数据结构
使用二进制协议减少网络传输开销,内部采用优化数据结构(如哈希表、跳表)加速操作。
既然Redis是单线程的,为什么6.0后要引入多线程?
-
Redis6.0依旧是默认单线程处理命令,执行GET、SET这些操作的时候,依然由主线程串行执行。
-
引入多线程是为了解决网络IO瓶颈:网络数据读写(Read/Write系统调用)和协议解析占用主线程太多时间,Redis6.0引入多线程专门处理网络数据读写和协议解析,但命令执行依然是主线程排队做。
-
Redis6.0的多线程是多线程I/O,单线程执行
Redis常见数据类型
Redis 五大基本数据类型
String(SDS 实现)
-
数据结构:
len:记录字符串长度,O(1) 时间复杂度获取。alloc:表示分配给字符数组的存储空间大小,通过 aloc-len 可计算剩余空间,以判断是否满足修改需求,解决缓冲区溢出问题。flags:五种 SDS 类型(sdshdr5~sdshdr64),根据字符串长度动态选择以节省内存。buf:二进制安全的字符数组,可存储字符串、数字或二进制数据(最大 512MB)。
-
核心命令:
SET key value/GET keyINCR key/DECR key(原子计数器)SETNX key value(分布式锁实现)
-
应用场景:
- 缓存对象(如 JSON 字符串)。
- 计数器(阅读量、点赞数)利用INCR原子性。
- 分布式锁(利用
SETNX的互斥性)。 - 共享 Session(集中存储会话信息)。
Hash
-
数据结构:
- 底层为
ziplist(小数据量)或hashtable(大数据量)。
- 底层为
-
核心命令:
HSET key field value/HGET key field
-
应用场景:
- 存储对象(如用户信息,Key 为用户 ID,Field 为属性名)。
- 购物车(Key 为用户 ID,Field 为商品 ID,Value 为数量)。
List
-
数据结构:
- 双向链表,底层为
quicklist(ziplist和linkedlist的混合体)。
- 双向链表,底层为
-
核心命令:
LPUSH/RPUSH(左右插入)LPOP/RPOP(左右弹出)LRANGE key start stop(范围查询)
-
应用场景:
- 消息流(如朋友圈最新动态)。
Set
-
数据结构:
- 无序且去重,底层为
intset(整数集合)或hashtable。支持交并差集操作
- 无序且去重,底层为
-
核心命令:
SADD key member(添加元素)SINTER key1 key2(求交集)
-
应用场景:
- 标签系统、共同好友、抽奖(去重特性)。
ZSet(Sorted Set)
-
数据结构:
- 底层为
ziplist或SkipList(跳表),按score排序,查询效率 O(logN)。
- 底层为
-
核心命令:
ZADD key score memberZRANGE key start stop(按score升序)
-
应用场景:
- 排行榜(如游戏积分排名)。
- 延时队列(用
score存储执行时间)。
三大特殊数据类型
Bitmap
- 特点 :
- 通过二进制位记录状态,极度节省空间。
- 应用场景 :
- 签到统计、活跃用户分析。
HyperLogLog
- 特点 :
- 概率算法统计基数(唯一元素),误差率约 0.81%,占用内存固定。
- 应用场景 :
- 大规模 UV 统计(如统计每天有多少IP访问网站,用Set存浪费内存,用HyperLogLog合适。)。
Geo
- 数据结构 :
- 基于
ZSet存储经纬度,支持距离计算和范围查询。
- 基于
- 应用场景 :
- 附近的人、地理位置服务(如滴滴打车)。