redis的scan操作

redis的scan操作

閱讀本文約花費: 2 (分鐘)

redis系列

在redis的db存在大量key或者db里头的某个set、zset、hash里头的元素非常多的话,用普通的get all操作很可能导致redis因为这个操作阻塞了,导致不能响应其他操作,特别是在高并发、海量数据的背景下,这个问题显得尤其严重。那么能不能像数据库那样有个分页的功能呢,答案就是scan操作。本文主要展示怎么在redis-cli以及SpringDataRedis中的使用。

scan语法

scan之后返回两部分,第一部分是下次scan的参数,第二部分就是scan出来的项

作用对象(db、set、zset、hash)

  • db(key)
127.0.0.1:6379> scan 0 1)"120" 2) 1)"articleMap:63" 2)"articleMap:37" 3)"counter:__rand_int__" 4)"articleMap:60" 5)"tagSet:tag5" 6)"articleMap:80" 7)"messageCache~keys" 8)"mymap" 9)"articleMap:46" 10)"articleMap:55" 127.0.0.1:6379> scan 120 1)"28" 2) 1)"articleMap:17" 2)"tagSet:tag1" 3)"articleMap:18" 4)"articleMap:81" 5)"xacxedx00x05tx00btest-cas" 6)"articleMap:51" 7)"articleMap:94" 8)"articleMap:26" 9)"articleMap:71" 10)"user-abcde"
  • set(value)
127.0.0.1:6379> sscan myset 0 1)"3" 2) 1)"m" 2)"j" 3)"c" 4)"h" 5)"f" 6)"i" 7)"a" 8)"g" 9)"n" 10)"e" 11)"b" 127.0.0.1:6379> sscan myset 3 1)"0" 2) 1)"l" 2)"k" 3)"d"
  • zset(value & score)
127.0.0.1:6379> zscan sortset 0 1)"0" 2) 1)"tom" 2)"89" 3)"jim" 4)"90" 5)"david" 6)"100"
  • hash(key & value)
127.0.0.1:6379> hscan mymap 0 1)"0" 2) 1)"name" 2)"patterncat" 3)"email" 4)"[email protected]" 5)"age" 6)"20" 7)"desc" 8)"hello" 9)"sex" 10)"male"

SCAN的额外参数

  • count(指定每次取多少条)
127.0.0.1:6379> scan 0 count 5 1)"240" 2) 1)"articleMap:63" 2)"articleMap:37" 3)"counter:__rand_int__" 4)"articleMap:60" 5)"tagSet:tag5"
  • match(匹配key)
127.0.0.1:6379> scan 0 match article* 1)"120" 2) 1)"articleMap:63" 2)"articleMap:37" 3)"articleMap:60" 4)"articleMap:80" 5)"articleMap:46" 6)"articleMap:55"

RedisTemplate操作

遍历数据库key

@Test public void scanDbKeys(){ template.execute(new RedisCallback<Iterable<byte[]>>() { @Override public Iterable<byte[]> doInRedis(RedisConnection connection) throws DataAccessException { List<byte[]> binaryKeys = new ArrayList<byte[]>(); Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().count(5).build()); while (cursor.hasNext()) { byte[] key = cursor.next(); binaryKeys.add(key); System.out.println(new String(key, StandardCharsets.UTF_8)); } try { cursor.close(); } catch (IOException e) { // do something meaningful } return binaryKeys; } }); }

遍历set

/** * sadd myset a b c d e f g h i j k l m n */ @Test public void scanSet(){ Cursor<String> cursor = template.opsForSet().scan("myset",ScanOptions.NONE); while (cursor.hasNext()){ System.out.println(cursor.next()); } }

遍历zset

/** * zadd sortset 89 tom 90 jim 100 david */ @Test public void scanZSet(){ Cursor<ZSetOperations.TypedTuple<String>> cursor = template.opsForZSet().scan("sortset",ScanOptions.NONE); while (cursor.hasNext()){ ZSetOperations.TypedTuple<String> item = cursor.next(); System.out.println(item.getValue() +":"+ item.getScore()); } }

遍历hash

/** * hset mymap name"patterncat" * hset mymap email"[email protected]" * hset mymap age 20 * hset mymap desc"hello" * hset mymap sex"male" */ @Test public void scanHash(){ Cursor<Map.Entry<Object, Object>> curosr = template.opsForHash().scan("mymap", ScanOptions.NONE); while(curosr.hasNext()){ Map.Entry<Object, Object> entry = curosr.next(); System.out.println(entry.getKey()+":"+entry.getValue()); } }

参考

Rate this post
No tags for this post.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注