转载自:https://blog.csdn.net/w05980598/article/details/80264568

众所周知,当redis中key数量越大,keys 命令执行越慢,而且最重要的会阻塞服务器,对单线程的redis来说,简直是灾难,终于找到了替代命令scan。

SCAN cursor [MATCH pattern] [COUNT count]

SCAN 命令及其相关的 SSCAN 命令、 HSCAN 命令和 ZSCAN 命令都用于增量地迭代(incrementally iterate)一集元素(a collection of elements):

  • SCAN 命令用于迭代当前数据库中的数据库键。
  • SSCAN 命令用于迭代集合键中的元素。
  • HSCAN 命令用于迭代哈希键中的键值对。
  • ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值)。

以上列出的四个命令都支持增量式迭代, 它们每次执行都只会返回少量元素, 所以这些命令可以用于生产环境, 而不会出现像 KEYS命令、 SMEMBERS 命令带来的问题 —— 当 KEYS 命令被用于处理一个大的数据库时, 又或者 SMEMBERS 命令被用于处理一个大的集合键时, 它们可能会阻塞服务器达数秒之久。

不过, 增量式迭代命令也不是没有缺点的: 举个例子, 使用 SMEMBERS 命令可以返回集合键当前包含的所有元素, 但是对于 SCAN 这类增量式迭代命令来说, 因为在对键进行增量式迭代的过程中, 键可能会被修改, 所以增量式迭代命令只能对被返回的元素提供有限的保证 (offer limited guarantees about the returned elements)。

因为 SCAN 、 SSCAN 、 HSCAN 和 ZSCAN 四个命令的工作方式都非常相似, 所以这个文档会一并介绍这四个命令, 但是要记住:

  • SSCAN 命令、 HSCAN 命令和 ZSCAN 命令的第一个参数总是一个数据库键。
  • 而 SCAN 命令则不需要在第一个参数提供任何数据库键 —— 因为它迭代的是当前数据库中的所有数据库键。
scan 0 默认返回10条数据。
127.0.0.1:6379> scan 0
1) "81920"
2)  1) "CMD:1000004739:4"
    2) "CMD:1000010475:2"
    3) "CMD:380071400001208:766"
    4) "CMD:1000006866:LIST"
    5) "CMD:380071400001208:20415"
    6) "CMD:380071400001231:21530"
    7) "CMD:380071400001208:21780"
    8) "CMD:7485630165:LIST"
    9) "CMD:1000001545:2"
   10) "CMD:380071400001231:4387"
 
可以用count 参数指定返回数据量:
127.0.0.1:6379> scan 0 count 100
1) "104448"
2)   1) "CMD:1000004739:4"
     2) "CMD:1000010475:2"
     3) "CMD:380071400001208:766"
     4) "CMD:1000006866:LIST"
     5) "CMD:380071400001208:20415"
     6) "CMD:380071400001231:21530"
     7) "CMD:380071400001208:21780"
     8) "CMD:7485630165:LIST"
     9) "CMD:1000001545:2"
    10) "CMD:380071400001231:4387"
    ......
    94) "CMD:201610200062:6"
    95) "CMD:VF3748211006:3"
    96) "CMD:1000009121:4"
    97) "CMD:380071400001231:6563"
    98) "CMD:1000010252:ID"
    99) "CMD:1000005261:5"
   100) "SERVER:45568_0"
 
使用match 参数来匹配模式:
127.0.0.1:6379> scan 0 match CMD* count 100
1) "104448"
2)  1) "CMD:1000004739:4"
    2) "CMD:1000010475:2"
    3) "CMD:380071400001208:766"
    4) "CMD:1000006866:LIST"
    5) "CMD:380071400001208:20415"
    6) "CMD:380071400001231:21530"
    7) "CMD:380071400001208:21780"
    8) "CMD:7485630165:LIST"
    9) "CMD:1000001545:2"
   10) "CMD:380071400001231:4387"
   ......
   86) "CMD:201610200062:6"
   87) "CMD:VF3748211006:3"
   88) "CMD:1000009121:4"
   89) "CMD:380071400001231:6563"
   90) "CMD:1000010252:ID"
   91) "CMD:1000005261:5"
最重要的是scan不会阻塞服务器,现网环境也可以用,真方便。
 
 
 
官方文档:http://redisdoc.com/key/scan.html#scan
 
 
上java 代码 
 
    /**
*
* HSCAN 命令用于迭代哈希键中的键值对。
* @Title: getSortedSetSize
* @Description:
* @param key
* @return
* @return long
* @author 2019-1-16 上午10:17:03
*/
public static Map<String, String> hscan(int dbIndex,String key,int pageSize){
Map<String, String> map = new HashMap<String, String>();
Jedis jedis = null;
try {
jedis = getJedis();
jedis.select(dbIndex);
ScanParams sp = new ScanParams();
sp.count(pageSize);//每次多少条 //可以设置模糊查询
loop(map, key, jedis, "0", sp);
} catch (Exception e) {
logger_xt_err.error(e.getMessage());
return null;
}finally{
// 返还到连接池
if(jedis!=null)close(jedis);
}
return map;
} public static Map<String, String> loop(Map<String, String> mapList, String key, Jedis jedis, String cursor,
ScanParams sp) {
try {
ScanResult<Entry<String, String>> map = jedis.hscan(key, cursor, sp);
cursor = map.getStringCursor();
for (Entry<String, String> en : map.getResult()) {
mapList.put(en.getKey(), en.getValue());
}
System.out.println("cursor:" + cursor);
} catch (Exception e) {
e.printStackTrace();
return null;
} if (!"0".equals(cursor)) {
loop(mapList, key, jedis, cursor, sp);
}
return mapList;
}
使用的jar包:jedis-2.9.0.jar,commons-pool2-2.4.2.jar
 
 
 
 
 
 
 

redis 用scan 代替keys,hgetAll的更多相关文章

  1. redis中scan和keys的区别

    scan和keys的区别 redis的keys命令,通来在用来删除相关的key时使用,但这个命令有一个弊端,在redis拥有数百万及以上的keys的时候,会执行的比较慢,更为致命的是,这个命令会阻塞r ...

  2. 在RedisTemplate中使用scan代替keys指令

    keys * 这个命令千万别在生产环境乱用.特别是数据庞大的情况下.因为Keys会引发Redis锁,并且增加Redis的CPU占用.很多公司的运维都是禁止了这个命令的 当需要扫描key,匹配出自己需要 ...

  3. redis之Scan

    scan 相比keys 具备有以下特点:1.复杂度虽然也是 O(n),但是它是通过游标分步进行的,不会阻塞线程;2.提供 limit 参数,可以控制每次返回结果的最大条数,limit 只是一个 hin ...

  4. 用redis的scan命令代替keys命令,以及在spring-data-redis中遇到的问题

    摘要 本文主要是介绍使用redis scan命令遇到的一些问题总结,scan命令本身没有什么问题,主要是spring-data-redis的问题. 需求 需要遍历redis中key,找到符合某些pat ...

  5. redis中使用SCAN代替KEYS

    前言 由于redis的keys命令是线上禁用,所以就有了SCAN.SSCAN.HSCAN和ZSCAN四个命令. 但是这四个命令也不是每次返回全部匹配结果,因此需要一遍遍执行下去,而且每次返回的curs ...

  6. Java Redis的Pipeline管道,批量操作,节省大量网络往返时间 & Redis批量读写(hmset&hgetall) 使用Pipeline

    一般情况下,大家使用redis去put/get都是先拿到一个jedis实例,然后操作,然后释放连接:这种模式是 请求-响应,请求-响应 这种模式,下一次请求必须得等第一次请求响应回来之后才可以,因为r ...

  7. Redis 通过 scan 找出不过期的 key

    SCAN 命令是一个基于游标的迭代器(cursor based iterator):SCAN 命令每次被调用之后,都会向用户返回一个新的游标,用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游 ...

  8. Redis命令参考(Keys & String)

    r = redis.Redis(ip, port, index) 如此实例化一个redis对象,index取值0-15,一个redis对象有16个库. Keys 函数 功能 返回值 备注 keys(s ...

  9. Python Redis中Scan遇到问题

    在项目启动中需要删除redis原先相同key储存的值,所以使用scan_iter来便利相关的key,并删除. 这里需要注意两个性能问题 1. scan_iter的模糊匹配的过滤器要正确,否则会带来很多 ...

随机推荐

  1. xss part2

    0x01 xss challenge level 6-10 1.1 level 6 test with typical, notice the script has changed change sc ...

  2. 不显示Zetero导出的文献库中的部分内容

    不显示Zetero导出的文献库中的部分内容 Zetero作为文献管理软件,收集到的参考文献的相关信息(域fields)比较齐全.文章或书籍的引用中仅仅只用到了其中的一部分,如作者.发表年.题名.期刊( ...

  3. Java基础加强-内部类及代理

    /*内部类是一个编译时的概念,*/ 常规内部类.静态内部类.局部内部类.匿名内部类 1.常规内部类(常规内部类没有static修饰且定义在外部类类体中) 1.常规内部类中的方法可以直接使用外部类的实例 ...

  4. 多进程之multiprocessing模块和进程池的实现

    转载:https://www.cnblogs.com/xiaobeibei26/p/6484849.html Python多进程之multiprocessing模块和进程池的实现 1.利用multip ...

  5. 通过mysql 连接远程数据库时,输入密码后,提示10060错误

    能提示输入密码,说明网络能够连接,而且能连到服务器.输入密码后提示错误,说明应该是权限问题 解决方法: ​一.进入mysql数据库命令行 ​二.输入use mysql; ​三.设置root账号密码为1 ...

  6. 移动端rem移动适配

    https://www.cnblogs.com/jingwhale/p/5741567.html

  7. golang map多层嵌套使用及遍历方法汇总

    原文:https://blog.csdn.net/boyhandsome7/article/details/79734847 ------------------------------------- ...

  8. HashMap源码分析二

    jdk1.2中HashMap的源码和jdk1.3中HashMap的源码基本上没变.在上篇中,我纠结的那个11和101的问题,在这边中找到答案了.   jdk1.2   public HashMap() ...

  9. [NOI2012]骑行川藏——拉格朗日乘子法

    原题链接 不会啊,只好现学了拉格朗日乘子法,简单记录一下 前置芝士:拉格朗日乘子法 要求\(n\)元目标函数\(f(x_1,x_2,...,x_n)\)的极值,且有\(m\)个约束函数形如\(h_i( ...

  10. 零基础免费搭建个人博客-hexo+github

    使用hexo生成静态博客并架设在免费的github page平台 准备 系统: Window 7 64位 使用软件: Git v1.9.5[下载地址] 百度云 360云盘 访问密码 d269 Git官 ...