DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

Redis LRANGE 把条数当成结束下标后返回空列表

LRANGE 的 stop 是包含式结束下标。偏移量加数量接口应换算为 start + count - 1,并单独处理数量为零和列表并发变化。

Redis 列表长度很大,执行 LRANGE test 99999 100 却得到空列表。命令本来想表达“从下标 99999 开始取 100 条”,但 LRANGE 的第三个参数不是数量,而是包含在结果内的结束下标。

这条命令实际要求从 99999 读到 100,结束位置在起点之前,因此没有元素可返回。它不说明列表丢失,也不需要清空键或重新导入数据。

下面针对 Redis List 的 LRANGE key start stop。该命令从 Redis 1.0.0 起提供;客户端封装可能把参数改名为 end,仍需核对它实际传给 Redis 的值。

先确认键和区间

在已经使用应用相同连接、认证与逻辑数据库的 redis-cli 会话中,对一个已知键做只读检查:

TYPE test
LLEN test
LRANGE test 0 0

test 是示例键名,应替换为实际目标。类型应为 list;长度足够时,LRANGE test 0 0 返回第一项,因为起点和终点都包含在区间内。

如果键不存在,LLEN 返回 0,LRANGE 返回空数组;若键是别的数据类型,应处理类型或键名错误。先确认这些条件,再判断是否只是把条数误当成了结束位置。不要用整库扫描或一次读取千万条数据来验证一个区间参数。

这几条命令是分别执行的,不能把先前读取的长度当作后续请求的数据快照。检查期间若有其他客户端删除、弹出或改写列表,后续结果可能已经变化。

取 count 条时,结束下标要减一

对非负起始下标 start 和正整数 count,结束位置应计算为:

stop = start + count - 1

从下标 99999 开始最多取 100 条,对应:

LRANGE test 99999 100098

如果写成 100099,在数据足够时会拿到 101 条。一个元素的区间是 start 到 start,不是 start 到 start + 1。

应用接口使用“偏移量和数量”时,应在调用 Redis 的那一层完成转换,并明确检查数量为正、起点非负及计算没有溢出。数量为 0 时在应用中直接返回空结果,不要机械计算 stop = -1 后发请求;对于起点 0,-1 在 Redis 中代表列表最后一项,反而可能读取整个列表。

下面几组边界可用于对照客户端实际发送的命令:

需求 LRANGE 起点 LRANGE 终点
第一项 0 0
前 100 项 0 99
下标 100 起的 100 项 100 199
最后 10 项 -10 -1

最后一行直接使用 Redis 的负下标语义;不要把这组参数再套进“非负偏移量加数量”的转换函数。

数量不足时,空结果也可能正常

起点已经超过列表末尾时,Redis 返回空结果,不会用异常提醒越界。终点超过末尾时,则只返回实际存在的尾部元素。因此,“要求 100 条”不等于一定得到 100 条。

分页还要考虑列表是否持续在头部插入或弹出。即使每次的起止计算正确,前后两次请求的下标也可能对应不同元素,造成重复或漏读。修正 stop 只能解决参数含义错误,不能让这种分页自动获得稳定快照;需要完整处理一批任务时,应按业务一致性要求另行设计读取方式。

大列表的深位置读取也不是只看返回条数就能判断成本。LRANGE 需要定位起点并读取区间,排查时保持范围有界,不要把 0 -1 当作默认诊断命令。

验收并保留原数据

在固定内容的测试列表中,检查单项、恰好一页、最后不足一页、起点越界和数量 0 的应用分支。除了条数,还要核对首尾元素,确保没有把边界向前或向后错移一位。

记录修改前后的参数映射,回退时恢复调用代码即可,不需要删除 List。若旧分页已经漏读业务记录,应按实际处理记录补核,不能因为新的查询返回了数据,就直接重放全部任务造成重复处理。