复杂度随数据量增长的命令
有一类命令的复杂度会随数据量线性增长甚至更差,在数据量大时会长时间占用主线程,把整个实例拖慢,影响的不是一次请求而是所有并发请求。典型的有遍历全部键、一次性取出整个集合、读取整个列表、带条件排序,以及参与集合很大的集合运算。判断标准很简单:先知道数据量级,再决定用哪条命令。
基本信息
| 风险特征 | 复杂度随元素或键数量线性增长甚至更差 |
|---|---|
| 影响范围 | 主线程被占用,所有并发请求一起变慢 |
| 高发命令 | 全键遍历、整体取出、大范围读取、集合运算 |
| 替代思路 | 分批增量遍历,逐段读取 |
| 判断前提 | 先确认数据量级再选命令 |
典型使用场景
- 线上出现周期性延迟尖峰,排查是否存在全量遍历类命令
- 代码评审时拦截在生产代码里出现的全量扫描写法
- 把历史遗留的全量读取改写为分批遍历,降低阻塞风险
- 为运维脚本设置规范:禁止在未知规模的数据上直接全量取
- 压测阶段构造接近真实规模的数据,避免小数据集掩盖问题
替代写法
替代写法
# 用分批遍历代替一次性全量获取
redis-cli --scan --pattern 'user:*' | head -20 # 增量遍历示例
redis-cli SCAN 0 COUNT 100 # 单次游标遍历
redis-cli HSCAN myhash 0 COUNT 50 # 分区段读取大哈希
redis-cli SORT mylist BY weight_* LIMIT 0 20 # 排序加范围限制
redis-cli SLOWLOG GET 10 # 回看慢命令记录常见命令与替代
| 命令类型 | 风险点 | 替代方式 |
|---|---|---|
| 全键遍历 | 扫描整个键空间 | 改为增量遍历并按批次处理 |
| 整体取出集合 | 一次返回全部元素 | 分批读取并限制单次数量 |
| 大范围列表读取 | 一次拉取整条列表 | 按区间分段读取 |
| 排序类操作 | 数据量大时开销成倍上升 | 加上范围限制或改由离线计算 |
| 集合运算 | 参与集越大耗时越长 | 预先裁剪数据量或改为异步计算 |
先知道量级再决定命令:小集合上这些命令完全可以放心使用,大集合上同样的写法就变成了事故隐患。
用增量遍历替代全量扫描时要注意它只是弱一致的遍历方式,遍历过程中新增或删除的键可能不被包含,业务逻辑要能接受这一点。