zoukankan      html  css  js  c++  java
  • redis学习及实践3---Jedis、JedisPool、Jedis分布式实例介绍

    一、相关jar包

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

    wKioL1MdK_fybGUhAACpWhNr9Ik847.jpg

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    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文件):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #最大分配的对象数
    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    

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    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中获得:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 从池中获取一个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中:

    1
    2
    3
    4
    5
    6
    7
    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:

    1
    ShardedJedisPool pool = new ShardedJedisPool(config, list);

         改由ShardedJedis,获取Jedis对象:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 从池中获取一个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机器中。

    五、综合实例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    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"13));
    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"03));
    // 修改列表中单个值
    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"01));
    // 列表出栈
    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.510.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();
    }
    }
  • 相关阅读:
    ubuntu 14.04 安装gvim 后报出warning
    ubuntu 如何搭建svn 服务器
    如何为wordpress 添加favicon
    如何为wordpress 的文章添加分页
    ubuntu 如何添加alias
    wordpress 如何防止盗链
    ubuntu 14.04 如何设置静态ip
    钉钉与金蝶ERP对接开发方式
    金蝶组件无法正常工作
    金蝶补丁安装失败
  • 原文地址:https://www.cnblogs.com/yuhoukongshan/p/6344286.html
Copyright © 2011-2022 走看看