使用社交账号登录
Redis 是一个开源的,基于内存的Key - Value数据结构存储系统,它不仅支持数据的持久化 (可以将内存中的数据保存到磁盘,重启后再次加载),还可以作为数据库、缓存和消息中间件使用。

6.0+ 版本
简介: 字符串是 Redis 中最基本的数据结构,可以存储任意类型的数据,包括字符串、数字、二进制数据等。字符串的最大长度为 512MB。
常用指令:
SET key value:设置键值对GET key:获取键对应的值DEL key:删除键值对EXPIRE key seconds:设置键的过期时间(单位:秒)TTL key:获取键的剩余过期时间(单位:秒)应用场景:
SETNX命令实现分布式锁。简介: 哈希是一种键值对的集合,可以存储多个键值对。哈希的键和值只能是字符串类型。
常用指令:
HSET key field value:设置哈希表中指定字段的值HGET key field:获取哈希表中指定字段的值HDEL key field:删除哈希表中指定字段HGETALL key:获取哈希表中所有字段的值HINCRBY key field increment:对哈希表中指定字段的值进行自增操作应用场景:
Note: Redis Hash 的设计目标是高性能的扁平化键值存储,而非复杂的嵌套对象存储。因此,Redis Hash 并不适合存储嵌套对象,例如,嵌套的哈希或列表等,如果需要存储嵌套对象,建议使用 JSON 序列化后存储为字符串。
简介: 列表是一种有序的、可重复的元素集合,可以存储多个元素。列表的元素只能是字符串类型。
QuickList

QuickList
在 Redis 3.2+ 版本统一使用 QuickList.
QuickList = ZipList + linked list,它结合了 ZipList 和 linked list 的优点,既节省内存,又提高了性能。
在 Redis 7.0+ 版本,QuickList = ListPack + linked list,ListPack 是 ZipList 的升级版,它进一步优化了内存使用和性能。
常用指令:
LPUSH key value1 [value2]:将一个或多个值插入到列表头部RPUSH key value1 [value2]:将一个或多个值插入到列表尾部LPOP key:移除并返回列表的第一个元素RPOP key:移除并返回列表的最后一个元素LRANGE key start stop:获取列表指定范围内的元素LINDEX key index:获取列表指定索引的元素LLEN key:获取列表的长度应用场景:
LPUSH和RPOP指令将任务插入队列和从队列中取出任务。简介: Set 是 String 类型的无序集合,集合成员是唯一的,不允许重复。Set 提供了交集、并集、差集等数学集合操作。
常用指令:
应用场景:
简介: Sorted Set 是 Set 的升级版,每个成员关联一个分数 (score),集合按分数从小到大排序。成员唯一,但分数可重复。
当有序集合的元素小于 128 个,且每个元素的长度小于 64 字节时,使用 ziplist 编码,否则使用 skiplist 和 hash 编码。
SkipList

SkipList 示意图
跳表查询过程是从最高级索引开始,逐级向下查找,直到找到目标元素或到达最底层索引。跳表插入和删除操作也是从最高级索引开始,逐级向下进行,直到找到目标元素或到达最底层索引,然后进行相应的操作。
查找某个元素类似于二分查找,时间复杂度为 O(log n)。插入和删除操作需要更新索引,时间复杂度为 O(log n)。跳表的空间复杂度为 O(n),其中 n 是链表的长度。
为什么不用平衡树?
内存使用更灵活 平衡树:每个节点固定包含 2 个指针(左右子树) 跳表:每个节点的指针数量是动态的,平均为 1/(1-p) 在 Redis 中,p=1/4,所以平均每个节点包含 1.33 个指针 结论:跳表比平衡树节省内存
范围查询更简单 平衡树的问题:找到范围的起始值后,需要进行复杂的中序遍历来找到范围内的所有节点 跳表的优势:找到起始值后,只需要在第 1 层(最底层)链表上连续遍历即可 比喻:就像在图书馆找书,跳表相当于找到书架后直接从左到右拿书,而平衡树需要在整个图书馆里按特定顺序跳着找书
实现和维护更简单 平衡树的复杂性:插入和删除可能触发复杂的树结构调整(旋转操作),代码复杂,调试困难 跳表的简单性:插入和删除只需要修改相邻节点的指针,就像在链表中插入节点一样简单 实际好处:代码易读、易维护、易扩展(比如添加 ZRANK 功能只需要少量代码修改)
常用指令:
应用场景:
bash
ZADD game:rank 9500 player1 8800 player2
ZREVRANGE game:rank 0 9 WITHSCORES # 获取前 10 名
Redis 提供 RDB、AOF 及混合持久化机制,确保数据安全。
| 特性 | RDB (快照) | AOF (日志) | 混合持久化 (推荐) |
|---|---|---|---|
| 原理 | 特定间隔保存内存快照 | 记录每条写命令 | AOF 文件头部是 RDB 快照,尾部是 AOF 增量日志 |
| 优点 | 恢复极快,文件紧凑 | 数据丢失少(高安全性) | 兼顾恢复速度与数据安全性 |
RDB
save m n,m 秒内发生 n 次修改时触发。AOF
混合持久化
Redis 的 Key 过期后并非立即删除,而是采用惰性删除和定期删除两种策略,此目的是为了减少 CPU 和内存的消耗,如果采用立即删除策略,则必然要创建大量定时器或定期扫描所有 key,当数据量较大时,会严重影响 Redis 的性能。
| 策略 | 触发时机 | 工作原理 | 优点 |
|---|---|---|---|
| 惰性删除 | 当访问某个 Key 时 | 查询 key 时,如果 key 已过期,则删除并返回空值 | 减少 CPU 和内存的消耗,但可能导致内存泄漏 |
| 定期删除 | 周期性执行(100ms) | 随机抽取少量(如 20 个)设置了过期时间的 key,如果过期 key 比例>25% 则持续重复此步骤 | 减少内存泄漏,但可能导致部分 key 无法及时删除 |
如果某个 key 过期了,一直没被访问(没办法触发惰性删除),又一直没在定期删除中被删除,那么这个 key 就会一直占用内存,导致内存泄漏。因此,Redis 提供了内存淘汰策略,当内存不足时,会根据一定的规则删除一些 key,以释放内存。
触发条件: 当 Redis 内存使用达到 maxmemory 配置的值时,会触发内存淘汰策略。
| 策略 | 作用 | 适用场景 |
|---|---|---|
| noeviction | 不淘汰任何 key,达到 maxmemory 时直接报错 | 数据绝对不能丢失的常见 |
| allkeys-lru | 淘汰最近最少使用的 key | 纯缓存场景,所有 key 都可以淘汰 |
| allkeys-lfu | 淘汰访问量最低的 key | 需要精确淘汰低频数据 |
| allkeys-random | 随机淘汰 key | 不关心淘汰哪个 key |
| volatile-lru | 淘汰最近最少使用的设置了过期时间的 key | 部分 key 需要持久化 |
| volatile-lfu | 淘汰访问量最低的设置了过期时间的 key | 部分 key 需要持久化,需要精确淘汰低频数据 |
| volatile-random | 随机淘汰设置了过期时间的 key | 随机清理过期数据 |
| volatile-ttl | 淘汰即将过期的 key | 优先清理快过期的数据 |
如何选择?
选择 LRU
选择 LFU
混合使用
SADD key member1 member2 # 添加成员
SREM key member1 member2 # 移除成员
SMEMBERS key # 获取所有成员
SISMEMBER key member # 判断成员是否存在
SCARD key # 获取成员数量
SPOP key [count] # 随机移除并返回成员
SRANDMEMBER key [count] # 随机返回成员(不移除)
SINTER key1 key2 # 交集
SUNION key1 key2 # 并集
SDIFF key1 key2 # 差集
SINTERSTORE dest k1 k2 # 交集存储到新key
ZADD key score member # 添加成员及分数
ZREM key member # 移除成员
ZSCORE key member # 获取成员分数
ZINCRBY key increment member # 增加成员分数
ZCARD key # 获取成员数量
ZCOUNT key min max # 统计分数区间内成员数
# 正序(分数从低到高)
ZRANGE key start stop [WITHSCORES] # 按索引范围查询
ZRANGEBYSCORE key min max [WITHSCORES] # 按分数范围查询
ZRANK key member # 获取成员排名(从0开始)
# 倒序(分数从高到低)
ZREVRANGE key start stop [WITHSCORES]
ZREVRANGEBYSCORE key max min [WITHSCORES]
ZREVRANK key member
# 集合操作
ZUNIONSTORE dest numkeys key1 key2 # 并集
ZINTERSTORE dest numkeys key1 key2 # 交集