一、高级数据结构:HyperLogLog(基数统计)
核心特性
-
数据结构实质
- 底层存储为 String 类型,用于海量数据去重计数。
- 牺牲精确性换取超高空间效率(标准误差 0.81%)。
-
核心原理
- 伯努利实验 + 极大似然估计 :通过计算二进制串首个
1
的位置(概率 \\approx \\frac{1}{2\^n} )估算基数。 - 分桶优化 :将数据哈希后分散到多个桶(默认 16384 桶),避免单一估计值偏差,提升精度。
- 伯努利实验 + 极大似然估计 :通过计算二进制串首个
-
应用场景
- UV(用户访问量)统计 :替代
SET
存储用户ID,内存占用极低(例:100万数据约 12KB)。 - PV(页面访问量) :需用计数器(如
INCR
),HyperLogLog 不适用。
- UV(用户访问量)统计 :替代
操作命令
命令 | 作用 | 示例 |
---|---|---|
PFADD key value [value...] |
添加元素 | PFADD uv:page1 "user1" "user2" |
PFCOUNT key [key...] |
统计基数 | PFCOUNT uv:page1 → 返回 2 |
PFMERGE destkey srcKey [srcKey...] |
合并多个键 | PFMERGE uv:total uv:page1 uv:page2 |
注意事项
- 重复插入自动去重 :
PFADD
相同值不影响统计结果。 - 内存优势 :100万数据内存占用约 12KB(16384 桶 × 6bit/桶)。
二、Redis事务Multi
1. 基本事务操作
- 开启事务 :
MULTI
→ 返回OK
,进入命令队列模式。 - 命令入队 :后续命令返回
QUEUED
,暂存服务端缓存。 - 提交执行 :
EXEC
一次性执行队列中所有命令。
bash
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> SET name "Alice"
QUEUED
127.0.0.1:6379(TX)> INCR counter
QUEUED
127.0.0.1:6379(TX)> EXEC # 提交事务
1) OK
2) (integer) 1
2. 事务错误处理
错误类型 | 表现 | 处理方式 |
---|---|---|
命令语法错误 (如 SETT key value ) |
入队时即报错,EXEC 拒绝执行 |
全体命令回滚 |
运行时错误 (如对字符串执行 ZADD ) |
错误命令失败,其他命令正常执行 | 无回滚(部分成功) |
bash
# 运行时错误示例(类型不匹配)
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> SET msg "hello" # 正确命令
QUEUED
127.0.0.1:6379(TX)> ZADD msg 100 "world" # 对字符串执行 ZADD
QUEUED
127.0.0.1:6379(TX)> EXEC
1) OK # SET 执行成功
2) (error) WRONGTYPE... # ZADD 执行失败
3. Watch 命令(乐观锁)
- 作用 :监视一个或多个 Key,若在
MULTI
-EXEC
期间被其他客户端修改,则事务失败。 - 流程 :
WATCH key
监视 Key。MULTI
开启事务 → 若 Key 被修改,事务自动失效。EXEC
返回(nil)
表示执行失败。
bash
# 客户端1
127.0.0.1:6379> WATCH balance
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> DECRBY balance 50 # 扣款 50
# 客户端2(在 EXEC 前修改 balance)
127.0.0.1:6379> INCRBY balance 100 # 增加余额
# 客户端1提交事务
127.0.0.1:6379(TX)> EXEC
(nil) # 因 balance 被修改,事务失败
4. 事务使用建议
- 避免使用 Redis 事务
不支持回滚、运行时错误仅部分失败,不符合 ACID。 - 替代方案 :
- Lua 脚本(原子执行复杂逻辑)。
- 7.0 函数库(支持分布式限流、原子下单等)。
三、Pipeline管道
1. 核心概念
-
本质 :客户端技术,用于优化网络传输效率。
-
原理 :将多个命令打包成单次网络请求发送给 Redis 服务端,服务端按顺序执行后,将结果一次性返回客户端。
-
与事务区别 :
特性 Pipeline 事务 (MULTI/EXEC) 执行层面 网络传输优化 服务端命令队列 原子性 ❌ 命令独立执行 ⚠️ 队列整体执行(非严格原子) 错误处理 失败命令不影响其他 语法错误全体回滚,运行时错误部分失败 性能影响 ⬆️ 显著提升吞吐量 ⬇️ 增加服务端内存压力
2. 工作流程
- 打包命令:
SET a 1
GET b
INCR c 2. 顺序执行所有命令 3. 批量返回:
OK
'valueb'
2 客户端 服务端 执行结果
3. 性能优势
-
减少网络延迟 :
N 条命令的耗时 ≈ 1次网络往返 + N 条命令执行时间
(对比普通模式:N次网络往返 + N条命令时间) -
基准测试 (本地环境示例):
命令数量 普通模式耗时 Pipeline 耗时 提升倍数 1,000 100ms 5ms 20× 10,000 1000ms 50ms 20×
4. 使用示例
命令行演示
bash
# 开启Pipeline(使用echo和nc工具)
(echo -en "SET key1 hello\r\nGET key1\r\nINCR counter\r\n"; sleep 1) | nc 127.0.0.1 6379
# 返回结果(一次性接收):
+OK
$5
hello
:1
5. 适用场景
-
批量数据导入
-
聚合查询优化
-
与事务结合使用
6. 注意事项
- 非原子性:其他客户端命令可能在 Pipeline 执行期间插入
- 内存控制:避免单次 Pipeline 包含过多命令(建议分批)
四、Pipeline vs Mult
特性 | Pipeline | Multi |
---|---|---|
本质 | 客户端批量发送命令(网络优化) | 服务端事务机制 |
原子性 | 无 | 命令队列整体执行 |
错误处理 | 命令独立执行/失败 | 语法错误全体回滚,运行时部分失败 |
组合使用 | 可将 MULTI/EXEC 放入 Pipeline 减少网络往返 |
--- |
五、Redis 7.0 新特性
- 分片 AOF
- 将 AOF 文件拆分为多个碎片,提升持久化效率和恢复速度。
- 函数库(Redis Functions)
- 支持预加载 Lua 脚本为函数,实现复杂原子操作(如分布式限流器)。
- 命令扩展
- 如
ZMPOP
(阻塞式弹出有序集合元素)、ZINTERCARD
(交集基数统计)等。
- 如
总结
组件 | 核心价值 | 适用场景 |
---|---|---|
HyperLogLog | 极低内存消耗统计海量 UV | 去重计数(误差容忍场景) |
事务Multi | 简单命令组合执行 | 需谨慎使用(推荐 Lua 替代) |
Pipeline | 提升批量命令网络吞吐量 | 批量操作优化 |