如何在没有索引的情况下扫描redis数据库?

问题描述 投票:0回答:1

我最近正在开发一个旧版 Redis 数据库。我想删除一些具有特定模式的未使用的数据。但是表太大了,2亿个key。不幸的是,没有索引,因此扫描几乎不可能。以下是记录样本:

前缀:64_BIT_HASH@INDEX_A 前缀:128_BIT_HASH@INDEX_B 前缀:n_BIT_HASH@INDEX_C ...... 前缀:x_BIT_HASH@INDEX_N

数据库中定义了大约300种INDEX类型。我需要删除模式 PREFIX:64_BIT_HASH@INDEX_A

我在springboot中使用反应式redis数据进行扫描,然后进行过滤,首先列出匹配PREFIX:64_BIT_HASH@INDEX_A的所有键,但是由于有2亿条记录,扫描花了10个小时仍然无法返回。有没有办法通过限制结果数量进行扫描,例如每 20K 个键扫描一次,而不是所有键?

尝试使用以下代码进行扫描,但由于数据太大而无法返回。

public Flux<String> findGidsByDomain(String domain){
    String wildCastKey = "PREFIX:*@INDEX_A";
    ScanOptions opts = ScanOptions.scanOptions().match(wildCastKey).build();
    return redisTemplate.scan(opts).map(key -> keyBuilder.fetchKey(key)).filter(key -> key.length() == 64);
}
stackexchange.redis spring-data-redis
1个回答
0
投票

使用从connectionFactory构建的游标

LettuceConnectionFactory 连接工厂;

public Flux findxxxsByCode(String code, int limit){

String wildCastKey = keyBuilder.wildCastKey(code);
Cursor cursor = connectionFactory.getConnection()
  .scan(ScanOptions.scanOptions().match(wildCastKey).build());

List<String> result = new ArrayList<>();
long count = 0;
while(count < limit){
  String k = new String((byte[]) cursor.next());
  log.debug("find key={}", k);
  String key = keyBuilder.fetchKey(k);
  if(key.length() == 64) {
    result.add(key);
    count++;
  }
}
cursor.close();
return Flux.fromIterable(result);

}

© www.soinside.com 2019 - 2024. All rights reserved.