下面是Java版的Redis客户端示例:
所需jar包网友可自行搜索下载,这里不再累赘
package redis;
import redis.clients.jedis.Jedis;
public class Redis {
public static void main(String[] args) {
Jedis jr = null;
try {
//redis服务地址和端口号
jr = new Jedis("127.0.0.1", 6379);
String key = "mkey";
jr.set(key,"hello,redis!");
String v = jr.get(key);
String k2 = "count";
jr.incr(k2);
jr.incr(k2);
System.out.println(v);
System.out.println(jr.get(k2));
} catch (Exception e) {
e.printStackTrace();
}
finally{
if(jr!=null){
jr.disconnect();
}
}
}
}
打印结果:
hello,redis!
2
edis客户端支持对象池,可以通过JedisPool.getResource方法从池中获取Jedis客户端对象,通过JedisPool.returnResource方法释放Jedis对象到池中,用对象池我们可以节省很多重新连接Redis Server的建议连接的时间,下面就是不用Jedis对象池与用Jedis对象池的一个性能对比:
测试方法:分别用直接new Jedis和从池中获取Jedis对象的方法,起200个并发,生个并发循环1000次。每个并发线程用一个Jedis对象。
测试代码如下:
package com.jd.redis.client;
import java.util.concurrent.CountDownLatch;
import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig;
publicclass JedisPoolTest {
privatestatic JedisPoolConfigconfig;//Jedis客户端池配置 privatestatic JedisPoolpool;//Jedis客户端池
static{ config =new JedisPoolConfig(); config.setMaxActive(60000); config.setMaxIdle(1000); config.setMaxWait(10000); config.setTestOnBorrow(true); pool =new JedisPool(config,"127.0.0.1", 6380); }
/** * 单笔测试(不用池) * @param count */ publicstaticvoid testNoPool(int count){ for(int i=0;i Jedis jr = null; try { jr = new Jedis("10.10.224.44", 6379); testOnce(jr); } catch (Exception e) { e.printStackTrace(); } finally{ if(jr!=null)jr.disconnect(); } } } /** * 单笔测试(用池) * @param count */ publicstaticvoid testWithPool(int count){ for(int i=0;i Jedis jr = null; try { jr = pool.getResource(); testOnce(jr); } catch (Exception e) { e.printStackTrace(); } finally{ if(jr!=null)pool.returnResource(jr); } } } /** * 并发测试(不用池) * @param paiallel并发量 * @param count每个并发循环次数 */ publicstaticvoid paiallelTestNoPool(int paiallel, int count){ Thread[] ts = new Thread[paiallel]; //用该对象保证所线程都完成主线程才退出 CountDownLatch cd = new CountDownLatch(paiallel); long start = System.currentTimeMillis(); for(int i=0; i < paiallel; i++){ ts[i] = new Thread(new WorkerNoPool(cd, count)); ts[i].start(); } try { cd.await();//等待所有子线程完成 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("NoPool useTime:"+ (System.currentTimeMillis() - start)); } /** * 并发测试(用池) * @param paiallel并发量 * @param count每个并发循环次数 */ publicstaticvoid paiallelTestWithPool(int paiallel, int count){ //用该对象保证所线程都完成主线程才退出 CountDownLatch cd = new CountDownLatch(paiallel); long start = System.currentTimeMillis(); Thread[] ts = new Thread[paiallel]; for(int i=0; i < paiallel; i++){ ts[i] = new Thread(new WorkerWithPool(cd, count)); ts[i].start(); } try { cd.await();//等待所有子线程完成 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Pool useTime:"+ (System.currentTimeMillis() - start)); pool.destroy(); } privatestaticvoid testOnce(Jedis jr){ System.out.println(jr.incr("incrTest")); } publicstaticclass WorkerNoPoolimplements Runnable{ private CountDownLatchcd; privateintcount; public WorkerNoPool(CountDownLatch cd,int count){ this.cd = cd; this.count = count; } publicvoid run() { try { testNoPool(this.count); } catch (Exception e) { e.printStackTrace(); } finally{ cd.countDown(); } } } publicstaticclass WorkerWithPoolimplements Runnable{ private CountDownLatchcd; privateintcount; public WorkerWithPool(CountDownLatch cd,int count){ this.cd = cd; this.count = count; } publicvoid run() { try { testWithPool(this.count); } catch (Exception e) { e.printStackTrace(); } finally{ cd.countDown(); } } } publicstaticvoid main(String[] args) { paiallelTestNoPool(100, 1000); //paiallelTestWithPool(100, 1000); } } |
测试输出:
NoPool useTime:43863 //没用对象池的输出 Pool useTime:12101 //用了对象池的输出 |
从测试结果看没用对象池的时间要比用了对象池的时间多出31762毫秒,同时没有用对象池的还出现了很多超时情况,用了对象池的都成功了,运行10000次,我们姑且可以认为平均每次请求可以节约3.1762(31762/10000)毫秒连接时间。我用的是Win7中的Jedis Java客户端程序连接局域网的Linux虚拟机上的Redis Server。
各种客户端实际是对Redis Protocol的封装,方便我们使用,了解Redis Protocol后我们也可以自己实现客户端。