这里有新鲜出炉的 Redis 教程, 程序狗速度看过来!
Redis Key-Value 数据库
Redis 是一个开源的使用 ANSI C 语言编写, 支持网络, 可基于内存亦可持久化的日志型, Key-Value 数据库, 并提供多种语言的 API.
本篇文章主要介绍了 Java 使用 Pipeline 对 Redis 批量读写 (hmset&hgetall), 具有一定的参考价值, 有兴趣的可以了解一下.
一般情况下, 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 条记录, 就是小菜一碟, 秒完.
来源: http://www.phperz.com/article/18/0201/359092.html