• 技术文章 >数据库 >Redis

    一起聊聊redis的scan操作

    藏色散人藏色散人2021-09-12 14:51:55转载104
    redis系列
    • redis的发布订阅功能
    • redis消息队列
    • redis的pipeline
    • redis的scan操作

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

    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) "\xac\xed\x00\x05t\x00\btest-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) "codecraft"
        3) "email"
        4) "pt@g.cn"
        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 "codecraft"
         *  hset mymap email "pt@g.cn"
         *  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());
            }
        }

    以上就是一起聊聊redis的scan操作的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:segmentfault,如有侵犯,请联系admin@php.cn删除
    专题推荐:redis
    上一篇:深入浅析redis中的三种特殊数据类型 下一篇:简单聊聊Redis中GETBIT和SETBIT
    线上培训班

    相关文章推荐

    • redis整数集不能降级?为什么?• PHP+Redis解决订单限流的实际问题• 分享TP6框架中Redis操作服务类的记录• php 连接不上redis怎么办

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网