在生产环境中如何用SSCAN无阻塞遍历Redis Set中的全量数据

小晨小哥_6435

小晨小哥_6435

2026-09-17

770人浏览

原创

不能直接用smembers遍历大set,因其会一次性加载全部元素阻塞主线程,导致redis卡顿、请求排队甚至超时熔断;应改用sscan分批遍历,以游标机制避免阻塞、降低内存与网络压力,并确保循环结束条件为cursor==0。

在生产环境中如何用sscan无阻塞遍历redis set中的全量数据

为什么不能直接用SMEMBERS遍历大Set

SMEMBERS会一次性把整个Set加载进内存并返回所有元素,对主线程是阻塞操作。当Set有几十万甚至百万成员时,Redis会卡住,其他客户端请求全部排队等待——这不是慢,是“暂时失联”。尤其在高并发缓存场景下,可能触发上游超时熔断。

常见错误现象包括:redis-cli执行SMEMBERS后长时间无响应、监控显示used_cpu_sys飙升、应用层报READTIMEOUTNOAUTH(其实是连接被挤掉)。

  • 底层原因:Redis 6.0之前是纯单线程,命令执行不可中断;即使6.0+,命令执行阶段仍是单线程
  • 内存压力:假设每个member平均占20字节,100万成员就需20MB响应体,再经网络序列化放大,容易打满带宽或触发客户端OOM
  • 没有游标机制,无法暂停/续传,失败就得重来

SSCAN的正确调用方式与参数取舍

SSCAN通过游标分批拉取,每次只处理一小块数据,不阻塞主线程。但默认行为并不够友好——比如COUNT太小会导致往返次数爆炸,太大又可能单次响应仍偏重。

Redis 8.2.3
Redis 8.2.3

Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。

下载

推荐组合:SSCAN key 0 MATCH * COUNT 500

  • cursor起始必须为0,后续用上一轮返回的新游标继续
  • MATCH *显式写出,避免某些客户端库默认不带导致漏匹配
  • COUNT 500是平衡点:比默认10快得多,又远低于单次10000可能引发的瞬时压力;实测在万级成员Set上,500~1000最稳
  • 不要依赖COUNT精确控制返回数量——Redis只保证“至少返回这么多”,实际可能更少(尤其接近尾部时)

如何写一个健壮的SSCAN循环(以Python为例)

关键不是“能跑通”,而是“不丢数据、不重复、可中断恢复”。游标归零不等于遍历结束,必须检查返回游标是否回到0才算完成。

cursor = 0
while cursor != 0:
    cursor, members = redis.sscan('myset', cursor, match='*', count=500)
    process_batch(members)  # 你的业务逻辑
    # 可在此处加sleep(0.01)主动让出CPU,降低对Redis吞吐影响
  • 务必用cursor != 0判断结束,而非len(members) == 0——空集合也可能返回cursor=0,但非空集合末尾游标也可能是0
  • 如果遍历中途崩溃,记录当前cursor值即可续跑,无需从头开始
  • 避免在process_batch里执行耗时操作(如HTTP请求、DB写入),否则会拖慢整体迭代节奏,间接延长Redis占用时间

生产环境必须注意的三个细节

SSCAN本身安全,但用法不当照样翻车。最容易被忽略的是这三点:

  • Set正在被并发写入时,SSCAN不保证强一致性——可能漏掉刚插入的元素,也可能重复返回刚删除又被加回的元素。这不是Bug,是设计使然;如需精确快照,请配合业务层加锁或使用WATCH+事务(代价高,慎选)
  • 如果Set底层编码是intset(全是整数且≤512个),SSCAN仍有效,但内部走的是线性扫描而非哈希表遍历,性能差异不大,无需特殊处理
  • 别在SCAN类命令上设超时(如socket_timeout=1)。网络抖动导致某次SSCAN失败,游标丢失就只能重来;应设合理长超时(如30秒),靠重试逻辑兜底

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.02

3969

19

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.14

3455

11

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.02

6112

6

redis怎么做缓存服务器
redis怎么做缓存服务器

redis 作为缓存服务器的答案:redis 是一款开源、高性能、分布式的键值存储,可作为缓存服务器使用。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

583

6

redis怎么解决数据一致性
redis怎么解决数据一致性

redis 提供了两种一致性模型,以维护副本数据一致性:强一致性 (sync) 确保写操作仅在复制到所有从节点后才完成;最终一致性 (async) 则在主节点上写操作后认为已完成,牺牲一致性换取性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

696

6

mysql和redis怎么保证双写一致性
mysql和redis怎么保证双写一致性

确保 mysql 和 redis 双写一致性的技术包括:1、事务性更新:同时更新 mysql 和 redis,保证一致性;2、主从复制:mysql 主服务器更改同步到 redis 从服务器;3、基于事件的更新:mysql 记录更改并发送到 redis等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

5482

6

redis缓存一般存些什么数据
redis缓存一般存些什么数据

redis缓存中存储的数据类型包括:字符串、哈希、列表、集合、有序集合、位图、地理空间数据和hyperloglog。这些数据类型适用于存储各种数据,从简单信息到复杂对象和地理位置。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

1120

6

redis的8种数据类型有哪些
redis的8种数据类型有哪些

redis 提供 8 种数据类型:字符串(文本、数字、二进制)、哈希(键值对)、列表(有序集合)、集合(无序唯一元素)、有序集合(按分数排序)、地理空间(地理位置)、hyperloglog(估计大数据基数)和位图(位序列存储)。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

916

6

redis主要作用有哪些
redis主要作用有哪些

redis 的主要作用包括:1. 缓存数据,提高访问速度;2. 充当消息队列,实现消息传递;3. 存储各种数据类型,如字符串、散列和集合;4. 管理会话信息,确保可靠性和可用性;5. 限制请求速率,防止服务器超载等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.04.07

4998

6

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
phpEnv手册
phpEnv手册

共0课时 | 0人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.5万人学习