详解Java使用Pipeline对Redis批量读写(hmset&hgetall)
作者:引鸩怼孑 时间:2023-11-17 15:17:24
一般情况下,Redis Client端发出一个请求后,通常会阻塞并等待Redis服务端处理,Redis服务端处理完后请求命令后会将结果通过响应报文返回给Client。
感觉这有点类似于HBase的Scan,通常是Client端获取每一条记录都是一次RPC调用服务端。
在Redis中,有没有类似HBase Scanner Caching的东西呢,一次请求,返回多条记录呢?
有,这就是Pipline。官方介绍 http://redis.io/topics/pipelining
通过pipeline方式当有大批量的操作时候,我们可以节省很多原来浪费在网络延迟的时间,需要注意到是用pipeline方式打包命令发 送,redis必须在处理完所有命令前先缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并不是打包的命令越多越好。
使用Pipeline在对Redis批量读写的时候,性能上有非常大的提升。
Java测试了一下:
package com.lxw1234.redis;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.Response;
public class Test {
public static void main(String[] args) throws Exception {
Jedis redis = new Jedis("127.0.0.1", 6379, 400000);
Map<String,String> data = new HashMap<String,String>();
redis.select(8);
redis.flushDB();
//hmset
long start = System.currentTimeMillis();
//直接hmset
for (int i=0;i<10000;i++) {
data.clear();
data.put("k_" + i, "v_" + i);
redis.hmset("key_" + i, data);
}
long end = System.currentTimeMillis();
System.out.println("dbsize:[" + redis.dbSize() + "] .. ");
System.out.println("hmset without pipeline used [" + (end - start) / 1000 + "] seconds ..");
redis.select(8);
redis.flushDB();
//使用pipeline hmset
Pipeline p = redis.pipelined();
start = System.currentTimeMillis();
for (int i=0;i<10000;i++) {
data.clear();
data.put("k_" + i, "v_" + i);
p.hmset("key_" + i, data);
}
p.sync();
end = System.currentTimeMillis();
System.out.println("dbsize:[" + redis.dbSize() + "] .. ");
System.out.println("hmset with pipeline used [" + (end - start) / 1000 + "] seconds ..");
//hmget
Set<String> keys = redis.keys("*");
//直接使用Jedis hgetall
start = System.currentTimeMillis();
Map<String,Map<String,String>> result = new HashMap<String,Map<String,String>>();
for(String key : keys) {
result.put(key, redis.hgetAll(key));
}
end = System.currentTimeMillis();
System.out.println("result size:[" + result.size() + "] ..");
System.out.println("hgetAll without pipeline used [" + (end - start) / 1000 + "] seconds ..");
//使用pipeline hgetall
Map<String,Response<Map<String,String>>> responses = new HashMap<String,Response<Map<String,String>>>(keys.size());
result.clear();
start = System.currentTimeMillis();
for(String key : keys) {
responses.put(key, p.hgetAll(key));
}
p.sync();
for(String k : responses.keySet()) {
result.put(k, responses.get(k).get());
}
end = System.currentTimeMillis();
System.out.println("result size:[" + result.size() + "] ..");
System.out.println("hgetAll with pipeline used [" + (end - start) / 1000 + "] seconds ..");
redis.disconnect();
}
}
测试结果如下:
dbsize:[10000] ..
hmset without pipeline used [243] seconds ..
dbsize:[10000] ..
hmset with pipeline used [0] seconds ..
result size:[10000] ..
hgetAll without pipeline used [243] seconds ..
result size:[10000] ..
hgetAll with pipeline used [0] seconds ..
使用pipeline来批量读写10000条记录,就是小菜一碟,秒完。
来源:https://my.oschina.net/u/2273085/blog/419920
标签:java,redis,hgetall
0
投稿
猜你喜欢
Spring Boot 配置和使用多线程池的实现
2022-09-04 19:53:02
安卓Android6.0权限动态获取操作示例
2023-01-26 22:56:43
Android自定义定时闹钟开发
2023-07-07 00:18:01
c# RSA非对称加解密及XML&PEM格式互换方案
2022-07-10 12:19:31
itext生成PDF设置页眉页脚的实例详解
2023-12-05 19:04:45
Android中Fragment与Activity的生命周期对比
2021-12-12 06:28:01
Android小知识之OkHttp的2种请求方式详解
2021-06-05 04:33:45
Android 优雅的实现通用格式化编辑
2023-02-08 05:24:02
Android RecyclerView实现滑动删除
2022-11-20 19:50:42
Java三种方法将List转换为Map的实例
2023-08-21 09:02:41
Android adb命令中pm工具的作用及用法说明
2022-05-27 23:38:42
C# ManualResetEvent使用方法详解
2022-05-15 23:57:51
实例代码讲解JAVA 观察者模式
2023-09-11 19:22:18
DrawerLayout的简单使用及侧滑菜单实现详解
2023-04-27 04:10:59
Java 向上转型和向下转型的详解
2022-06-21 08:28:03
Spring Security自定义登录原理及实现详解
2022-11-20 21:57:39
使用SpringBoot获取所有接口的路由
2021-08-29 22:28:34
Log4j新手快速入门教程
2023-06-01 11:59:44
spring-boot使用Admin监控应用的方法
2023-06-28 19:58:39
jmeter+ant+jenkins自动化测试环境配置搭建过程
2023-11-17 23:38:06