首页 > 其他 > 详细

redis学习及实践3---Jedis、JedisPool、Jedis分布式实例介绍

时间:2014-03-10 18:15:00      阅读:447      评论:0      收藏:0      [点我收藏+]

一、相关jar包

   主要用到的是jedis的核心包,笔者用到的是2.1.0版;另根据“池”的应用等还需要用到相关jar包。下图是笔者建立的简单的jedis测试project图:

bubuko.com,布布扣

   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实例

   在引入相关jar包后,只要new一个Jedis对象,就能做redis相关操作了。以下是一个简单的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关联到key。
       redis.set("name", "wangjun1");
       redis.set("id", "123456");
       redis.set("address", "guangzhou");
                                                                                                                                                                                                                             
       //SETEX key seconds value将值value关联到key,并将key的生存时间设为seconds(以秒为单位)。
       redis.setex("foo", 5, "haha");
                                                                                                                                                                                                                             
       //MSET key value [key value ...]同时设置一个或多个key-value对。
       redis.mset("haha","111","xixi","222");
                                                                                                                                                                                                                              
       //redis.flushAll();清空所有的key
       System.out.println(redis.dbSize());//dbSize是多少个key的个数
                                                                                                                                                                                                                             
       //APPEND key value如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值之后。
       redis.append("foo", "00");//如果key已经存在并且是一个字符串,APPEND命令将value追加到key原来的值之后。
                                                                                                                                                                                                                             
       //GET key 返回key所关联的字符串值
       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完成池化实现。

   先做个配置文件(properties文件):

#最大分配的对象数
redis.pool.maxActive=1024
#最大能够保持idel状态的对象数
redis.pool.maxIdle=200
#当池内没有返回对象时,最大等待时间
redis.pool.maxWait=1000
#当调用borrow Object方法时,是否进行有效性检查
redis.pool.testOnBorrow=true
#当调用return Object方法时,是否进行有效性检查
redis.pool.testOnReturn=true
#IP
redis.ip=172.0.0.1
#Port
redis.port=6379

   jedisPool的相关详细配置可参考:http://www.2cto.com/database/201311/254449.html    

   在静态代码段中完成初始化:

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";
// 删数据
jedis.del(keys);
// 存数据
jedis.set(keys, "snowolf");
// 取数据
String value = jedis.get(keys);
System.out.println(value);
// 释放对象池
pool.returnResource(jedis);

四、Jedis分布式(Sharding/shared一致性哈希)

   Memcached完全基于分布式集群,而RedisMaster-Slave,如果想把Reids,做成集群模式,无外乎多做几套Master-Slave,每套Master-Slave完成各自的容灾处理,通过Client工具,完成一致性哈希。(PS:Memcached是在Server端完成ShardingRedis只能依靠各个ClientSharding可能会在Redis 3.0系列支持ServerSharding

   shared一致性哈希采用以下方案:

  1. Redis服务器节点划分:将每台服务器节点采用hash算法划分为160个虚拟节点(可以配置划分权重)

  2. 将划分虚拟节点采用TreeMap存储

  3. 对每个Redis服务器的物理连接采用LinkedHashMap存储

  4. 对Key or KeyTag 采用同样的hash算法,然后从TreeMap获取大于等于键hash值得节点,取最邻近节点存储;当key的hash值大于虚拟节点hash值得最大值时,存入第一个虚拟节点

sharded采用的hash算法:MD5 和 MurmurHash两种;默认采用64位的MurmurHash算法;有兴趣的可以研究下,MurmurHash是一种高效,低碰撞的hash算法;参考地址:  

   保留前面的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";
// 删数据
jedis.del(keys);
// 存数据
jedis.set(keys, value);
// 取数据
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";
    /**
     * 构造函数
     */
    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"));
        // 构造池
        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==========================");
        // 清空数据
        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==========================");
        // 清空数据
        System.out.println(jedis.flushDB());
        // 存储数据
        shardedJedis.set("foo", "bar");
        System.out.println(shardedJedis.get("foo"));
        // 若key不存在,则存储
        shardedJedis.setnx("foo", "foo not exits");
        System.out.println(shardedJedis.get("foo"));
        // 覆盖数据
        shardedJedis.set("foo", "foo update");
        System.out.println(shardedJedis.get("foo"));
        // 追加数据
        shardedJedis.append("foo", " hello, world");
        System.out.println(shardedJedis.get("foo"));
        // 设置key的有效期,并存储数据
        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"));
        // 获取并更改数据
        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==========================");
        // 清空数据
        System.out.println(jedis.flushDB());
        // 添加数据
        shardedJedis.lpush("lists", "vector");
        shardedJedis.lpush("lists", "ArrayList");
        shardedJedis.lpush("lists", "LinkedList");
        // 数组长度
        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"));
        // 删除区间以外的数据
        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==========================");
        // 清空数据
        System.out.println(jedis.flushDB());
        // 添加数据
        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==========================");
        // 清空数据
        System.out.println(jedis.flushDB());
        // 添加数据
        shardedJedis.zadd("zset", 10.1, "hello");
        shardedJedis.zadd("zset", 10.0, ":");
        shardedJedis.zadd("zset", 9.0, "zset");
        shardedJedis.zadd("zset", 11.0, "zset!");
        // 元素个数
        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==========================");
        // 清空数据
        System.out.println(jedis.flushDB());
        // 添加数据
        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 的值加上增量 increment
        System.out.println(shardedJedis.hincrBy("hashs", "entryKey", 123l));
        // 获取所有的keys
        System.out.println(shardedJedis.hkeys("hashs"));
        // 获取所有的values
        System.out.println(shardedJedis.hvals("hashs"));
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        new Test().show();
    }
}


redis学习及实践3---Jedis、JedisPool、Jedis分布式实例介绍,布布扣,bubuko.com

redis学习及实践3---Jedis、JedisPool、Jedis分布式实例介绍

原文:http://flyingsnail.blog.51cto.com/5341669/1371650

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!