Как использовать команды SCAN в Jedis
Я использовал redis и jedis в течение некоторого времени и никогда не нуждался в командах SCAN. Теперь, однако, мне нужно использовать команды SCAN, в частности hscan. Я понимаю, как он работает на уровне redis, но сторона-оболочка jedis Java запутывает меня. Существуют классы ScanResults
и ScanParameter
, и у меня нет четкого представления о том, как правильно их использовать. Документация по этой функции отсутствует или, по крайней мере, трудно найти. Может ли кто-нибудь указать, где найти достойные примеры того, как перебирать хэш с помощью hscan с jedis?
Извините, у меня нет кода, но то, что я пробовал до сих пор, просто не имеет никакого смысла.
Ответы
Ответ 1
В хорошей традиции ответа на собственные вопросы, вот что я узнал:
key = "THEKEY";
ScanParams scanParams = new ScanParams().count(100);
String cur = redis.clients.jedis.ScanParams.SCAN_POINTER_START;
boolean cycleIsFinished = false;
while(!cycleIsFinished){
ScanResult<Entry<String, String>> scanResult =
jedis.hscan(key, cur, scanParams);
List<Entry<String, String>> result = scanResult.getResult();
//do whatever with the key-value pairs in result
cur = scanResult.getStringCursor();
if (cur.equals("0")){
cycleIsFinished = true;
}
}
Важная часть состоит в том, что cur является переменной String и "0"
, если проверка завершена.
С помощью ScanParams я смог определить приблизительный размер каждого фрагмента, чтобы получить хэш. Приблизительный, потому что хэш может измениться во время сканирования, поэтому может быть, что элемент возвращается дважды в цикле.
Ответ 2
Мне не нравятся переменные флага
Jedis jedis = new Jedis("localhost");
ScanParams scanParams = new ScanParams().count(10).match("*");
String cur = SCAN_POINTER_START;
do {
ScanResult<String> scanResult = jedis.scan(cur, scanParams);
// work with result
scanResult.getResult().stream().forEach(System.out::println);
cur = scanResult.getStringCursor();
} while (!cur.equals(SCAN_POINTER_START));
Ответ 3
Предложение к приведенному выше примеру. Вы можете указать совпадение клавиш в классе scanParams. См. Ниже.
ScanParams scanParams = new ScanParams();
scanParams.match("*");
String cursor = redis.clients.jedis.ScanParams.SCAN_POINTER_START;
boolean cycleIsFinished = false;
while (!cycleIsFinished) {
ScanResult<String> scanResult = jedisRead.scan(cursor, scanParams);
List<String> result = scanResult.getResult();
/*
* do what you need to do with the result
*/
cursor = scanResult.getStringCursor();
if (cursor.equals("0")) {
cycleIsFinished = true;
}
}
Ответ 4
Если вы используете интерфейсы java.util.Iterator
или java.lang.Iterable
тогда вы можете попробовать попробовать Redison на основе Redison.
Вот пример того, как перебирать все ключи карты под именем "myMap", хранящиеся в Redis:
RedissonClient redissonClient = RedissonClient.create(config);
// implements java.util.concurrent.ConcurrentMap interface
RMap<String, String> map = redissonClient.getMap("myMap");
// default batch size on each HSCAN invocation is 10
for (String key: map.keySet()) {
...
}
// default batch size on each HSCAN invocation is 250
for (String key: map.keySet(250)) {
...
}
Вот пример того, как перебирать все ключи, хранящиеся в Redis:
RedissonClient redissonClient = RedissonClient.create(config);
RKeys keys = redissonClient.getKeys();
// default batch size on each SCAN invocation is 10
for (String key: keys.getKeys()) {
...
}
// default batch size on each SCAN invocation is 250
for (String key: keys.getKeys(250)) {
...
}
Очень просто, не так ли?