redis HSCAN命令及jedis的hscan方法

参考文档:

http://doc.redisfans.com/key/scan.html

hscan是针对hash类型扫描,如果hash内条目非常多时,比如超过10万,那么根据默认的count = 10,每次扫描返回空的概率很大,此时可以根据情况把count调大:

下边是对jedis的 hscan进行了封装:

@Override
	public ScanResults hscanToResltByVague(String key, String pattern, String cursor, int pageSize) {
		List<Map.Entry<String, String>> result = null;
		List<Map.Entry<String, String>> results = new ArrayList<Map.Entry<String, String>>();
		ScanResults rsl = new ScanResults();
		ScanParams params = new ScanParams();
		String scanCursor = "0";
		if (!RobotUtils.isNull(cursor)) {
			scanCursor = cursor;
		}
		params.count(pageSize + 50);
		do {
			ScanResult<Entry<String, String>> scanResult = jedis.hscan(key, scanCursor, params.match(pattern));
			scanCursor = scanResult.getStringCursor();
			result = scanResult.getResult();
			results.addAll(result);
			if (results.size() >= pageSize) {
				break;
			}
		} while (!scanCursor.equals("0"));
		rsl.setCursor(scanCursor);
		rsl.setResultsEntry(results);
		rsl.setResultSize(results.size());
		return rsl;
	}

 实际使用:

@Test
     public void testRedisHscan() throws InterruptedException {
         
         Thread.sleep(1000*40);
         
         long start = System.currentTimeMillis();
         
         DataCache cache = DataCacheFactory.getInstance();
         //ScanResults rs = cache.hscanToResltByVague("METADATA:VDITEMS", "c3ed2101aa56421d9f0eb23e4b719c29*", "0", 50000);
         List<HashMap<String, String>> lst = cache.hscanToResltByVague(SysConfig.getProperty("metadata.cache.vdItem"), "c3ed2101aa56421d9f0eb23e4b719c29*", "0", 50000).getResults();
         
        long end = System.currentTimeMillis();
         
         System.out.println("+++++++++++++++++耗时:"+(end-start));
         try {
            System.out.println("+++++++++++++++++耗时:"+(end-start)+"     结果:"+JSONUtils.serializeObject(lst));
        } catch (IOException e) {
            // TODO Auto-generated catch block
             e.printStackTrace();
        }
     }

 

 

### Redis HSCAN 命令概述 HSCANRedis 提供的一个用于增量迭代哈希表键值对的命令。它类似于 SCAN 和 SSCAN,能够高效地分批获取哈希中的字段及其对应值,避免一次性加载整个数据集到内存中,从而减少服务器负载。 #### 基本语法 以下是 HSCAN 的基本语法: ```bash HSCAN key cursor [MATCH pattern] [COUNT count] ``` - **key**: 要扫描的目标哈希名称。 - **cursor**: 游标参数,初始调用时应设置为 `0`,后续调用则使用上一次返回的结果中的游标值。 - **MATCH pattern** (可选): 只匹配特定模式的字段名。 - **COUNT count** (可选): 指定每次迭代返回的大致数量,默认由 Redis 自动调整[^1]。 --- #### 返回值结构 HSCAN 返回一个数组,其中第一个元素是下次调用所需的游标值(字符串形式),第二个元素是一个包含字段和值的列表。当游标值变为 `0` 时表示已遍历完成。 --- #### 示例代码 以下是一些常见的 HSCAN 使用场景: ##### 场景一:简单全量扫描 假设有一个名为 `user:info` 的哈希存储了一些用户信息: ```redis > HMSET user:info name Alice age 25 city NewYork OK ``` 通过 HSCAN 遍历该哈希的所有字段和值: ```redis > HSCAN user:info 0 1) "0" 2) 1) "name" 2) "Alice" 3) "age" 4) "25" 5) "city" 6) "NewYork" ``` ##### 场景二:带 MATCH 参数过滤字段 仅查找以 `name` 开头的字段: ```redis > HSCAN user:info 0 MATCH name* 1) "0" 2) 1) "name" 2) "Alice" ``` ##### 场景三:控制 COUNT 数量 尝试每批次只读取两个字段: ```redis > HSCAN user:info 0 COUNT 2 1) "10" # 下次使用的游标值 2) 1) "name" 2) "Alice" 3) "age" 4) "25" > HSCAN user:info 10 COUNT 2 1) "0" # 表明已经结束 2) 1) "city" 2) "NewYork" ``` --- #### 解决问题的能力 相比直接使用 HGETALL 或 KEYS 来获取所有字段和值,HSCAN 更适合处理大规模数据集合。它可以有效防止因单次请求过多数据而导致的服务阻塞或性能下降。 另外,在实际应用中,可以通过 Python 等编程语言封装 HSCAN 功能实现更复杂的逻辑。例如,下面展示如何利用 Python 客户端库 `redis-py` 实现完整的哈希扫描功能: ```python import redis r = redis.StrictRedis(host='localhost', port=6379, db=0) def scan_hash(key): cursor = '0' while cursor != 0: cursor, data = r.hscan(key, cursor=cursor) for field, value in zip(data[::2], data[1::2]): print(f"{field.decode('utf-8')}: {value.decode('utf-8')}") # 测试函数 scan_hash("user:info") ``` 上述脚本会逐步打印出目标哈希内的所有字段与值组合。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值