博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
redis sscan java_redis 用scan 代替keys,hgetAll
阅读量:5976 次
发布时间:2019-06-20

本文共 3328 字,大约阅读时间需要 11 分钟。

转载自: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:

*@paramkey

*@return*@returnlong

*@author2019-1-16 上午10:17:03*/

public static Map hscan(int dbIndex,String key,intpageSize){

Map map = new HashMap();

Jedis jedis= null;try{

jedis=getJedis();

jedis.select(dbIndex);

ScanParams sp= newScanParams();

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);

}returnmap;

}public static Map loop(MapmapList, String key, Jedis jedis, String cursor,

ScanParams sp) {try{

ScanResult> map =jedis.hscan(key, cursor, sp);

cursor=map.getStringCursor();for (Entryen : 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);

}returnmapList;

}

使用的jar包:jedis-2.9.0.jar,commons-pool2-2.4.2.jar

你可能感兴趣的文章
卓越质量管理成就创新高地 中关村软件园再出发
查看>>
linux rsync 远程同步
查看>>
httpd的manual列目录漏洞
查看>>
myeclipse2014破解过程
查看>>
漫谈几种反编译对抗技术
查看>>
Timer 和 TimerTask 例子
查看>>
Spring BOOT 集成 RabbitMq 实战操作(一)
查看>>
安装python3.5注意事项及相关命令
查看>>
进程通信之无名信号量
查看>>
并发串行调用接口
查看>>
Mongodb3.0.5副本集搭建及spring和java连接副本集配置
查看>>
FileStream大文件复制
查看>>
TDD 的本质不是 TDD
查看>>
linux命令学习——ps
查看>>
freemark 判断list是否为空
查看>>
JS的一些扩展:String、StringBuilder、Uri
查看>>
solr的suggest模块
查看>>
2PHP页面缓存
查看>>
菜鸟学Linux命令:bg fg jobs命令 任务管理
查看>>
【Linux系统编程】 Linux系统调用概述
查看>>