LRANGE 的危险用法
LRANGE 按区间返回列表元素,复杂度与返回元素数相关:起点越靠后要先跳过一段,元素越多代价越大。真正危险的不是命令本身,而是「跨全表」的写法:在大列表上执行区间覆盖全表,主线程会被长时间占用,输出缓冲同时按元素总量膨胀,内存与延迟一起被推高。
基本信息
| 复杂度 | O(S+N),S 为起点到端点的距离,N 为返回元素数 |
|---|---|
| 全量读法 | LRANGE key 0 -1(生产大列表上属于高危操作) |
| 分页 | 按区间切片,游标要按内容或时间桶设计 |
| 替代结构 | stream 消费者组,或按时间分桶多个列表 |
| 观测 | LLEN 看规模,MEMORY USAGE 看体积 |
| 影响面 | 主线程阻塞、输出缓冲膨胀、客户端内存压力 |
典型使用场景
- 队列消费:小批量取出后裁剪,或改用带确认机制的 stream
- 列表分页展示:按时间桶拆成多个列表,每页只读一个桶
- 日志与流水类数据:改用 stream,自带 ID、消费组与确认
- 阻塞排查:延迟尖峰与 LRANGE 大区间调用同期出现时用慢查询日志确认
- 大 key 治理:先看规模与体积,再决定是裁剪、分桶还是换结构
最小示例
最小示例
redis-cli LLEN big:list # 先看规模,再决定怎么读
redis-cli LRANGE big:list 0 99 # 分页读,每批控制在百级
redis-cli LRANGE big:list 100 199 # 下一页
redis-cli LTRIM big:list 100 -1 # 取完即裁剪,控制单键规模
redis-cli SLOWLOG GET 10 # 确认是否有大区间读取拖慢实例
redis-cli MEMORY USAGE big:list # 单键体积评估代价与替代
| 做法 | 代价 | 替代方案 |
|---|---|---|
| LRANGE key 0 -1 | 长时占用主线程并放大输出缓冲 | 分页读,或读完立即裁剪 |
| 固定索引分页 | 并发写入时出现重复或漏读 | 以元素内容或时间桶作为游标 |
| 一次取走大批量 | 客户端内存与网络同时承压 | 限批读取,边取边处理 |
| 用列表做长期队列 | 堆积后任何读取都变危险 | 改用 stream 消费者组 |
代价主要随返回元素数增长,起点越靠后还要多花一段定位开销;判断风险时看「这次要返回多少条」,而不是列表总长。
做队列时「取一批再裁剪」要考虑竞态:多个消费者同时 LTRIM 会互相截断,最好串行消费或直接改用 stream。