从海量数据里查出某一固定前缀的key

一 留意细节

摸清数据规模,即问清楚边界


方法1: 利用keys pattern

KEYS pattern:查找所有符合给定模式pattern的key
eg: keys a* 找出所有以a开头的key

使用keys对线上业务的影响

  • KEYS指令一次性返回所有匹配的key
  • 键的数量过大会使服务卡顿

方法2:SCAN cursor match pattern count countnum

eg:scan 0 match *a count 10 从游标为0

  • 基于游标的迭代器,需要基于上一次的游标延续之前的迭代过程
  • 以0作为游标开始一次新的迭代,直到命令返回游标0完成一次遍历
  • 不保证每次执行都返回某个给定数量的元素,支持模糊查询
  • 一次返回的数量不可控,只能大概率符合count参数

二.关于scan的使用

下面提供两个我自己包装的scan,一个是hash里模糊取key,另外一个是直接string key的模糊取

   @Override
    @SuppressWarnings("unchecked")
    public <T> Map<String, T> hScan(String key, String pattern) {
        final Map<String, T> scanResult = Maps.newHashMap();
        try (Cursor<Map.Entry<Object, Object>> cursor = template.opsForHash().scan(key, ScanOptions.scanOptions()
                .count(Integer.MAX_VALUE)
                .match(pattern)
                .build())) {
            while (cursor.hasNext()) {
                final Map.Entry<Object, Object> entry = cursor.next();
                scanResult.put(String.valueOf(entry.getKey()), (T) entry.getValue());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return scanResult;
    }


  @Override
    public Set<String> scan(String pattern) {
        return template.execute((RedisCallback<Set<String>>) connection -> {
            Set<String> keysTmp = Sets.newHashSet();
            try (Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder()
                    .count(Integer.MAX_VALUE)
                    .match(pattern)
                    .build())) {
                while (cursor.hasNext()) {
                    keysTmp.add(new String(cursor.next()));
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            return keysTmp;
        });
    }

三.关于scan的坑

  • COUNT 选项只是对增量式迭代命令的一种提示(hint),不能代表返回的个数,它只是限定服务器单次遍历的字典槽位数量(约等于)。
  • count要根据扫描数据量大小而定,Scan虽然无锁,但是也不能保证在超过百万数据量级别搜索效率;count不能太小,网络交互会变多,count要尽可能的大。在搜索结果集1万以内,建议直接设置为与所搜集大小相同

其他坑可以点这里看官网

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容