redis学习及实践3---Jedis、JedisPool、Jedis分布式实例介绍
? ?主要用到的是jedis的核心包,筆者用到的是2.1.0版;另根據(jù)“池”的應用等還需要用到相關(guān)jar包。下圖是筆者建立的簡單的jedis測試project圖:
? ?jar包的文檔可參考:
http://www.boyunjian.com/javadoc/org.apache.servicemix.bundles/org.apache.servicemix.bundles.jedis/2.1.0_1/_/redis/clients/jedis/JedisShardInfo.html
二、簡單是Jedis實例
? ?在引入相關(guān)jar包后,只要new一個Jedis對象,就能做redis相關(guān)操作了。以下是一個簡單的jedis實例:
package com.pptv.redis; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import redis.clients.jedis.Jedis; public class JedisDemo { public void test(){ Jedis redis = new Jedis ("172.0.0.1",6379);//連接redis redis.auth("redis");//驗證密碼,如果需要驗證的話// STRING 操作//SET key value將字符串值value關(guān)聯(lián)到key。redis.set("name", "wangjun1");redis.set("id", "123456");redis.set("address", "guangzhou");//SETEX key seconds value將值value關(guān)聯(lián)到key,并將key的生存時間設(shè)為seconds(以秒為單位)。redis.setex("foo", 5, "haha");//MSET key value [key value ...]同時設(shè)置一個或多個key-value對。redis.mset("haha","111","xixi","222");//redis.flushAll();清空所有的keySystem.out.println(redis.dbSize());//dbSize是多少個key的個數(shù)//APPEND key value如果key已經(jīng)存在并且是一個字符串,APPEND命令將value追加到key原來的值之后。redis.append("foo", "00");//如果key已經(jīng)存在并且是一個字符串,APPEND命令將value追加到key原來的值之后。//GET key 返回key所關(guān)聯(lián)的字符串值redis.get("foo");//MGET key [key ...] 返回所有(一個或多個)給定key的值List list = redis.mget("haha","xixi");for(int i=0;i<list.size();i++){System.out.println(list.get(i));}}public static void main(String[] args) { JedisDemo t1 = new JedisDemo(); t1.test(); } }
三、JedisPool應用
Jedis 使用 commons-pool 完成池化實現(xiàn)。
? ?先做個配置文件(properties文件):
#最大分配的對象數(shù) redis.pool.maxActive=1024 #最大能夠保持idel狀態(tài)的對象數(shù) redis.pool.maxIdle=200 #當池內(nèi)沒有返回對象時,最大等待時間 redis.pool.maxWait=1000 #當調(diào)用borrow Object方法時,是否進行有效性檢查 redis.pool.testOnBorrow=true #當調(diào)用return Object方法時,是否進行有效性檢查 redis.pool.testOnReturn=true #IP redis.ip=172.0.0.1 #Port redis.port=6379
? ?jedisPool的相關(guān)詳細配置可參考:http://www.2cto.com/database/201311/254449.html ? ?
? ?在靜態(tài)代碼段中完成初始化:
private static JedisPool pool; static {ResourceBundle bundle = ResourceBundle.getBundle("redis");if (bundle == null) {throw new IllegalArgumentException("[redis.properties] is not found!");}JedisPoolConfig config = new JedisPoolConfig();config.setMaxActive(Integer.valueOf(bundle.getString("redis.pool.maxActive")));config.setMaxIdle(Integer.valueOf(bundle.getString("redis.pool.maxIdle")));config.setMaxWait(Long.valueOf(bundle.getString("redis.pool.maxWait")));config.setTestOnBorrow(Boolean.valueOf(bundle.getString("redis.pool.testOnBorrow")));config.setTestOnReturn(Boolean.valueOf(bundle.getString("redis.pool.testOnReturn")));pool = new JedisPool(config, bundle.getString("redis.ip"),Integer.valueOf(bundle.getString("redis.port"))); }
? ?然后修改#2的簡單實例,修改為Jedis從pool中獲得:
// 從池中獲取一個Jedis對象 Jedis jedis = pool.getResource(); String keys = "name"; // 刪數(shù)據(jù) jedis.del(keys); // 存數(shù)據(jù) jedis.set(keys, "snowolf"); // 取數(shù)據(jù) String value = jedis.get(keys); System.out.println(value); // 釋放對象池 pool.returnResource(jedis);
四、Jedis分布式(Sharding/shared一致性哈希)
? ?Memcached 完全基于分布式集群,而 Redis 是 Master-Slave ,如果想把 Reids ,做成集群模式,無外乎多做幾套 Master-Slave ,每套 Master-Slave 完成各自的容災處理,通過 Client 工具,完成一致性哈希。( PS : Memcached 是在 Server 端完成 Sharding , Redis 只能依靠各個 Client 做 Sharding 。 可能會在 Redis 3.0 系列支持 Server 端 Sharding 。 )
? ?shared一致性哈希采用以下方案:
Redis服務器節(jié)點劃分:將每臺服務器節(jié)點采用hash算法劃分為160個虛擬節(jié)點(可以配置劃分權(quán)重)
將劃分虛擬節(jié)點采用TreeMap存儲
對每個Redis服務器的物理連接采用LinkedHashMap存儲
對Key or KeyTag 采用同樣的hash算法,然后從TreeMap獲取大于等于鍵hash值得節(jié)點,取最鄰近節(jié)點存儲;當key的hash值大于虛擬節(jié)點hash值得最大值時,存入第一個虛擬節(jié)點
? ? sharded采用的hash算法:MD5 和 MurmurHash兩種;默認采用64位的MurmurHash算法;有興趣的可以研究下,MurmurHash是一種高效,低碰撞的hash算法;參考地址: ?
? ??http://blog.csdn.net/yfkiss/article/details/7337382
? ??https://sites.google.com/site/murmurhash/ ?
? ?保留前面的 JedisPoolConfig ,新增兩個Redis的IP(redis1.ip,redis2.ip),完成兩個 JedisShardInfo 實例 ,并將其丟進List中:
JedisShardInfo jedisShardInfo1 = new JedisShardInfo(bundle.getString("redis1.ip"), Integer.valueOf(bundle .getString("redis.port"))); JedisShardInfo jedisShardInfo2 = new JedisShardInfo(bundle.getString("redis2.ip"), Integer.valueOf(bundle .getString("redis.port"))); List<JedisShardInfo> list = new LinkedList<JedisShardInfo>(); list.add(jedisShardInfo1); list.add(jedisShardInfo2);
? ?初始化 ShardedJedisPool 代替 JedisPool:
ShardedJedisPool pool = new ShardedJedisPool(config, list);? ? 改由ShardedJedis,獲取Jedis對象:
// 從池中獲取一個Jedis對象 ShardedJedis jedis = pool.getResource(); String keys = "name"; String value = "snowolf"; // 刪數(shù)據(jù) jedis.del(keys); // 存數(shù)據(jù) jedis.set(keys, value); // 取數(shù)據(jù) String v = jedis.get(keys); System.out.println(v); // 釋放對象池 pool.returnResource(jedis);
? ?通過以上方式,向redis進行set操作的key-value,會通過hash而均勻的分配到pool里的redis機器中。
五、綜合實例
package com.pptv.redis; import java.util.ArrayList; import java.util.List; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.JedisShardInfo; import redis.clients.jedis.ShardedJedis; import redis.clients.jedis.ShardedJedisPool; /*** redis的Java客戶端Jedis測試驗證** @author*/ public class Test {/*** 非切片客戶端鏈接*/private Jedis jedis;/*** 非切片鏈接池*/private JedisPool jedisPool;/*** 切片客戶端鏈接*/private ShardedJedis shardedJedis;/*** 切片鏈接池*/private ShardedJedisPool shardedJedisPool;private String ip = "172.16.205.186";/*** 構(gòu)造函數(shù)*/public Test() {initialPool();initialShardedPool();shardedJedis = shardedJedisPool.getResource();jedis = jedisPool.getResource();}private void initialPool() {// 池基本配置JedisPoolConfig config = new JedisPoolConfig();config.setMaxActive(20);config.setMaxIdle(5);config.setMaxWait(1000l);config.setTestOnBorrow(false);jedisPool = new JedisPool(config, ip, 6379);}/*** 初始化切片池*/private void initialShardedPool() {// 池基本配置JedisPoolConfig config = new JedisPoolConfig();config.setMaxActive(20);config.setMaxIdle(5);config.setMaxWait(1000l);config.setTestOnBorrow(false);// slave鏈接List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();shards.add(new JedisShardInfo(ip, 6379, "master"));// 構(gòu)造池shardedJedisPool = new ShardedJedisPool(config, shards);}public void show() {// key檢測testKey();// string檢測testString();// list檢測testList();// set檢測testSet();// sortedSet檢測testSortedSet();// hash檢測testHash();shardedJedisPool.returnResource(shardedJedis);}private void testKey() {System.out.println("=============key==========================");// 清空數(shù)據(jù)System.out.println(jedis.flushDB());System.out.println(jedis.echo("foo"));// 判斷key否存在System.out.println(shardedJedis.exists("foo"));shardedJedis.set("key", "values");System.out.println(shardedJedis.exists("key"));}private void testString() {System.out.println("=============String==========================");// 清空數(shù)據(jù)System.out.println(jedis.flushDB());// 存儲數(shù)據(jù)shardedJedis.set("foo", "bar");System.out.println(shardedJedis.get("foo"));// 若key不存在,則存儲shardedJedis.setnx("foo", "foo not exits");System.out.println(shardedJedis.get("foo"));// 覆蓋數(shù)據(jù)shardedJedis.set("foo", "foo update");System.out.println(shardedJedis.get("foo"));// 追加數(shù)據(jù)shardedJedis.append("foo", " hello, world");System.out.println(shardedJedis.get("foo"));// 設(shè)置key的有效期,并存儲數(shù)據(jù)shardedJedis.setex("foo", 2, "foo not exits");System.out.println(shardedJedis.get("foo"));try {Thread.sleep(3000);} catch (InterruptedException e) {}System.out.println(shardedJedis.get("foo"));// 獲取并更改數(shù)據(jù)shardedJedis.set("foo", "foo update");System.out.println(shardedJedis.getSet("foo", "foo modify"));// 截取value的值System.out.println(shardedJedis.getrange("foo", 1, 3));System.out.println(jedis.mset("mset1", "mvalue1", "mset2", "mvalue2","mset3", "mvalue3", "mset4", "mvalue4"));System.out.println(jedis.mget("mset1", "mset2", "mset3", "mset4"));System.out.println(jedis.del(new String[] { "foo", "foo1", "foo3" }));}private void testList() {System.out.println("=============list==========================");// 清空數(shù)據(jù)System.out.println(jedis.flushDB());// 添加數(shù)據(jù)shardedJedis.lpush("lists", "vector");shardedJedis.lpush("lists", "ArrayList");shardedJedis.lpush("lists", "LinkedList");// 數(shù)組長度System.out.println(shardedJedis.llen("lists"));// 排序 // System.out.println(shardedJedis.sort("lists"));// 字串System.out.println(shardedJedis.lrange("lists", 0, 3));// 修改列表中單個值shardedJedis.lset("lists", 0, "hello list!");// 獲取列表指定下標的值System.out.println(shardedJedis.lindex("lists", 1));// 刪除列表指定下標的值System.out.println(shardedJedis.lrem("lists", 1, "vector"));// 刪除區(qū)間以外的數(shù)據(jù)System.out.println(shardedJedis.ltrim("lists", 0, 1));// 列表出棧System.out.println(shardedJedis.lpop("lists"));// 整個列表值System.out.println(shardedJedis.lrange("lists", 0, -1));}private void testSet() {System.out.println("=============set==========================");// 清空數(shù)據(jù)System.out.println(jedis.flushDB());// 添加數(shù)據(jù)shardedJedis.sadd("sets", "HashSet");shardedJedis.sadd("sets", "SortedSet");shardedJedis.sadd("sets", "TreeSet");// 判斷value是否在列表中System.out.println(shardedJedis.sismember("sets", "TreeSet"));;// 整個列表值System.out.println(shardedJedis.smembers("sets"));// 刪除指定元素System.out.println(shardedJedis.srem("sets", "SortedSet"));// 出棧System.out.println(shardedJedis.spop("sets"));System.out.println(shardedJedis.smembers("sets"));//shardedJedis.sadd("sets1", "HashSet1");shardedJedis.sadd("sets1", "SortedSet1");shardedJedis.sadd("sets1", "TreeSet");shardedJedis.sadd("sets2", "HashSet2");shardedJedis.sadd("sets2", "SortedSet1");shardedJedis.sadd("sets2", "TreeSet1");// 交集System.out.println(jedis.sinter("sets1", "sets2"));// 并集System.out.println(jedis.sunion("sets1", "sets2"));// 差集System.out.println(jedis.sdiff("sets1", "sets2"));}private void testSortedSet() {System.out.println("=============zset==========================");// 清空數(shù)據(jù)System.out.println(jedis.flushDB());// 添加數(shù)據(jù)shardedJedis.zadd("zset", 10.1, "hello");shardedJedis.zadd("zset", 10.0, ":");shardedJedis.zadd("zset", 9.0, "zset");shardedJedis.zadd("zset", 11.0, "zset!");// 元素個數(shù)System.out.println(shardedJedis.zcard("zset"));// 元素下標System.out.println(shardedJedis.zscore("zset", "zset"));// 集合子集System.out.println(shardedJedis.zrange("zset", 0, -1));// 刪除元素System.out.println(shardedJedis.zrem("zset", "zset!"));System.out.println(shardedJedis.zcount("zset", 9.5, 10.5));// 整個集合值System.out.println(shardedJedis.zrange("zset", 0, -1));}private void testHash() {System.out.println("=============hash==========================");// 清空數(shù)據(jù)System.out.println(jedis.flushDB());// 添加數(shù)據(jù)shardedJedis.hset("hashs", "entryKey", "entryValue");shardedJedis.hset("hashs", "entryKey1", "entryValue1");shardedJedis.hset("hashs", "entryKey2", "entryValue2");// 判斷某個值是否存在System.out.println(shardedJedis.hexists("hashs", "entryKey"));// 獲取指定的值System.out.println(shardedJedis.hget("hashs", "entryKey"));// 批量獲取指定的值System.out.println(shardedJedis.hmget("hashs", "entryKey", "entryKey1"));// 刪除指定的值System.out.println(shardedJedis.hdel("hashs", "entryKey"));// 為key中的域 field 的值加上增量 incrementSystem.out.println(shardedJedis.hincrBy("hashs", "entryKey", 123l));// 獲取所有的keysSystem.out.println(shardedJedis.hkeys("hashs"));// 獲取所有的valuesSystem.out.println(shardedJedis.hvals("hashs"));}/*** @param args*/public static void main(String[] args) {new Test().show();} }
總結(jié)
以上是生活随笔為你收集整理的redis学习及实践3---Jedis、JedisPool、Jedis分布式实例介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java实现图片压缩代码,图片大小转换
- 下一篇: 算法入门开灯问题,新做法