How to get all Keys from Redis using redis template
Asked Answered
G

9

22

I have been stuck with this problem with quite some time.I want to get keys from redis using redis template. I tried this.redistemplate.keys("*"); but this doesn't fetch anything. Even with the pattern it doesn't work.

Can you please advise on what is the best solution to this.

Glottalized answered 30/9, 2013 at 15:27 Comment(0)
M
31

I just consolidated the answers, we have seen here.

Here are the two ways of getting keys from Redis, when we use RedisTemplate.

1. Directly from RedisTemplate

Set<String> redisKeys = template.keys("samplekey*"));
// Store the keys in a List
List<String> keysList = new ArrayList<>();
Iterator<String> it = redisKeys.iterator();
while (it.hasNext()) {
       String data = it.next();
       keysList.add(data);
}

Note: You should have configured redisTemplate with StringRedisSerializer in your bean

If you use java based bean configuration

redisTemplate.setDefaultSerializer(new StringRedisSerializer());

If you use spring.xml based bean configuration

<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>

<!-- redis template definition -->
<bean
    id="redisTemplate"
    class="org.springframework.data.redis.core.RedisTemplate"
    p:connection-factory-ref="jedisConnectionFactory"
    p:keySerializer-ref="stringRedisSerializer"
    />

2. From JedisConnectionFactory

RedisConnection redisConnection = template.getConnectionFactory().getConnection();
Set<byte[]> redisKeys = redisConnection.keys("samplekey*".getBytes());
List<String> keysList = new ArrayList<>();
Iterator<byte[]> it = redisKeys.iterator();
while (it.hasNext()) {
       byte[] data = (byte[]) it.next();
       keysList.add(new String(data, 0, data.length));
}
redisConnection.close();

If you don't close this connection explicitly, you will run into an exhaustion of the underlying jedis connection pool as said in https://mcmap.net/q/587324/-spring-redistemplate-after-8-calls-method-keys-hangs-up.

Mccord answered 19/8, 2016 at 6:17 Comment(0)
C
11

try:

Set<byte[]> keys = RedisTemplate.getConnectionFactory().getConnection().keys("*".getBytes());

Iterator<byte[]> it = keys.iterator();

while(it.hasNext()){

    byte[] data = (byte[])it.next();

    System.out.println(new String(data, 0, data.length));
}
Claireclairobscure answered 4/2, 2014 at 9:39 Comment(0)
F
6

Try redisTemplate.setKeySerializer(new StringRedisSerializer());

Fehr answered 18/2, 2015 at 17:15 Comment(2)
IMHO it's not the best solution because this may produce some error when using with HashOperationsOden
Yes it does gave me problem. You cannot put value of type other than string in this case.Jehoash
C
4

Avoid to use keys command. It may ruin performance when it is executed against large databases.

You should use scan command instead. Here is how you can do it:

RedisConnection redisConnection = null;
try {
    redisConnection = redisTemplate.getConnectionFactory().getConnection();
    ScanOptions options = ScanOptions.scanOptions().match("myKey*").count(100).build();

    Cursor c = redisConnection.scan(options);
    while (c.hasNext()) {
        logger.info(new String((byte[]) c.next()));
    }
} finally {
    redisConnection.close(); //Ensure closing this connection.
}

or do it much simplier with Redisson Redis Java client:

Iterable<String> keysIterator = redisson.getKeys().getKeysByPattern("test*", 100);
for (String key : keysIterator) {
    logger.info(key);
}
Caliban answered 22/3, 2020 at 7:10 Comment(1)
I have list of keys (data type as list) in redis cache and I want to get all the keys in one shot. Can we do this using redisson ?Fictionist
G
2

Try

import org.springframework.data.redis.core.RedisTemplate;
import org.apache.commons.collections.CollectionUtils;

String key = "example*";
Set keys = redisTemplate.keys(key); 
if (CollectionUtils.isEmpty(keys)) return null;
List list = redisTemplate.opsForValue().multiGet(keys);
Gosse answered 4/3, 2021 at 4:21 Comment(1)
Worked like charm!Corkage
S
1

It did work, but seems not recommended? Because we can't use Keys command in production. I assume RedisTemplate.getConnectionFactory().getConnection().keys is calling redis Keys command. What are the alternatives?

Swansdown answered 22/2, 2016 at 6:19 Comment(0)
F
1

I was using redisTemplate.keys(), but it was not working. So I used jedis, it worked. The following is the code that I used.

    Jedis jedis = new Jedis("localhost", 6379);
    Set<String> keys = jedis.keys("*".getBytes());
    for (String key : keys) {
        // do something
    } // for
Fierro answered 3/1, 2017 at 8:48 Comment(2)
API doc says this is for debug only, is that true?Irresolute
Should be "Set<byte[]> keys = jedis.keys("*".getBytes());"Cancan
G
0

Solution can be like this

String pattern = "abc"+"*";
Set<String> keys = jedis.keys(pattern);
for (String key : keys) {
    jedis.keys(key);
} 

Or you can use jedis.hscan() and ScanParams instead.

Glaciate answered 9/8, 2016 at 8:58 Comment(1)
do not use keys in production env, dangerousNahshu
S
0

This should work,

Jedis jedis = new Jedis("localhost");
String cursor = "0";
ScanParams scanParams = new ScanParams().match("*").count(100);

do {
    ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
    List<String> keys = scanResult.getResult();
    cursor = scanResult.getStringCursor();
    // do something with keys
} while (!cursor.equals("0"));
Swansdown answered 3/3, 2023 at 6:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.