tencent cloud

腾讯云分布式缓存数据库(兼容 Redis)

动态与公告
产品动态
公告
新手指引
产品简介
产品概述
产品优势
应用场景
存储引擎
产品系列
产品版本
规格与性能
读写分离
多可用区部署
地域和可用区
名词解释
购买指南
计费概述
定价中心
购买实例
续费说明(包年包月)
退费说明(包年包月)
欠费说明
按量转包年包月
快速入门
快速创建实例
连接 Redis 实例
操作指南
操作总览
连接数据库实例
管理实例
升级实例
管理节点(Redis/ValKey 版)
管理多可用区
备份与恢复
账号管理
参数配置
慢查询
访问管理
网络与安全
监控与告警
事件管理(Redis/ValKey 版)
数据迁移
Redis 版全球复制
数据库审计
诊断优化
Sentinel 模式
开发准则
命名规则
基本使用准则
Key 与 Value 设计原则
命令使用准则
客户端程序设计准则
连接池配置
命令参考
命令参考概览
Redis 版与 Valkey 版命令兼容性
大版本命令使用差异
Proxy 架构与直连模式的使用差异
命令更多操作(Redis/Valkey 版)
Memcached 版命令兼容性
实践教程
基于 Spring Boot 搭建 Redis 客户端监控
Redis 客户端连接配置策略与实践
集群架构全局 SCAN 使用指南
实例安全下线
热 Key 与 大 key
可用区迁移方案
故障处理
连接异常
Redisson 客户端超时重连异常分析及解决方案
性能排查与调优
API 文档
History
Introduction
API Category
Making API Requests
Instance APIs
Parameter Management APIs
Other APIs
Backup and Restoration APIs
Region APIs
Monitoring and Management APIs
Log APIs
Data Types
Error Codes
常见问题
使用常见问题
连接登录问题
购买相关问题
相关协议
服务等级协议
Terms of Service
词汇表
联系我们

集群架构全局 SCAN 使用指南

PDF
聚焦模式
字号
最后更新时间: 2026-03-17 18:23:48

基本介绍

腾讯云分布式缓存数据库集群版通过创新的 Proxy 架构解决了原生 Redis Cluster 不支持全局 SCAN 的限制,在原生 Redis Cluster 中,由于数据分散在多个分片节点,无法直接进行跨节点扫描操作;腾讯云通过扩展 SCAN 命令功能,支持两种精准扫描模式:用户可通过在命令末尾添加 NODEID 参数实现针对特定分片节点的定向扫描,同时从 Proxy 5.8.9 版本开始,全面支持无节点限制的全局 SCAN 操作,实现对集群所有分片数据的完整遍历能力。

使用限制

当集群发生节点切换(主从角色变更)、分片缩减(集群缩容)时,可能触发 SCAN 游标小概率的失效,导致游标对应的分片索引与实际节点映射关系断裂。若此时继续使用原游标执行扫描,系统将抛出错误 ,例如,-ERR invalid cursor(master node idx out of range)\\r\\n),此异常说明游标绑定的历史分片状态已失效。若强行忽略错误继续迭代,不仅无法获取有效数据,更会因游标与分片逻辑不同步进入死循环,严重消耗系统资源。

参考代码

腾讯云分布式缓存数据库Redis 集群环境下,执行 SCAN 操作时,若捕获到由集群拓扑变更引发的游标异常,需将游标重置为起始位0并重启全局扫描流程。该策略直接规避了因分片索引失效导致的游标死循环风险,确保数据遍历的完整性与安全性。如下代码实现了一个基于 Redis SCAN 命令的安全键扫描功能,特别针对大型 Redis 数据库的键遍历需求。具体连接配置,请参见 Jedis 连接 Redis
package com.example.service.impl;
import com.example.config.RedisConnectionFactory;
import com.example.service.RedisService;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.ScanParams;
import redis.clients.jedis.resps.ScanResult;
import java.util.*;
/**
* Redis服务实现类
*/
public class RedisServiceImpl implements RedisService {
//scan最大重试次数
private static final int MAX_RETRIES = 3;
private final RedisConnectionFactory connectionFactory;
/**
* 构造函数
*/
public RedisServiceImpl() {
this.connectionFactory = RedisConnectionFactory.getInstance();
}
/**
* scan最佳实践
* @param pattern 匹配的模式
* @param count 每次迭代返回的 key 的数量
*/
@Override
public void scanKeys(String pattern, int count) {
try (Jedis jedis = connectionFactory.getConnection()) {
int retryCount = 0;
boolean scanCompleted = false;
int totalKeysProcessed = 0;
int totalBatches = 0;
long startTime = System.currentTimeMillis();
// 对scan过程的报错进行捕获,遇到报错从0开始重新scan扫描
while (!scanCompleted && retryCount <= MAX_RETRIES) {
String cursor = ScanParams.SCAN_POINTER_START;
ScanParams scanParams = new ScanParams();
scanParams.count(count);
scanParams.match(pattern);
try {
while (true) {
ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
List<String> keys = scanResult.getResult();
totalBatches++;
if (!keys.isEmpty()) {
totalKeysProcessed += keys.size();
// 处理获取到的键 - 业务逻辑
processKeysWithBusinessLogic(keys);
}
cursor = scanResult.getCursor();
// 游标为"0"时完成扫描
if (cursor.equals(ScanParams.SCAN_POINTER_START)) {
long endTime = System.currentTimeMillis();
double timeElapsed = (endTime - startTime) / 1000.0;
System.out.println("\\n🎉 扫描完成!");
System.out.println("总批次数: " + totalBatches);
System.out.println("总键数: " + totalKeysProcessed);
System.out.println("扫描耗时: " + timeElapsed + " 秒");
System.out.println("平均速度: " + (totalKeysProcessed / timeElapsed) + " 键/秒");
scanCompleted = true;
break;
}
}
} catch (Exception e) {
retryCount++;
System.err.println("⚠️ 扫描过程中发生错误,尝试从0开始重新扫描 (" + retryCount + "/" + MAX_RETRIES + ")");
e.printStackTrace();
// 超过最大重试次数,终止重试
if (retryCount > MAX_RETRIES) {
throw new RuntimeException("达到最大重试次数 (" + MAX_RETRIES + "),扫描失败", e);
}
}
}
} catch (Exception e) {
System.err.println("扫描键失败: " + e.getMessage());
e.printStackTrace();
}
}
/**
* 处理键的业务逻辑
*/
private void processKeysWithBusinessLogic(List<String> keys) {
// 业务处理逻辑....
System.out.println(keys.size());
}
}

帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈