03.RedisJava客户端Jedis的使用

时间:2022-05-18 14:52:42
 

1.Jedis基本使用

使用Jedis客户端使用Redis服务与在服务器上通过redis-cli使用命令基本一样,关于Redis命令请参考:http://www.redis.cn/commands.htmlhttp://www.runoob.com/redis/redis-commands.html
1.使用Jedis连接Redis服务
  1. publicstaticvoid main(String[] args)
  2. {
  3. Jedis jedis =newJedis("192.168.110.101",6379);
  4. String result = jedis.ping();// 测试连接
  5. System.out.println(result);
  6. jedis.close();
  7. }
2.Jedis客户端的基本使用
下面根据Redis命令划分,使用Jedis
  1. //关键字(Keys)
  2. System.out.println("exists :"+ jedis.exists("name"));
  3. System.out.println("del :"+ jedis.del("name"));
  4. //字符串(String)
  5. System.out.println("set :"+ jedis.set("name","危常焕"));
  6. System.out.println("get :"+ jedis.get("name"));
  7. //哈希(Hashs)
  8. for(int i =0; i <10; i++)
  9. {
  10. System.out.println("hset :"+ jedis.hset("hset","set-key"+ i,"set-value"+ i));
  11. }
  12. System.out.println("hkeys :"+ jedis.hkeys("hset"));
  13. //列表(Lists)
  14. System.out.println("rpush :"+ jedis.rpush("lset","lset001","lset002","lset003","lset004"));
  15. System.out.println("lrange :"+ jedis.lrange("lset",0,2));
  16. //集合(Sets)
  17. System.out.println("sadd :"+ jedis.sadd("sadd","sadd001","sadd002","sadd003"));
  18. System.out.println("scard :"+ jedis.scard("sadd"));
  19. //有序集合(Sorted Sets)
  20. Map<String,Double> scoreMembers =newHashMap<String,Double>();
  21. scoreMembers.put("001",0.1D);
  22. scoreMembers.put("002",0.2D);
  23. scoreMembers.put("003",0.3D);
  24. System.out.println("zadd :"+ jedis.zadd("zadd", scoreMembers));
  25. System.out.println("zrange :"+ jedis.zrange("zadd",1L,2L));
  26. //HyperLogLog
  27. for(int i =0; i <10; i++)
  28. {
  29. System.out.println("pfadd :"+ jedis.pfadd("HyperLogLog", UUID.randomUUID().toString()));
  30. }
  31. System.out.println("pfcount :"+ jedis.pfcount("HyperLogLog"));
  32. //发布/订阅(Pub/Sub)
  33. Thread thread =newThread(newRunnable()
  34. {
  35. @Override
  36. publicvoid run()
  37. {
  38. finalJedis j =newJedis("192.168.110.101",6379);
  39. j.subscribe(newJedisPubSub()
  40. {
  41. @Override
  42. publicvoid onMessage(String channel,String message)
  43. {
  44. System.out.println("onMessage--channel:"+ channel +" message:"+ message);
  45. this.unsubscribe();
  46. }
  47. },"channel001");
  48. j.close();
  49. System.out.println("连接已关闭");
  50. }
  51. });
  52. thread.start();
  53. Thread.sleep(10);
  54. System.out.println("publish :"+ jedis.publish("channel001","发送一条消息"));
  55. //事务(Transactions)
  56. Transaction transaction = jedis.multi();
  57. System.out.println("set :"+ transaction.set("multi001","123"));
  58. System.out.println("incr :"+ transaction.incr("multi001"));
  59. System.out.println("transaction.exec :"+ transaction.exec());
  60. // 脚本(Scripting)
  61. System.out.println("eval :"+ jedis.eval("local msg = \"Hello, world!\" return msg"));
  62. //连接(Connection)
  63. System.out.println("ping :"+ jedis.ping());
  64. System.out.println("select :"+ jedis.select(0));
  65. //服务(Server)
  66. System.out.println("dbSize :"+ jedis.dbSize());
  67. System.out.println("clientList :"+ jedis.clientList());
Redis支持执行Lua脚本,关于Lua脚本的基本使用可参考:http://www.oschina.net/translate/intro-to-lua-for-redis-programmers

2.Jedis深入使用

1.Jedis中常见类关系如下
03.RedisJava客户端Jedis的使用
2.JedisPool的使用
JedisPool只是提供基本的连接池而已
  1. publicstaticvoid main(String[] args)
  2. {
  3. JedisPoolConfig config =newJedisPoolConfig();
  4. // 连接池中最大连接数。高版本:maxTotal,低版本:maxActive
  5. config.setMaxTotal(8);
  6. // 连接池中最大空闲的连接数
  7. config.setMaxIdle(4);
  8. // 连接池中最少空闲的连接数
  9. config.setMinIdle(1);
  10. // 当连接池资源耗尽时,调用者最大阻塞的时间,超时将跑出异常。单位,毫秒数;默认为-1.表示永不超时。高版本:maxWaitMillis,低版本:maxWait
  11. config.setMaxWaitMillis(15000);
  12. // 连接空闲的最小时间,达到此值后空闲连接将可能会被移除。负值(-1)表示不移除
  13. config.setMinEvictableIdleTimeMillis(300000);
  14. // 对于“空闲链接”检测线程而言,每次检测的链接资源的个数。默认为3
  15. config.setNumTestsPerEvictionRun(3);
  16. // “空闲链接”检测线程,检测的周期,毫秒数。如果为负值,表示不运行“检测线程”。默认为-1
  17. config.setTimeBetweenEvictionRunsMillis(60000);// 一分钟
  18. // 向调用者输出“链接”资源时,是否检测是有有效,如果无效则从连接池中移除,并尝试获取继续获取。默认为false。建议保持默认值
  19. config.setTestOnBorrow(false);
  20. // 向连接池“归还”链接时,是否检测“链接”对象的有效性。默认为false。建议保持默认值
  21. config.setTestOnReturn(false);
  22. // 向调用者输出“链接”对象时,是否检测它的空闲超时;默认为false。如果“链接”空闲超时,将会被移除。建议保持默认值
  23. config.setTestWhileIdle(false);
  24. JedisPool pool =newJedisPool(config,"192.168.110.101",6379);
  25. Jedis jedis = pool.getResource();// 从pool中获取资源
  26. try
  27. {
  28. jedis.set("k1","v1");
  29. System.out.println(jedis.get("k1"));
  30. }
  31. catch(Exception e)
  32. {
  33. e.printStackTrace();
  34. }
  35. finally
  36. {
  37. jedis.close();
  38. // pool.returnResource(jedis); // 此方法已过时
  39. }
  40. for(int i =0; i <10; i++)
  41. {
  42. jedis = pool.getResource();
  43. // jedis.close(); // 去掉注释观察效果
  44. System.out.println("NumActive:"+ pool.getNumActive());
  45. System.out.println("NumIdle:"+ pool.getNumIdle());
  46. System.out.println("NumWaiters:"+ pool.getNumWaiters());
  47. }
  48. pool.close();
  49. pool.destroy();
  50. }
3.JedisSentinelPool使用
JedisSentinelPool在有Sentinel集群服务时使用,他除了提供连接池功能之外还能够在master服务宕机Sentinel集群选出新的master服务节点后连接池连接的Redis服务也会更新成新的master服务地址
  1. publicstaticvoid main(String[] args)
  2. {
  3. String host =null;
  4. int port =0;
  5. Set<String> sentinels =newHashSet<String>();
  6. sentinels.add("192.168.110.100:26379");
  7. sentinels.add("192.168.110.100:36379");
  8. sentinels.add("192.168.110.100:46379");
  9. JedisSentinelPool jedisSentinelPool =newJedisSentinelPool("master001", sentinels);
  10. host = jedisSentinelPool.getCurrentHostMaster().getHost();
  11. port = jedisSentinelPool.getCurrentHostMaster().getPort();
  12. System.out.println(host +":"+ port);
  13. Jedis jedis = jedisSentinelPool.getResource();
  14. jedis.set("001","ASDFG");
  15. System.out.println(jedis.get("001"));
  16. jedis.close();
  17. // 关闭Redis Master服务
  18. Scanner scanner =newScanner(System.in);
  19. String input = scanner.nextLine();
  20. System.out.println(input);
  21. host = jedisSentinelPool.getCurrentHostMaster().getHost();
  22. port = jedisSentinelPool.getCurrentHostMaster().getPort();
  23. System.out.println(host +":"+ port);
  24. jedis = jedisSentinelPool.getResource();
  25. jedis.set("001","ZXCVB");
  26. System.out.println(jedis.get("001"));
  27. jedis.close();
  28. jedisSentinelPool.close();
  29. jedisSentinelPool.destroy();
  30. }
注意:master服务宕机之后一段时间内(若干秒)方法返回的jedis客户端还是以前的master服务地址,会导致连接池在一段时间内(若干秒)不能使用。但是很快就会回复正常连接到新的master服务上,需要注意的是这需要一段时间(若干秒)
运行以上程序输出如下,注意中间打印的部分:
  1. 192.168.110.102:6379
  2. ASDFG
  3. 2015-10-222:50:30 redis.clients.jedis.JedisSentinelPool initPool
  4. 信息:CreatedJedisPool to master at 192.168.110.101:6379
  5. 192.168.110.101:6379
  6. ZXCVB
对于Sentinel的特有操作Jedis类就有方法支持:
03.RedisJava客户端Jedis的使用
4.ShardedJedisPool使用
ShardedJedisPool除了有连接池的功能,它可以根据key计算出这个key对应存储的Redis服务器,实现多台Redis服务器扩容
  1. publicstaticvoid main(String[] args)
  2. {
  3. JedisPoolConfig config =newJedisPoolConfig();
  4. List<JedisShardInfo> shards =newArrayList<JedisShardInfo>();
  5. shards.add(newJedisShardInfo("192.168.110.101","Redis001",6379,20*1000,1));
  6. shards.add(newJedisShardInfo("192.168.110.102","Redis002",6379,20*1000,2));
  7. shards.add(newJedisShardInfo("192.168.110.103","Redis003",6379,20*1000,4));
  8. ShardedJedisPool shardedJedisPool =newShardedJedisPool(config, shards);
  9. for(int i =0; i <10; i++)
  10. {
  11. ShardedJedis shardedJedis = shardedJedisPool.getResource();
  12. String key ="shard"+ i;
  13. shardedJedis.set(key,"v-"+ i);
  14. System.out.println(shardedJedis.get(key));
  15. JedisShardInfo shardInfo = shardedJedis.getShardInfo(key);
  16. System.out.println("getHost:"+ shardInfo.getHost());
  17. shardedJedis.close();
  18. }
  19. shardedJedisPool.close();
  20. shardedJedisPool.destroy();
  21. }
运行打印结果:
  1. v-0
  2. getHost:192.168.110.102
  3. v-1
  4. getHost:192.168.110.101
  5. v-2
  6. getHost:192.168.110.102
  7. v-3
  8. getHost:192.168.110.103
  9. v-4
  10. getHost:192.168.110.102
  11. v-5
  12. getHost:192.168.110.102
  13. v-6
  14. getHost:192.168.110.103
  15. v-7
  16. getHost:192.168.110.102
  17. v-8
  18. getHost:192.168.110.102
  19. v-9
  20. getHost:192.168.110.103
注意:计算key对应到Redis服务器的默认算法与Redis的IP和端口无关,只与JedisShardInfo的name属性有关,所以可以好好使用这个特性!其具体实现如下:
  1. //位置:redis.clients.util.Sharded<R, S extends ShardInfo<R>>
  2. privatevoid initialize(List<S> shards)
  3. {
  4. nodes =newTreeMap<Long, S>();
  5. for(int i =0; i != shards.size();++i)
  6. {
  7. final S shardInfo = shards.get(i);
  8. if(shardInfo.getName()==null)
  9. for(int n =0; n <160* shardInfo.getWeight(); n++)
  10. {
  11. nodes.put(this.algo.hash("SHARD-"+ i +"-NODE-"+ n), shardInfo);
  12. }
  13. else
  14. for(int n =0; n <160* shardInfo.getWeight(); n++)
  15. {
  16. nodes.put(this.algo.hash(shardInfo.getName()+"*"+ shardInfo.getWeight()+ n), shardInfo);
  17. }
  18. resources.put(shardInfo, shardInfo.createResource());
  19. }
  20. }
-------------------------------------------------------------------------------------------------------------------------------