You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus/Mutiny中实现Redis scan功能是否必须使用递归?

非递归Redis SCAN实现方案

响应式客户端(适配你现有Mutiny技术栈)

你当前使用的是Mutiny响应式框架,直接调用框架内置的repeat操作符即可替代递归实现,逻辑更简洁,同时避免递归深度过大引发的栈溢出风险,完整实现如下:

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import io.smallrye.mutiny.Uni;

// 初始化结果集合与游标变量
List<String> results = new ArrayList<>();
AtomicReference<String> cursor = new AtomicReference<>("0");

Uni<List<String>> scanUni = Uni.createFrom().deferred(() -> {
            // 每次执行都用最新游标构造请求参数
            List<String> args = List.of(cursor.get(), "MATCH", "*");
            return reactiveRedisClient.scan(args);
        })
        // 配置重复执行规则
        .repeat()
        .until(item -> {
            // 存储本次扫描到的键
            List<?> keysPart = (List<?>) item.get(1);
            keysPart.forEach(k -> results.add(k.toString()));
            // 更新游标
            cursor.set(item.get(0).toString());
            // 游标返回0时终止循环
            return "0".equals(cursor.get());
        })
        // 取最后一次执行结果,转换为返回最终扫描结果的Uni
        .last()
        .map(ignored -> results);

// 订阅逻辑和原实现完全兼容
scanUni.subscribe().with(item -> LOGGER.info(item));

核心逻辑说明:

  • 用AtomicReference包装游标是因为Lambda表达式内只能引用final或等效final的变量,包装后可以自由修改内部存储的游标值
  • deferred操作符保证每次重复执行scan请求时,都会读取最新的游标值构造参数,不会复用第一次请求的参数
  • 所有循环逻辑都由框架内置操作符实现,没有自定义递归调用,可维护性更高

同步客户端通用实现

如果你使用的是同步Redis客户端(如Jedis),非递归实现更简单,直接用do-while循环即可:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import java.util.ArrayList;
import java.util.List;

List<String> results = new ArrayList<>();
String cursor = "0";
ScanParams params = new ScanParams().match("*");
do {
    ScanResult<String> scanResult = jedis.scan(cursor, params);
    results.addAll(scanResult.getResult());
    cursor = scanResult.getCursor();
} while (!"0".equals(cursor));

LOGGER.info(results);

内容的提问来源于stack exchange,提问作者Charlie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 16:36:04