1.Jedis基本使用
使用Jedis客戶端使用Redis服務與在服務器上通過redis-cli
使用命令
基本一樣,關於Redis命令請參考:
http://www.redis.cn/commands.html、
http://www.runoob.com/redis/redis-commands.html
1.使用Jedis連接Redis服務
publicstaticvoid main(String[] args){Jedis jedis =newJedis("192.168.110.101",6379);String result = jedis.ping();// 測試連接System.out.println(result);jedis.close();}
2.Jedis客戶端的基本使用
下面根據Redis命令划分,使用Jedis
//關鍵字(Keys)System.out.println("exists :"+ jedis.exists("name"));System.out.println("del :"+ jedis.del("name"));//字符串(String)System.out.println("set :"+ jedis.set("name","危常煥"));System.out.println("get :"+ jedis.get("name"));//哈希(Hashs)for(int i =0; i <10; i++){System.out.println("hset :"+ jedis.hset("hset","set-key"+ i,"set-value"+ i));}System.out.println("hkeys :"+ jedis.hkeys("hset"));//列表(Lists)System.out.println("rpush :"+ jedis.rpush("lset","lset001","lset002","lset003","lset004"));System.out.println("lrange :"+ jedis.lrange("lset",0,2));//集合(Sets)System.out.println("sadd :"+ jedis.sadd("sadd","sadd001","sadd002","sadd003"));System.out.println("scard :"+ jedis.scard("sadd"));//有序集合(Sorted Sets)Map<String,Double> scoreMembers =newHashMap<String,Double>();scoreMembers.put("001",0.1D);scoreMembers.put("002",0.2D);scoreMembers.put("003",0.3D);System.out.println("zadd :"+ jedis.zadd("zadd", scoreMembers));System.out.println("zrange :"+ jedis.zrange("zadd",1L,2L));//HyperLogLogfor(int i =0; i <10; i++){System.out.println("pfadd :"+ jedis.pfadd("HyperLogLog", UUID.randomUUID().toString()));}System.out.println("pfcount :"+ jedis.pfcount("HyperLogLog"));//發布/訂閱(Pub/Sub)Thread thread =newThread(newRunnable(){@Overridepublicvoid run(){finalJedis j =newJedis("192.168.110.101",6379);j.subscribe(newJedisPubSub(){@Overridepublicvoid onMessage(String channel,String message){System.out.println("onMessage--channel:"+ channel +" message:"+ message);this.unsubscribe();}},"channel001");j.close();System.out.println("連接已關閉");}});thread.start();Thread.sleep(10);System.out.println("publish :"+ jedis.publish("channel001","發送一條消息"));//事務(Transactions)Transaction transaction = jedis.multi();System.out.println("set :"+ transaction.set("multi001","123"));System.out.println("incr :"+ transaction.incr("multi001"));System.out.println("transaction.exec :"+ transaction.exec());// 腳本(Scripting)System.out.println("eval :"+ jedis.eval("local msg = \"Hello, world!\" return msg"));//連接(Connection)System.out.println("ping :"+ jedis.ping());System.out.println("select :"+ jedis.select(0));//服務(Server)System.out.println("dbSize :"+ jedis.dbSize());System.out.println("clientList :"+ jedis.clientList());
Redis支持執行Lua腳本,關於Lua腳本的基本使用可參考:
http://www.oschina.net/translate/intro-to-lua-for-redis-programmers
2.Jedis深入使用
1.Jedis中常見類關系如下
2.JedisPool的使用
JedisPool只是提供基本的連接池而已
publicstaticvoid main(String[] args){JedisPoolConfig config =newJedisPoolConfig();// 連接池中最大連接數。高版本:maxTotal,低版本:maxActiveconfig.setMaxTotal(8);// 連接池中最大空閑的連接數config.setMaxIdle(4);// 連接池中最少空閑的連接數config.setMinIdle(1);// 當連接池資源耗盡時,調用者最大阻塞的時間,超時將跑出異常。單位,毫秒數;默認為-1.表示永不超時。高版本:maxWaitMillis,低版本:maxWaitconfig.setMaxWaitMillis(15000);// 連接空閑的最小時間,達到此值后空閑連接將可能會被移除。負值(-1)表示不移除config.setMinEvictableIdleTimeMillis(300000);// 對於“空閑鏈接”檢測線程而言,每次檢測的鏈接資源的個數。默認為3config.setNumTestsPerEvictionRun(3);// “空閑鏈接”檢測線程,檢測的周期,毫秒數。如果為負值,表示不運行“檢測線程”。默認為-1config.setTimeBetweenEvictionRunsMillis(60000);// 一分鍾// 向調用者輸出“鏈接”資源時,是否檢測是有有效,如果無效則從連接池中移除,並嘗試獲取繼續獲取。默認為false。建議保持默認值config.setTestOnBorrow(false);// 向連接池“歸還”鏈接時,是否檢測“鏈接”對象的有效性。默認為false。建議保持默認值config.setTestOnReturn(false);// 向調用者輸出“鏈接”對象時,是否檢測它的空閑超時;默認為false。如果“鏈接”空閑超時,將會被移除。建議保持默認值config.setTestWhileIdle(false);JedisPool pool =newJedisPool(config,"192.168.110.101",6379);Jedis jedis = pool.getResource();// 從pool中獲取資源try{jedis.set("k1","v1");System.out.println(jedis.get("k1"));}catch(Exception e){e.printStackTrace();}finally{jedis.close();// pool.returnResource(jedis); // 此方法已過時}for(int i =0; i <10; i++){jedis = pool.getResource();// jedis.close(); // 去掉注釋觀察效果System.out.println("NumActive:"+ pool.getNumActive());System.out.println("NumIdle:"+ pool.getNumIdle());System.out.println("NumWaiters:"+ pool.getNumWaiters());}pool.close();pool.destroy();}
3.JedisSentinelPool使用
JedisSentinelPool在有Sentinel集群服務時使用,他除了提供連接池功能之外還能夠在master服務宕機
Sentinel
集群選出新的
master
服務節點后連接池連接的Redis服務也會更新成新的
master
服務地址
publicstaticvoid main(String[] args){String host =null;int port =0;Set<String> sentinels =newHashSet<String>();sentinels.add("192.168.110.100:26379");sentinels.add("192.168.110.100:36379");sentinels.add("192.168.110.100:46379");JedisSentinelPool jedisSentinelPool =newJedisSentinelPool("master001", sentinels);host = jedisSentinelPool.getCurrentHostMaster().getHost();port = jedisSentinelPool.getCurrentHostMaster().getPort();System.out.println(host +":"+ port);Jedis jedis = jedisSentinelPool.getResource();jedis.set("001","ASDFG");System.out.println(jedis.get("001"));jedis.close();// 關閉Redis Master服務Scanner scanner =newScanner(System.in);String input = scanner.nextLine();System.out.println(input);host = jedisSentinelPool.getCurrentHostMaster().getHost();port = jedisSentinelPool.getCurrentHostMaster().getPort();System.out.println(host +":"+ port);jedis = jedisSentinelPool.getResource();jedis.set("001","ZXCVB");System.out.println(jedis.get("001"));jedis.close();jedisSentinelPool.close();jedisSentinelPool.destroy();}
注意:
master服務宕機之后一段時間內(若干秒)方法返回的jedis客戶端還是以前的master服務地址,會導致連接池在一段時間內(若干秒)不能使用。但是很快就會回復正常連接到新的master服務上,需要注意的是這需要一段時間(若干秒)
運行以上程序輸出如下,注意中間打印的部分:
192.168.110.102:6379ASDFG2015-10-222:50:30 redis.clients.jedis.JedisSentinelPool initPool信息:CreatedJedisPool to master at 192.168.110.101:6379192.168.110.101:6379ZXCVB
對於
Sentinel的特有操作Jedis類
就有方法支持:

4.ShardedJedisPool使用
ShardedJedisPool除了有連接池的功能,它可以根據key計算出這個key對應存儲的Redis服務器,實現多台Redis服務器擴容
publicstaticvoid main(String[] args){JedisPoolConfig config =newJedisPoolConfig();List<JedisShardInfo> shards =newArrayList<JedisShardInfo>();shards.add(newJedisShardInfo("192.168.110.101","Redis001",6379,20*1000,1));shards.add(newJedisShardInfo("192.168.110.102","Redis002",6379,20*1000,2));shards.add(newJedisShardInfo("192.168.110.103","Redis003",6379,20*1000,4));ShardedJedisPool shardedJedisPool =newShardedJedisPool(config, shards);for(int i =0; i <10; i++){ShardedJedis shardedJedis = shardedJedisPool.getResource();String key ="shard"+ i;shardedJedis.set(key,"v-"+ i);System.out.println(shardedJedis.get(key));JedisShardInfo shardInfo = shardedJedis.getShardInfo(key);System.out.println("getHost:"+ shardInfo.getHost());shardedJedis.close();}shardedJedisPool.close();shardedJedisPool.destroy();}
運行打印結果:
v-0getHost:192.168.110.102v-1getHost:192.168.110.101v-2getHost:192.168.110.102v-3getHost:192.168.110.103v-4getHost:192.168.110.102v-5getHost:192.168.110.102v-6getHost:192.168.110.103v-7getHost:192.168.110.102v-8getHost:192.168.110.102v-9getHost:192.168.110.103
注意:計算key對應到Redis服務器的默認算法與Redis的IP和端口無關,只與
JedisShardInfo
的name屬性有關,所以可以好好使用這個特性!其具體實現如下:
//位置:redis.clients.util.Sharded<R, S extends ShardInfo<R>>privatevoid initialize(List<S> shards){nodes =newTreeMap<Long, S>();for(int i =0; i != shards.size();++i){final S shardInfo = shards.get(i);if(shardInfo.getName()==null)for(int n =0; n <160* shardInfo.getWeight(); n++){nodes.put(this.algo.hash("SHARD-"+ i +"-NODE-"+ n), shardInfo);}elsefor(int n =0; n <160* shardInfo.getWeight(); n++){nodes.put(this.algo.hash(shardInfo.getName()+"*"+ shardInfo.getWeight()+ n), shardInfo);}resources.put(shardInfo, shardInfo.createResource());}}
-------------------------------------------------------------------------------------------------------------------------------
