<导航

Jedis使用

一、概述

Jedis是Redis官方推荐的Java连接开发工具。下面总结下使用相关API。比较粗糙,主要是copy总结网上的一些资料,有时间再重新整理好了。

参考API文档:http://tool.oschina.net/uploads/apidocs/redis/clients/jedis/Jedis.html

二、基本使用

Jedis的基本使用非常简单,只需要创建Jedis对象的时候指定host,port, password即可。当然,Jedis对象又很多构造方法,都大同小异,只是对应和Redis连接的socket的参数不一样而已。简单使用如下图所示

1、jedis.ping()

编译以下 Java 程序,确保驱动包的路径是正确的。

import redis.clients.jedis.Jedis;
 
public class RedisJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost");
        System.out.println("连接成功");
        //查看服务是否运行
        System.out.println("服务正在运行: "+jedis.ping());
    }
}
连接成功
服务正在运行: PONG

2、Redis Java String(字符串) 实例

import redis.clients.jedis.Jedis;
 
public class RedisStringJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost");
        System.out.println("连接成功");
        //设置 redis 字符串数据
        jedis.set("runoobkey", "www.runoob.com");
        // 获取存储的数据并输出
        System.out.println("redis 存储的字符串为: "+ jedis.get("runoobkey"));
    }
}
连接成功
redis 存储的字符串为: www.runoob.com

3、Redis Java List(列表) 实例

import java.util.List;
import redis.clients.jedis.Jedis;
 
public class RedisListJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost");
        System.out.println("连接成功");
        //存储数据到列表中
        jedis.lpush("site-list", "Runoob");
        jedis.lpush("site-list", "Google");
        jedis.lpush("site-list", "Taobao");
        // 获取存储的数据并输出
        List<String> list = jedis.lrange("site-list", 0 ,2);
        for(int i=0; i<list.size(); i++) {
            System.out.println("列表项为: "+list.get(i));
        }
    }
}
连接成功
列表项为: Taobao
列表项为: Google
列表项为: Runoob

4、Redis Java Keys 实例

import java.util.Iterator;
import java.util.Set;
import redis.clients.jedis.Jedis;
 
public class RedisKeyJava {
    public static void main(String[] args) {
        //连接本地的 Redis 服务
        Jedis jedis = new Jedis("localhost");
        System.out.println("连接成功");
 
        // 获取数据并输出
        Set<String> keys = jedis.keys("*"); 
        Iterator<String> it=keys.iterator() ;   
        while(it.hasNext()){   
            String key = it.next();   
            System.out.println(key);   
        }
    }
}
连接成功
runoobkey
site-list 

注意:jedis的默认读取时间是2s,由于用的是jedis对象连接因此当多个线程操作redis的时候,redis服务器采用的机制是FIFO(先入先出)机制,因此会使得线程等待时间增长,会造成redis读取超时。

三、附上两个工具类

  注意:使用Jedis连接池之后,尽量在用完连接对象后记得把连接归还给连接池。只需要使用Jedis的close方法就可以了。

  1 package com.aicai.qa.tools.statics.redis;
  2 
  3 import com.aicai.qa.tools.statics.config.SysConfigUtil;
  4 import redis.clients.jedis.BinaryClient;
  5 import redis.clients.jedis.Jedis;
  6 import redis.clients.jedis.JedisPool;
  7 import redis.clients.jedis.JedisPoolConfig;
  8 
  9 import java.util.List;
 10 import java.util.Map;
 11 import java.util.Set;
 12 
 13 /**
 14  * @author tengfei
 15  * @version 1.0
 16  * @date 2018/7/13 下午4:15
 17  */
 18 public class RedisUtil {
 19     private JedisPool pool = null;
 20 
 21     private RedisUtil() {
 22         if (pool == null) {
 23             String ip = SysConfigUtil.getSysConfigUtil("redis.properties").getString("redis.host");
 24             int port = SysConfigUtil.getSysConfigUtil("redis.properties").getInt("redis.port");
 25             String password = SysConfigUtil.getSysConfigUtil("redis.properties").getString("redis.password");
 26             JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
 27             jedisPoolConfig.setMaxTotal(SysConfigUtil.getSysConfigUtil("redis.properties").getInt("redis.maxTotal"));
 28             jedisPoolConfig.setMaxIdle(SysConfigUtil.getSysConfigUtil("redis.properties").getInt("redis.maxIdle"));
 29             jedisPoolConfig.setMaxWaitMillis(SysConfigUtil.getSysConfigUtil("redis.properties").getLong("redis.maxWaitMillis"));
 30             jedisPoolConfig.setTestOnBorrow(SysConfigUtil.getSysConfigUtil("redis.properties").getBoolean("redis.testOnBorrow"));
 31             if (password != null && !"".equals(password)) {
 32                 // redis 设置了密码
 33                 pool = new JedisPool(jedisPoolConfig, ip, port, 10000, password);
 34             } else {
 35                 // redis 未设置密码
 36                 pool = new JedisPool(jedisPoolConfig, ip, port, 10000);
 37             }
 38         }
 39     }
 40 
 41     /**
 42      * 获取指定key的值,如果key不存在返回null,如果该Key存储的不是字符串,会抛出一个错误
 43      *
 44      * @param key
 45      * @return
 46      */
 47     public String get(String key) {
 48         Jedis jedis = getJedis();
 49         String value = null;
 50         value = jedis.get(key);
 51         return value;
 52     }
 53 
 54     /**
 55      * 设置key的值为value
 56      *
 57      * @param key
 58      * @param value
 59      * @return
 60      */
 61     public String set(String key, String value) {
 62         Jedis jedis = getJedis();
 63         return jedis.set(key, value);
 64     }
 65 
 66     /**
 67      * 删除指定的key,也可以传入一个包含key的数组
 68      *
 69      * @param keys
 70      * @return
 71      */
 72     public Long del(String... keys) {
 73         Jedis jedis = getJedis();
 74         return jedis.del(keys);
 75     }
 76 
 77     /**
 78      * 通过key向指定的value值追加值
 79      *
 80      * @param key
 81      * @param str
 82      * @return
 83      */
 84     public Long append(String key, String str) {
 85         Jedis jedis = getJedis();
 86         return jedis.append(key, str);
 87     }
 88 
 89     /**
 90      * 判断key是否存在
 91      *
 92      * @param key
 93      * @return
 94      */
 95     public Boolean exists(String key) {
 96         Jedis jedis = getJedis();
 97         return jedis.exists(key);
 98     }
 99 
100     /**
101      * 设置key value,如果key已经存在则返回0
102      *
103      * @param key
104      * @param value
105      * @return
106      */
107     public Long setnx(String key, String value) {
108         Jedis jedis = getJedis();
109         return jedis.setnx(key, value);
110     }
111 
112     /**
113      * 设置key value并指定这个键值的有效期
114      *
115      * @param key
116      * @param seconds
117      * @param value
118      * @return
119      */
120     public String setex(String key, int seconds, String value) {
121         Jedis jedis = getJedis();
122         return jedis.setex(key, seconds, value);
123     }
124 
125     /**
126      * 通过key 和offset 从指定的位置开始将原先value替换
127      *
128      * @param key
129      * @param offset
130      * @param str
131      * @return
132      */
133     public Long setrange(String key, int offset, String str) {
134         Jedis jedis = getJedis();
135         return jedis.setrange(key, offset, str);
136     }
137 
138     /**
139      * 通过批量的key获取批量的value
140      *
141      * @param keys
142      * @return
143      */
144     public List<String> mget(String... keys) {
145         Jedis jedis = getJedis();
146         return jedis.mget(keys);
147     }
148 
149     /**
150      * 批量的设置key:value,也可以一个
151      *
152      * @param keysValues
153      * @return
154      */
155     public String mset(String... keysValues) {
156         Jedis jedis = getJedis();
157         return jedis.mset(keysValues);
158     }
159 
160     /**
161      * 批量的设置key:value,可以一个,如果key已经存在则会失败,操作会回滚
162      *
163      * @param keysValues
164      * @return
165      */
166     public Long msetnx(String... keysValues) {
167         Jedis jedis = getJedis();
168         return jedis.msetnx(keysValues);
169     }
170 
171     /**
172      * 设置key的值,并返回一个旧值
173      *
174      * @param key
175      * @param value
176      * @return
177      */
178     public String getSet(String key, String value) {
179         Jedis jedis = getJedis();
180         return jedis.getSet(key, value);
181     }
182 
183     /**
184      * 通过下标 和key 获取指定下标位置的 value
185      *
186      * @param key
187      * @param startOffset
188      * @param endOffset
189      * @return
190      */
191     public String getrange(String key, int startOffset, int endOffset) {
192         Jedis jedis = getJedis();
193         return jedis.getrange(key, startOffset, endOffset);
194     }
195 
196     /**
197      * 通过key 对value进行加值+1操作,当value不是int类型时会返回错误,当key不存在是则value为1
198      *
199      * @param key
200      * @return
201      */
202     public Long incr(String key) {
203         Jedis jedis = getJedis();
204         return jedis.incr(key);
205     }
206 
207     /**
208      * 通过key给指定的value加值,如果key不存在,则这是value为该值
209      *
210      * @param key
211      * @param integer
212      * @return
213      */
214     public Long incrBy(String key, long integer) {
215         Jedis jedis = getJedis();
216         return jedis.incrBy(key, integer);
217     }
218 
219     /**
220      * 对key的值做减减操作,如果key不存在,则设置key为-1
221      *
222      * @param key
223      * @return
224      */
225     public Long decr(String key) {
226         Jedis jedis = getJedis();
227         return jedis.decr(key);
228     }
229 
230     /**
231      * 减去指定的值
232      *
233      * @param key
234      * @param integer
235      * @return
236      */
237     public Long decrBy(String key, long integer) {
238         Jedis jedis = getJedis();
239         return jedis.decrBy(key, integer);
240     }
241 
242     /**
243      * 通过key获取value值的长度
244      *
245      * @param key
246      * @return
247      */
248     public Long strLen(String key) {
249         Jedis jedis = getJedis();
250         return jedis.strlen(key);
251     }
252 
253     /**
254      * 通过key给field设置指定的值,如果key不存在则先创建,如果field已经存在,返回0
255      *
256      * @param key
257      * @param field
258      * @param value
259      * @return
260      */
261     public Long hsetnx(String key, String field, String value) {
262         Jedis jedis = getJedis();
263         return jedis.hsetnx(key, field, value);
264     }
265 
266     /**
267      * 通过key给field设置指定的值,如果key不存在,则先创建
268      *
269      * @param key
270      * @param field
271      * @param value
272      * @return
273      */
274     public Long hset(String key, String field, String value) {
275         Jedis jedis = getJedis();
276         return jedis.hset(key, field, value);
277     }
278 
279     /**
280      * 通过key同时设置 hash的多个field
281      *
282      * @param key
283      * @param hash
284      * @return
285      */
286     public String hmset(String key, Map<String, String> hash) {
287         Jedis jedis = getJedis();
288         return jedis.hmset(key, hash);
289     }
290 
291     /**
292      * 通过key 和 field 获取指定的 value
293      *
294      * @param key
295      * @param failed
296      * @return
297      */
298     public String hget(String key, String failed) {
299         Jedis jedis = getJedis();
300         return jedis.hget(key, failed);
301     }
302 
303     /**
304      * 设置key的超时时间为seconds
305      *
306      * @param key
307      * @param seconds
308      * @return
309      */
310     public Long expire(String key, int seconds) {
311         Jedis jedis = getJedis();
312         return jedis.expire(key, seconds);
313     }
314 
315     /**
316      * 通过key 和 fields 获取指定的value 如果没有对应的value则返回null
317      *
318      * @param key
319      * @param fields 可以是 一个String 也可以是 String数组
320      * @return
321      */
322     public List<String> hmget(String key, String... fields) {
323         Jedis jedis = getJedis();
324         return jedis.hmget(key, fields);
325     }
326 
327     /**
328      * 通过key给指定的field的value加上给定的值
329      *
330      * @param key
331      * @param field
332      * @param value
333      * @return
334      */
335     public Long hincrby(String key, String field, Long value) {
336         Jedis jedis = getJedis();
337         return jedis.hincrBy(key, field, value);
338     }
339 
340     /**
341      * 通过key和field判断是否有指定的value存在
342      *
343      * @param key
344      * @param field
345      * @return
346      */
347     public Boolean hexists(String key, String field) {
348         Jedis jedis = getJedis();
349         return jedis.hexists(key, field);
350     }
351 
352     /**
353      * 通过key返回field的数量
354      *
355      * @param key
356      * @return
357      */
358     public Long hlen(String key) {
359         Jedis jedis = getJedis();
360         return jedis.hlen(key);
361     }
362 
363     /**
364      * 通过key 删除指定的 field
365      *
366      * @param key
367      * @param fields 可以是 一个 field 也可以是 一个数组
368      * @return
369      */
370     public Long hdel(String key, String... fields) {
371         Jedis jedis = getJedis();
372         return jedis.hdel(key, fields);
373     }
374 
375     /**
376      * 通过key返回所有的field
377      *
378      * @param key
379      * @return
380      */
381     public Set<String> hkeys(String key) {
382         Jedis jedis = getJedis();
383         return jedis.hkeys(key);
384     }
385 
386     /**
387      * 通过key返回所有和key有关的value
388      *
389      * @param key
390      * @return
391      */
392     public List<String> hvals(String key) {
393         Jedis jedis = getJedis();
394         return jedis.hvals(key);
395     }
396 
397     /**
398      * 通过key获取所有的field和value
399      *
400      * @param key
401      * @return
402      */
403     public Map<String, String> hgetall(String key) {
404         Jedis jedis = getJedis();
405         return jedis.hgetAll(key);
406     }
407 
408     /**
409      * 通过key向list头部添加字符串
410      *
411      * @param key
412      * @param strs 可以是一个string 也可以是string数组
413      * @return 返回list的value个数
414      */
415     public Long lpush(String key, String... strs) {
416         Jedis jedis = getJedis();
417         return jedis.lpush(key, strs);
418     }
419 
420     /**
421      * 通过key向list尾部添加字符串
422      *
423      * @param key
424      * @param strs 可以是一个string 也可以是string数组
425      * @return 返回list的value个数
426      */
427     public Long rpush(String key, String... strs) {
428         Jedis jedis = getJedis();
429         return jedis.rpush(key, strs);
430     }
431 
432     /**
433      * 通过key在list指定的位置之前或者之后 添加字符串元素
434      *
435      * @param key
436      * @param where LIST_POSITION枚举类型
437      * @param pivot list里面的value
438      * @param value 添加的value
439      * @return
440      */
441     public Long linsert(String key, BinaryClient.LIST_POSITION where,
442                         String pivot, String value) {
443         Jedis jedis = getJedis();
444         return jedis.linsert(key, where, pivot, value);
445     }
446 
447     /**
448      * 通过key设置list指定下标位置的value
449      * 如果下标超过list里面value的个数则报错
450      *
451      * @param key
452      * @param index 从0开始
453      * @param value
454      * @return 成功返回OK
455      */
456     public String lset(String key, Long index, String value) {
457         Jedis jedis = getJedis();
458         return jedis.lset(key, index, value);
459     }
460 
461     /**
462      * 通过key从对应的list中删除指定的count个 和 value相同的元素
463      *
464      * @param key
465      * @param count 当count为0时删除全部
466      * @param value
467      * @return 返回被删除的个数
468      */
469     public Long lrem(String key, long count, String value) {
470         Jedis jedis = getJedis();
471         return jedis.lrem(key, count, value);
472     }
473 
474     /**
475      * 通过key保留list中从strat下标开始到end下标结束的value值
476      *
477      * @param key
478      * @param start
479      * @param end
480      * @return 成功返回OK
481      */
482     public String ltrim(String key, long start, long end) {
483         Jedis jedis = getJedis();
484         return jedis.ltrim(key, start, end);
485     }
486 
487     /**
488      * 通过key从list的头部删除一个value,并返回该value
489      *
490      * @param key
491      * @return
492      */
493     public synchronized String lpop(String key) {
494 
495         Jedis jedis = getJedis();
496         return jedis.lpop(key);
497     }
498 
499     /**
500      * 通过key从list尾部删除一个value,并返回该元素
501      *
502      * @param key
503      * @return
504      */
505     synchronized public String rpop(String key) {
506         Jedis jedis = getJedis();
507         return jedis.rpop(key);
508     }
509 
510     /**
511      * 通过key从一个list的尾部删除一个value并添加到另一个list的头部,并返回该value
512      * 如果第一个list为空或者不存在则返回null
513      *
514      * @param srckey
515      * @param dstkey
516      * @return
517      */
518     public String rpoplpush(String srckey, String dstkey) {
519         Jedis jedis = getJedis();
520         return jedis.rpoplpush(srckey, dstkey);
521     }
522 
523     /**
524      * 通过key获取list中指定下标位置的value
525      *
526      * @param key
527      * @param index
528      * @return 如果没有返回null
529      */
530     public String lindex(String key, long index) {
531         Jedis jedis = getJedis();
532         return jedis.lindex(key, index);
533     }
534 
535     /**
536      * 通过key返回list的长度
537      *
538      * @param key
539      * @return
540      */
541     public Long llen(String key) {
542         Jedis jedis = getJedis();
543         return jedis.llen(key);
544     }
545 
546     /**
547      * 通过key获取list指定下标位置的value
548      * 如果start 为 0 end 为 -1 则返回全部的list中的value
549      *
550      * @param key
551      * @param start
552      * @param end
553      * @return
554      */
555     public List<String> lrange(String key, long start, long end) {
556         Jedis jedis = getJedis();
557         return jedis.lrange(key, start, end);
558     }
559 
560     /**
561      * 通过key向指定的set中添加value
562      *
563      * @param key
564      * @param members 可以是一个String 也可以是一个String数组
565      * @return 添加成功的个数
566      */
567     public Long sadd(String key, String... members) {
568         Jedis jedis = getJedis();
569         return jedis.sadd(key, members);
570     }
571 
572     /**
573      * 通过key删除set中对应的value值
574      *
575      * @param key
576      * @param members 可以是一个String 也可以是一个String数组
577      * @return 删除的个数
578      */
579     public Long srem(String key, String... members) {
580         Jedis jedis = getJedis();
581         return jedis.srem(key, members);
582     }
583 
584     /**
585      * 通过key随机删除一个set中的value并返回该值
586      *
587      * @param key
588      * @return
589      */
590     public String spop(String key) {
591         Jedis jedis = getJedis();
592         return jedis.spop(key);
593     }
594 
595     /**
596      * 通过key获取set中的差集
597      * 以第一个set为标准
598      *
599      * @param keys 可以 是一个string 则返回set中所有的value 也可以是string数组
600      * @return
601      */
602     public Set<String> sdiff(String... keys) {
603         Jedis jedis = getJedis();
604         return jedis.sdiff(keys);
605     }
606 
607     /**
608      * 通过key获取set中的差集并存入到另一个key中
609      * 以第一个set为标准
610      *
611      * @param dstkey 差集存入的key
612      * @param keys   可以 是一个string 则返回set中所有的value 也可以是string数组
613      * @return
614      */
615     public Long sdiffstore(String dstkey, String... keys) {
616         Jedis jedis = getJedis();
617         return jedis.sdiffstore(dstkey, keys);
618     }
619 
620     /**
621      * 通过key获取指定set中的交集
622      *
623      * @param keys 可以 是一个string 也可以是一个string数组
624      * @return
625      */
626     public Set<String> sinter(String... keys) {
627         Jedis jedis = getJedis();
628         return jedis.sinter(keys);
629     }
630 
631     /**
632      * 通过key获取指定set中的交集 并将结果存入新的set中
633      *
634      * @param dstkey
635      * @param keys   可以 是一个string 也可以是一个string数组
636      * @return
637      */
638     public Long sinterstore(String dstkey, String... keys) {
639         Jedis jedis = getJedis();
640         return jedis.sinterstore(dstkey, keys);
641     }
642 
643     /**
644      * 通过key返回所有set的并集
645      *
646      * @param keys 可以 是一个string 也可以是一个string数组
647      * @return
648      */
649     public Set<String> sunion(String... keys) {
650         Jedis jedis = getJedis();
651         return jedis.sunion(keys);
652     }
653 
654     /**
655      * 通过key返回所有set的并集,并存入到新的set中
656      *
657      * @param dstkey
658      * @param keys   可以 是一个string 也可以是一个string数组
659      * @return
660      */
661     public Long sunionstore(String dstkey, String... keys) {
662         Jedis jedis = getJedis();
663         return jedis.sunionstore(dstkey, keys);
664     }
665 
666     /**
667      * 通过key将set中的value移除并添加到第二个set中
668      *
669      * @param srckey 需要移除的
670      * @param dstkey 添加的
671      * @param member set中的value
672      * @return
673      */
674     public Long smove(String srckey, String dstkey, String member) {
675         Jedis jedis = getJedis();
676         return jedis.smove(srckey, dstkey, member);
677     }
678 
679     /**
680      * 通过key获取set中value的个数
681      *
682      * @param key
683      * @return
684      */
685     public Long scard(String key) {
686         Jedis jedis = getJedis();
687         return jedis.scard(key);
688     }
689 
690     /**
691      * 通过key判断value是否是set中的元素
692      *
693      * @param key
694      * @param member
695      * @return
696      */
697     public Boolean sismember(String key, String member) {
698         Jedis jedis = getJedis();
699         return jedis.sismember(key, member);
700     }
701 
702     /**
703      * 通过key获取set中随机的value,不删除元素
704      *
705      * @param key
706      * @return
707      */
708     public String srandmember(String key) {
709         Jedis jedis = getJedis();
710         return jedis.srandmember(key);
711     }
712 
713     /**
714      * 通过key获取set中所有的value
715      *
716      * @param key
717      * @return
718      */
719     public Set<String> smembers(String key) {
720         Jedis jedis = getJedis();
721         return jedis.smembers(key);
722     }
723 
724 
725     /**
726      * 通过key向zset中添加value,score,其中score就是用来排序的
727      * 如果该value已经存在则根据score更新元素
728      *
729      * @param key
730      * @param score
731      * @param member
732      * @return
733      */
734     public Long zadd(String key, double score, String member) {
735         Jedis jedis = getJedis();
736         return jedis.zadd(key, score, member);
737     }
738 
739     /**
740      * 通过key删除在zset中指定的value
741      *
742      * @param key
743      * @param members 可以 是一个string 也可以是一个string数组
744      * @return
745      */
746     public Long zrem(String key, String... members) {
747         Jedis jedis = getJedis();
748         return jedis.zrem(key, members);
749     }
750 
751     /**
752      * 通过key增加该zset中value的score的值
753      *
754      * @param key
755      * @param score
756      * @param member
757      * @return
758      */
759     public Double zincrby(String key, double score, String member) {
760         Jedis jedis = getJedis();
761         return jedis.zincrby(key, score, member);
762     }
763 
764     /**
765      * 通过key返回zset中value的排名
766      * 下标从小到大排序
767      *
768      * @param key
769      * @param member
770      * @return
771      */
772     public Long zrank(String key, String member) {
773         Jedis jedis = getJedis();
774         return jedis.zrank(key, member);
775     }
776 
777     /**
778      * 通过key返回zset中value的排名
779      * 下标从大到小排序
780      *
781      * @param key
782      * @param member
783      * @return
784      */
785     public Long zrevrank(String key, String member) {
786         Jedis jedis = getJedis();
787         return jedis.zrevrank(key, member);
788     }
789 
790     /**
791      * 通过key将获取score从start到end中zset的value
792      * socre从大到小排序
793      * 当start为0 end为-1时返回全部
794      *
795      * @param key
796      * @param start
797      * @param end
798      * @return
799      */
800     public Set<String> zrevrange(String key, long start, long end) {
801         Jedis jedis = getJedis();
802         return jedis.zrevrange(key, start, end);
803     }
804 
805     /**
806      * 通过key返回指定score内zset中的value
807      *
808      * @param key
809      * @param max
810      * @param min
811      * @return
812      */
813     public Set<String> zrangebyscore(String key, String max, String min) {
814         Jedis jedis = getJedis();
815         return jedis.zrevrangeByScore(key, max, min);
816     }
817 
818     /**
819      * 通过key返回指定score内zset中的value
820      *
821      * @param key
822      * @param max
823      * @param min
824      * @return
825      */
826     public Set<String> zrangeByScore(String key, double max, double min) {
827         Jedis jedis = getJedis();
828         return jedis.zrevrangeByScore(key, max, min);
829     }
830 
831     /**
832      * 返回指定区间内zset中value的数量
833      *
834      * @param key
835      * @param min
836      * @param max
837      * @return
838      */
839     public Long zcount(String key, String min, String max) {
840         Jedis jedis = getJedis();
841         return jedis.zcount(key, min, max);
842     }
843 
844     /**
845      * 通过key返回zset中的value个数
846      *
847      * @param key
848      * @return
849      */
850     public Long zcard(String key) {
851         Jedis jedis = getJedis();
852         return jedis.zcard(key);
853     }
854 
855     /**
856      * 通过key获取zset中value的score值
857      *
858      * @param key
859      * @param member
860      * @return
861      */
862     public Double zscore(String key, String member) {
863         Jedis jedis = getJedis();
864         return jedis.zscore(key, member);
865     }
866 
867     /**
868      * 通过key删除给定区间内的元素
869      *
870      * @param key
871      * @param start
872      * @param end
873      * @return
874      */
875     public Long zremrangeByRank(String key, long start, long end) {
876         Jedis jedis = getJedis();
877         return jedis.zremrangeByRank(key, start, end);
878     }
879 
880     /**
881      * 通过key删除指定score内的元素
882      *
883      * @param key
884      * @param start
885      * @param end
886      * @return
887      */
888     public Long zremrangeByScore(String key, double start, double end) {
889         Jedis jedis = getJedis();
890         return jedis.zremrangeByScore(key, start, end);
891     }
892 
893     /**
894      * 返回满足pattern表达式的所有key
895      * keys(*)
896      * 返回所有的key
897      *
898      * @param pattern
899      * @return
900      */
901     public Set<String> keys(String pattern) {
902         Jedis jedis = getJedis();
903         return jedis.keys(pattern);
904     }
905 
906     /**
907      * 通过key判断值得类型
908      *
909      * @param key
910      * @return
911      */
912     public String type(String key) {
913         Jedis jedis = getJedis();
914         return jedis.type(key);
915     }
916 
917 
918     private void close(Jedis jedis) {
919         if (jedis != null) {
920             jedis.close();
921         }
922     }
923 
924     private Jedis getJedis() {
925         return pool.getResource();
926     }
927 
928     public static RedisUtil getRedisUtil() {
929         return new RedisUtil();
930     }
931 
932 }
View Code

 

//连接redis ,redis的默认端口是6379

Jedis  jedis = new Jedis ("localhost",6379); 



//验证密码,如果没有设置密码这段代码省略

jedis.auth("password"); 



jedis.connect();//连接

jedis.disconnect();//断开连接



Set<String> keys = jedis.keys("*"); //列出所有的key

Set<String> keys = jedis.keys("key"); //查找特定的key

 



//移除给定的一个或多个key,如果key不存在,则忽略该命令. 

jedis.del("key1");

jedis.del("key1","key2","key3","key4","key5");



//移除给定key的生存时间(设置这个key永不过期)
jedis.persist("key1"); 

//检查给定key是否存在
jedis.exists("key1"); 

//将key改名为newkey,当key和newkey相同或者key不存在时,返回一个错误
jedis.rename("key1", "key2");

//返回key所储存的值的类型。 
//none(key不存在),string(字符串),list(列表),set(集合),zset(有序集),hash(哈希表) 
jedis.type("key1");

//设置key生存时间,当key过期时,它会被自动删除。 
jedis.expire("key1", 5);//5秒过期 
 


//字符串值value关联到key。 
jedis.set("key1", "value1"); 

//将值value关联到key,并将key的生存时间设为seconds(秒)。 
jedis.setex("foo", 5, "haha"); 

//清空所有的key
jedis.flushAll();

//返回key的个数 
jedis.dbSize();

//哈希表key中的域field的值设为value。 
jedis.hset("key1", "field1", "field1-value"); 
jedis.hset("key1", "field2", "field2-value"); 

Map map = new HashMap(); 
map.put("field1", "field1-value"); 
map.put("field2", "field2-value"); 
jedis.hmset("key1", map); 


//返回哈希表key中给定域field的值 
jedis.hget("key1", "field1");

//返回哈希表key中给定域field的值(多个)
List list = jedis.hmget("key1","field1","field2"); 
for(int i=0;i<list.size();i++){ 
   System.out.println(list.get(i)); 
} 

//返回哈希表key中所有域和值
Map<String,String> map = jedis.hgetAll("key1"); 
for(Map.Entry entry: map.entrySet()) { 
   System.out.print(entry.getKey() + ":" + entry.getValue() + "\t"); 
} 

//删除哈希表key中的一个或多个指定域
jedis.hdel("key1", "field1");
jedis.hdel("key1", "field1","field2");

//查看哈希表key中,给定域field是否存在。 
jedis.hexists("key1", "field1");

//返回哈希表key中的所有域
jedis.hkeys("key1");

//返回哈希表key中的所有值
jedis.hvals("key1");



//将值value插入到列表key的表头。 
jedis.lpush("key1", "value1-0"); 
jedis.lpush("key1", "value1-1"); 
jedis.lpush("key1", "value1-2"); 

//返回列表key中指定区间内的元素,区间以偏移量start和stop指定.
//下标(index)参数start和stop从0开始;
//负数下标代表从后开始(-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推)
List list = jedis.lrange("key1", 0, -1);//stop下标也在取值范围内(闭区间)
for(int i=0;i<list.size();i++){ 
   System.out.println(list.get(i)); 
} 

//返回列表key的长度。 
jedis.llen("key1")



//将member元素加入到集合key当中。 
jedis.sadd("key1", "value0"); 
jedis.sadd("key1", "value1"); 

//移除集合中的member元素。 
jedis.srem("key1", "value1"); 

//返回集合key中的所有成员。 
Set set = jedis.smembers("key1"); 

//判断元素是否是集合key的成员
jedis.sismember("key1", "value2")); 

//返回集合key的元素的数量
jedis.scard("key1");
 
//返回一个集合的全部成员,该集合是所有给定集合的交集
jedis.sinter("key1","key2")
 
//返回一个集合的全部成员,该集合是所有给定集合的并集
jedis.sunion("key1","key2")

//返回一个集合的全部成员,该集合是所有给定集合的差集
jedis.sdiff("key1","key2");
View Code

四、JedisPool使用

1、JedisPool 资源池优化

合理的 JedisPool 资源池参数设置能够有效地提升 Redis 性能。下面将对 JedisPool 的使用和资源池的参数进行详细说明,并提供优化配置的建议。

1)使用方法

以 Jedis 2.9.0 为例,其 Maven 依赖如下:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
    <scope>compile</scope>
</dependency>

Jedis 使用 Apache Commons-pool2 对资源池进行管理,在定义 JedisPool 时需注意其关键参数 GenericObjectPoolConfig(资源池)。该参数的使用示例如下,其中的参数的说明请参见下文。

GenericObjectPoolConfig jedisPoolConfig = new GenericObjectPoolConfig();
jedisPoolConfig.setMaxTotal(...);
jedisPoolConfig.setMaxIdle(...);
jedisPoolConfig.setMinIdle(...);
jedisPoolConfig.setMaxWaitMillis(...);
...

JedisPool 的初始化方法如下:

// redisHost为实例的IP, redisPort 为实例端口,redisPassword 为实例的密码,timeout 既是连接超时又是读写超时
JedisPool jedisPool = new JedisPool(jedisPoolConfig, redisHost, redisPort, timeout, redisPasswor//d);
//执命令如下
Jedis jedis = null;
try {
    jedis = jedisPool.getResource();
    //具体的命令
    jedis.executeCommand()
} catch (Exception e) {
    logger.error(e.getMessage(), e);
} finally {
    //在 JedisPool 模式下,Jedis 会被归还给资源池
    if (jedis != null) 
        jedis.close();
}

2)参数说明

  Jedis 连接就是连接池中 JedisPool 管理的资源, JedisPool 保证资源在一个可控范围内,并且保障线程安全。使用合理的GenericObjectPoolConfig 配置能够提升 Redis 的服务性能,降低资源开销。下列两表将对一些重要参数进行说明,并提供设置建议。

表 1. 资源设置与使用相关参数

空闲 Jedis 对象检测由下列四个参数组合完成,testWhileIdle 是该功能的开关。

表 2. 空闲资源检测相关参数

为了方便使用,Jedis 提供了 JedisPoolConfig ,它继承了 GenericObjectPoolConfig 在空闲检测上的一些设置。

public class JedisPoolConfig extends GenericObjectPoolConfig {
  public JedisPoolConfig() {
    // defaults to make your life with connection pool easier :)
    setTestWhileIdle(true);
    //
    setMinEvictableIdleTimeMillis(60000);
    //
    setTimeBetweenEvictionRunsMillis(30000);
    setNumTestsPerEvictionRun(-1);
    }
}

说明: 可以在 org.apache.commons.pool2.impl.BaseObjectPoolConfig 中查看全部默认值。

3)关键参数设置建议

maxTotal(最大连接数)

想合理设置maxTotal(最大连接数)需要考虑的因素较多,如:

  • 业务希望的 Redis 并发量;
  • 客户端执行命令时间;
  • Redis资源,例如 nodes (如应用个数等) * maxTotal 不能超过 Redis 的最大连接数;
  • 资源开销,例如虽然希望控制空闲连接,但又不希望因为连接池中频繁地释放和创建连接造成不必要的开销。

假设一次命令时间,即 borrow|return resource 加上 Jedis 执行命令 ( 含网络耗时)的平均耗时约为1ms,一个连接的 QPS 大约是1000,业务期望的 QPS 是50000,那么理论上需要的资源池大小是 50000 / 1000 = 50。

但事实上这只是个理论值,除此之外还要预留一些资源,所以 maxTotal 可以比理论值大一些。这个值不是越大越好,一方面连接太多会占用客户端和服务端资源,另一方面对于 Redis 这种高 QPS 的服务器,如果出现大命令的阻塞,即使设置再大的资源池也无济于事。

maxIdle 与 minIdle

maxIdle 实际上才是业务需要的最大连接数,maxTotal 是为了给出余量,所以 maxIdle 不要设置得过小,否则会有 new Jedis (新连接)开销,而 minIdle 是为了控制空闲资源检测。

连接池的最佳性能是 maxTotal = maxIdle ,这样就避免了连接池伸缩带来的性能干扰。但如果并发量不大或者 maxTotal 设置过高,则会导致不必要的连接资源浪费。

您可以根据实际总 QPS 和调用 Redis 的客户端规模整体评估每个节点所使用的连接池大小。

使用监控获取合理值

在实际环境中,比较可靠的方法是通过监控来尝试获取参数的最佳值。可以考虑通过 JMX 等方式实现监控,从而找到合理值。

4)工具类

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.*;


public class RedisUtil {
    
    private static Logger log = SnowLog.getLogger(RedisUtil.class);
    //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
    private static int MAX_WAIT = 5 * 1000;
    //超时时间
    private static int TIMEOUT = 2 * 1000;
    
    private static JedisPool jedisPool = null;
    
    /**
     * Jedis实例获取返回码
     * 
     * @author jqlin
     *
     */
    public static class JedisStatus{
        /**Jedis实例获取失败*/
        public static final long FAIL_LONG = -5L;
        /**Jedis实例获取失败*/
        public static final int FAIL_INT = -5;
        /**Jedis实例获取失败*/
        public static final String FAIL_STRING = "-5";
    }
    
    
    private static void initialPool() {
        //Redis服务器IP
        String HOST="";
        int PORT=6379;
        String AUTH="";
        try {
            HOST = ParamsUtil.getSysParam("redis.native.host");
            //Redis的端口号
            PORT = Integer.parseInt(ParamsUtil.getSysParam("redis.native.port"));
            //访问密码
            AUTH = ParamsUtil.getSysParam("redis.native.password");
        } catch (SnowException e1) {
            log.error("初始化异常", e1);
        }
        
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            //最大连接数,如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
            config.setMaxTotal(Integer.parseInt(ParamsUtil.getSysParam("redis.native.maxTotal")));
            //最大空闲数,控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
            config.setMaxIdle(Integer.parseInt(ParamsUtil.getSysParam("redis.native.maxIdle")));
            //最小空闲数
            config.setMinIdle(Integer.parseInt(ParamsUtil.getSysParam("redis.native.minIdle")));
            //是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
            config.setTestOnBorrow(true);
            //在return给pool时,是否提前进行validate操作
            config.setTestOnReturn(true);
            //在空闲时检查有效性,默认false
            config.setTestWhileIdle(true);
            //表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;
            //这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义
            config.setMinEvictableIdleTimeMillis(30000);
            //表示idle object evitor两次扫描之间要sleep的毫秒数
            config.setTimeBetweenEvictionRunsMillis(60000);
            //表示idle object evitor每次扫描的最多的对象数
            config.setNumTestsPerEvictionRun(1000); 
            //等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
            config.setMaxWaitMillis(MAX_WAIT);
            
            if (StringUtils.isNotBlank(AUTH)) {
                jedisPool = new JedisPool(config, HOST, PORT, TIMEOUT, AUTH);
            } else {
                jedisPool = new JedisPool(config, HOST, PORT, TIMEOUT);
            }
        } catch (Exception e) {
            if(jedisPool != null){
                jedisPool.close();
            }
            log.error("初始化Redis连接池失败", e);
        }
    }
    
    /**
     * 初始化Redis连接池
     */
    static {
        initialPool();
    }
    
    /**
     * 在多线程环境同步初始化
     */
    private static synchronized void poolInit() {
        if (jedisPool == null) {
            initialPool();
        }
    }
    
     /**
     * 同步获取Jedis实例
     *
     * @return Jedis
     */
    public static Jedis getJedis() throws Exception{
        if (jedisPool == null) {
            poolInit();
        }

        Jedis jedis = null;
        try {
            if (jedisPool != null) {
                jedis = jedisPool.getResource();
            }
        } catch (Exception e) {
            log.error("同步获取Jedis实例失败" + e.getMessage(), e);
            returnBrokenResource(jedis);
            throw new Exception(Exception.ExceptionType.ERROR,"同步获取Jedis实例失败");
        }  
        
        return jedis;
    }
    
    /**
     * 释放jedis资源
     *
     * @param jedis
     */
    @SuppressWarnings("deprecation")
    public static void returnResource(final Jedis jedis) {
        if (jedis != null && jedisPool != null) {
            jedisPool.returnResource(jedis);
        }
    }
    
    @SuppressWarnings("deprecation")
    public static void returnBrokenResource(final Jedis jedis) {
        if (jedis != null && jedisPool != null) {
            jedisPool.returnBrokenResource(jedis);
        }
    }
    
    /**
     * 设置值
     * 
     * @param key 
     * @param value 
     * @return -5:Jedis实例获取失败<br/>OK:操作成功<br/>null:操作失败
     * @author jqlin
     */
    public static String set(String key, String value) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return JedisStatus.FAIL_STRING;
        }
         
        String result = null;
        try { 
            result = jedis.set(key, value);
        } catch (Exception e) {
            log.error("设置值失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * 设置值
     * 
     * @param key
     * @param value
     * @param expire 过期时间,单位:秒
     * @return -5:Jedis实例获取失败<br/>OK:操作成功<br/>null:操作失败
     * @author jqlin
     */
    public static String set(String key, String value, int expire) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return JedisStatus.FAIL_STRING;
        }
        
        String result = null;
        try { 
            result = jedis.set(key, value);
            jedis.expire(key, expire);
        } catch (Exception e) {
            log.error("设置值失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }
        
        return result;
    }
    
    /**
     * 获取值
     * 
     * @param key
     * @return
     * @author jqlin
     */
    public static String get(String key) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return JedisStatus.FAIL_STRING;
        }
         
        String result = null;
        try { 
            result = jedis.get(key);
        } catch (Exception e) {
            log.error("获取值失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * 设置key的过期时间
     * 
     * @param key
     * @param value -5:Jedis实例获取失败,1:成功,0:失败
     * @return
     * @author jqlin
     */
    public static long expire(String key, int seconds) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return JedisStatus.FAIL_LONG;
        }
         
        long result = 0L;
        try { 
            result = jedis.expire(key, seconds);
        } catch (Exception e) {
            log.error(String.format("设置key=%s的过期时间失败:" + e.getMessage(), key), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * 判断key是否存在
     * 
     * @param key
     * @return
     * @author jqlin
     */
    public static boolean exists(String key) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            log.warn("Jedis实例获取为空");
            return false;
        }
         
        boolean result = false;
        try { 
            result = jedis.exists(key);
        } catch (Exception e) {
            log.error(String.format("判断key=%s是否存在失败:" + e.getMessage(), key), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * 删除key
     * 
     * @param keys
     * @return -5:Jedis实例获取失败,1:成功,0:失败
     * @author jqlin
     */
    public static long del(String... keys) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return JedisStatus.FAIL_LONG;
        }
         
        long result = JedisStatus.FAIL_LONG;
        try {  
            result = jedis.del(keys);
        } catch (Exception e) {
            log.error(String.format("删除key=%s失败:" + e.getMessage(), keys), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * set if not exists,若key已存在,则setnx不做任何操作
     * 
     * @param key
     * @param value key已存在,1:key赋值成功
     * @return
     * @author jqlin
     */
    public static long setnx(String key, String value) throws Exception{
        long result = JedisStatus.FAIL_LONG;
        
        Jedis jedis = getJedis();
        if(jedis == null){
            return result;
        }
         
        try { 
            result = jedis.setnx(key, value);
        } catch (Exception e) {
            log.error("设置值失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * set if not exists,若key已存在,则setnx不做任何操作
     * 
     * @param key
     * @param value key已存在,1:key赋值成功
     * @param expire 过期时间,单位:秒
     * @return
     * @author jqlin
     */
    public static long setnx(String key, String value, int expire) throws Exception{
        long result = JedisStatus.FAIL_LONG;
        
        Jedis jedis = getJedis();
        if(jedis == null){
            return result;
        }
        try {
            result = jedis.setnx(key, value);
            jedis.expire(key, expire);
        } catch (Exception e) {
            log.error("设置值失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }
        
        return result;
    }
    
    
    

   /**
    * 
    * @param key
    * @param value 
    * @param expire 秒
    * @return OK 成功  
    */
    public static String setnxByYao(String key, String value, int expire) throws Exception{
        String result = "";
        
        Jedis jedis = getJedis();
        if(jedis == null){
            return result;
        }
        try {
            result = jedis.set(key, value, "NX", "EX", expire);
        } catch (Exception e) {
            log.error("设置值失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }
        
        return result;
    }
    
    
    /**
     * 在列表key的头部插入元素
     * 
     * @param key
     * @param values -5:Jedis实例获取失败,>0:返回操作成功的条数,0:失败
     * @return
     * @author jqlin
     */
    public static long lpush(String key, String... values) throws Exception{
        long result = JedisStatus.FAIL_LONG;
        
        Jedis jedis = getJedis();
        if(jedis == null){
            return result;
        }
         
        try { 
            result = jedis.lpush(key, values);
        } catch (Exception e) {
            log.error("在列表key的头部插入元素失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * 在列表key的尾部插入元素
     * 
     * @param key
     * @param values -5:Jedis实例获取失败,>0:返回操作成功的条数,0:失败
     * @return
     * @author jqlin
     */
    public static long rpush(String key, String... values) throws Exception{
        long result = JedisStatus.FAIL_LONG;
        
        Jedis jedis = getJedis();
        if(jedis == null){
            return result;
        }
         
        try { 
            result = jedis.rpush(key, values);
        } catch (Exception e) {
            log.error("在列表key的尾部插入元素失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * 返回存储在key列表的特定元素 
     *   
     * 
     * @param key 
     * @param start 开始索引,索引从0开始,0表示第一个元素,1表示第二个元素
     * @param end 结束索引,-1表示最后一个元素,-2表示倒数第二个元素
     * @return redis client获取失败返回null
     * @author jqlin
     */
    public static List<String> lrange(String key, long start, long end) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return null;
        }
         
        List<String> result = null;
        try { 
            result = jedis.lrange(key, start, end);
        } catch (Exception e) {
            log.error("查询列表元素失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
//    /**
//     * 获取List缓存对象
//     * 
//     * @param key
//     * @param start
//     * @param end
//     * @return List<T> 返回类型
//     * @author jqlin
//     */
//    public static <T> List<T> range(String key, long start, long end, Class<T> clazz){
//        List<String> dataList = lrange(key, start, end);
//        if(dataList==null){
//            return new ArrayList<T>();
//        }
//        
//        return JavaJsonConvert.json2List(dataList.toString(), clazz);
//    }

    /**
     * 获取列表长度
     * 
     * @param key -5:Jedis实例获取失败
     * @return
     * @author jqlin
     */
    public static long llen(String key) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return JedisStatus.FAIL_LONG;
        }
         
        long result = 0;
        try { 
            result = jedis.llen(key);
        } catch (Exception e) {
            log.error("获取列表长度失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * 移除等于value的元素<br/><br/>
     *        当count>0时,从表头开始查找,移除count个;<br/>
     *        当count=0时,从表头开始查找,移除所有等于value的;<br/>
     *        当count<0时,从表尾开始查找,移除count个
     * 
     * @param key
     * @param count
     * @param value
     * @return -5:Jedis实例获取失败
     * @author jqlin
     */
    public static long lrem(String key, long count, String value) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return JedisStatus.FAIL_LONG;
        }
         
        long result = 0;
        try { 
            result = jedis.lrem(key, count, value);
        } catch (Exception e) {
            log.error("获取列表长度失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * 对列表进行修剪
     * 
     * @param key
     * @param start
     * @param end
     * @return -5:Jedis实例获取失败,OK:命令执行成功
     * @author jqlin
     */
    public static String ltrim(String key, long start, long end) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return JedisStatus.FAIL_STRING;
        }
         
        String result = "";
        try { 
            result = jedis.ltrim(key, start, end);
        } catch (Exception e) {
            log.error("获取列表长度失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * 设置对象
     * 
     * @param key
     * @param obj
     * @return
     * @author jqlin
     */
//    public static <T> String setObject(String key ,T obj){  
//        Jedis jedis = getJedis();
//        if(jedis == null){
//            return JedisStatus.FAIL_STRING;
//        }
//         
//        String result = null;
//        try { 
//            byte[] data=SerializeUtil.serialize(obj); 
//            result = jedis.set(key.getBytes(), data);
//        } catch (Exception e) {
//            log.error("设置对象失败:" + e.getMessage(), e);
//            returnBrokenResource(jedis);
//        } finally {
//            returnResource(jedis);
//        }
//
//        return result;
//    }
    
    /**
     * 获取对象
     * 
     * @param key
     * @return
     * @author jqlin
     */
//    @SuppressWarnings("unchecked")
//    public static <T> T getObject(String key){  
//        Jedis jedis = getJedis();
//        if(jedis == null){
//            return null;
//        }
//         
//        T result = null;
//        try { 
//            byte[] data = jedis.get(key.getBytes());
//            if(data != null && data.length > 0){
//                result=(T)SerializeUtil.unserialize(data);
//            }
//        } catch (Exception e) {
//            log.error("获取对象失败:" + e.getMessage(), e);
//            returnBrokenResource(jedis);
//        } finally {
//            returnResource(jedis);
//        }
//
//        return result;
//    }
    
    /**
     * 设置List集合(慎用)
     * 
     * @param key
     * @param dataList
     * @return
     * @author jqlin
     */
//    public synchronized static <T> T setList(String key, List<T> dataList){  
//        Jedis jedis = getJedis();
//        if(jedis == null){
//            return null;
//        }
//         
//        T result = null;
//        try { 
//            List<T> list = getList(key);
//            if(CollectionUtils.isNotEmpty(list)){
//                dataList.addAll(list);
//            }
//            
//            if(CollectionUtils.isNotEmpty(dataList)){
//                byte[] data = SerializeUtil.serializeToList(dataList);
//                jedis.set(key.getBytes(), data);
//            }else{//如果list为空,则设置一个空  
//                jedis.set(key.getBytes(), "".getBytes());
//            }
//        } catch (Exception e) {
//            log.error("设置List集合失败:" + e.getMessage(), e);
//            returnBrokenResource(jedis);
//        } finally {
//            returnResource(jedis);
//        }
//
//        return result;
//    }
    
    /**
     * 获取List集合(慎用)
     * 
     * @param key
     * @return
     * @author jqlin
     */
//    public static <T> List<T> getList(String key){  
//        Jedis jedis = getJedis();
//        if(jedis == null){
//            return null;
//        }
//         
//        try { 
//             byte[] data = getJedis().get(key.getBytes());  
//             if(data != null && data.length > 0){
//                 return SerializeUtil.unserializeToList(data);
//             }
//        } catch (Exception e) {
//            log.error("获取List集合失败:" + e.getMessage(), e);
//            returnBrokenResource(jedis);
//        } finally {
//            returnResource(jedis);
//        }
//
//        return null;
//    }
    
    /**
     * 缓存Map赋值
     * 
     * @param key
     * @param field
     * @param value
     * @return -5:Jedis实例获取失败
     * @author jqlin
     */
    public static long hset(String key, String field, String value) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return JedisStatus.FAIL_LONG;
        }
         
        long result = 0L;
        try { 
            result = jedis.hset(key, field, value);
        } catch (Exception e) {
            log.error("缓存Map赋值失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    
    
    /**
     * 获取缓存的Map值
     * 
     * @param key
     * @return
     */
    public static String hget(String key, String field)throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            return null;
        }
         
        String result = null;
        try { 
            result = jedis.hget(key, field);
        } catch (Exception e) {
            log.error("获取缓存的Map值失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return result;
    }
    
    /**
     * 获取map所有的字段和值
     * 
     * @param key
     * @return
     * @author jqlin
     */
    public static Map<String, String> hgetAll(String key)throws Exception{
        Map<String, String> map = new HashMap<String, String>();
        
        Jedis jedis = getJedis();
        if(jedis == null){
            log.warn("Jedis实例获取为空");
            return map;
        }
         
        try { 
            map = jedis.hgetAll(key);
        } catch (Exception e) {
            log.error("获取map所有的字段和值失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return map;
    }
    
    /**
     * 查看哈希表 key 中,指定的field字段是否存在。
     * 
     * @param key
     * @param field
     * @return
     * @author jqlin
     */
    public static Boolean hexists(String key, String field)throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            log.warn("Jedis实例获取为空");
            return null;
        }
         
        try { 
            return jedis.hexists(key, field);
        } catch (Exception e) {
            log.error("查看哈希表field字段是否存在失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return null;
    }

    /**
     * 获取所有哈希表中的字段
     * 
     * @param key
     * @return
     * @author jqlin
     */
    public static Set<String> hkeys(String key) throws Exception{
        Set<String> set = new HashSet<String>();
        Jedis jedis = getJedis();
        if(jedis == null){
            log.warn("Jedis实例获取为空");
            return set;
        }
        
        try { 
            return jedis.hkeys(key);
        } catch (Exception e) {
            log.error("获取所有哈希表中的字段失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return null;
    }
    
    /**
     * 获取所有哈希表中的值
     * 
     * @param key
     * @return
     * @author jqlin
     */
    public static List<String> hvals(String key) throws Exception{
        List<String> list = new ArrayList<String>();
        Jedis jedis = getJedis();
        if(jedis == null){
            log.warn("Jedis实例获取为空");
            return list;
        }
        
        try { 
            return jedis.hvals(key);
        } catch (Exception e) {
            log.error("获取所有哈希表中的值失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return null;
    }
    
    /**
     * 从哈希表 key 中删除指定的field
     * 
     * @param key
     * @param field
     * @return
     * @author jqlin
     */
    public static long hdel(String key, String... fields)throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            log.warn("Jedis实例获取为空");
            return JedisStatus.FAIL_LONG;
        }
        
        try { 
            return jedis.hdel(key, fields);
        } catch (Exception e) {
            log.error("map删除指定的field失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return 0;
    }

    /**
     * 返回set 集合长度
     * @param key
     * @return
     * @throws Exception
     */
    public static Long scard(String key) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            log.warn("Jedis实例获取为空");
            return JedisStatus.FAIL_LONG;
        }
        try{
            return jedis.scard(key);
        } catch (Exception e) {
            log.error("操作keys失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }
        return 0L;
    }


    /**
     * 设置 set集合
     * @param key
     * @param members
     * @return
     * @throws Exception
     */
    public static Long srem(String key,String... members) throws Exception{
        Jedis jedis = getJedis();
        if(jedis == null){
            log.warn("Jedis实例获取为空");
            return JedisStatus.FAIL_LONG;
        }
        try{
            return jedis.srem(key,members);
        } catch (Exception e) {
            log.error("操作keys失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }
        return 0L;
    }


    // 
    /**
     * 返回set 集合
     * @param key
     * @return
     * @throws SnowException
     */
    public static Set<String> smembers(String key)throws Exception{
         Set<String> keyList = new HashSet<String>();
        Jedis jedis = getJedis();
        if(jedis == null){
            log.warn("Jedis实例获取为空");
            return keyList;
        }
        try{
            keyList =jedis.smembers(key);
        } catch (Exception e) {
            log.error("操作keys失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }
        return keyList;
    }

    
    public static Set<String> keys(String pattern)throwsException{
        Set<String> keyList = new HashSet<String>();
        Jedis jedis = getJedis();
        if(jedis == null){
            log.warn("Jedis实例获取为空");
            return keyList;
        }
        
        try { 
            keyList = jedis.keys(pattern);
        } catch (Exception e) {
            log.error("操作keys失败:" + e.getMessage(), e);
            returnBrokenResource(jedis);
        } finally {
            returnResource(jedis);
        }

        return keyList;
    }
    
    public static void main(String[] args) throws Exception {
//        System.out.println(hset("map", "a","3"));
//        System.out.println(hset("map", "b","3"));
//        System.out.println(hset("map", "c","3"));
        Set<String> set = keys("lock*");
        for(String key : set){
            System.out.println(key);
        }
    }
}
View Code

2、常见问题

1)、资源不足

下面两种情况均属于无法从资源池获取到资源。

  • 超时:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
…
Caused by: java.util.NoSuchElementException: Timeout waiting for idle object
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:449)
  • blockWhenExhausted 为 false ,因此不会等待资源释放:
redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
…
Caused by: java.util.NoSuchElementException: Pool exhausted
at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:464)

此类异常的原因不一定是资源池不够大,请参见关键参数设置建议中的分析。建议从网络、资源池参数设置、资源池监控(如果对 JMX 监控)、代码(例如没执行jedis.close())、慢查询、DNS等方面进行排查。

2)、预热 JedisPool

  由于一些原因(如超时时间设置较小等),项目在启动成功后可能会出现超时。 JedisPool 定义最大资源数、最小空闲资源数时,不会在连接池中创建 Jedis 连接。初次使用时,池中没有资源使用则会先 new Jedis ,使用后再放入资源池,该过程会有一定的时间开销,所以建议在定义 JedisPool 后,以最小空闲数量为基准对 JedisPool 进行预热,示例如下:

List<Jedis> minIdleJedisList = new ArrayList<Jedis>(jedisPoolConfig.getMinIdle());

for (int i = 0; i < jedisPoolConfig.getMinIdle(); i++) {
    Jedis jedis = null;
    try {
        jedis = pool.getResource();
        minIdleJedisList.add(jedis);
        jedis.ping();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    } finally {
    }
}

for (int i = 0; i < jedisPoolConfig.getMinIdle(); i++) {
    Jedis jedis = null;
    try {
        jedis = minIdleJedisList.get(i);
        jedis.close();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    } finally {
    
    }
}

 

 

 

 

文章整理自:

http://tool.oschina.net/uploads/apidocs/redis/clients/jedis/Jedis.html

https://www.runoob.com/redis/redis-java.html

https://www.cnblogs.com/tengfly/p/9307373.html

https://help.aliyun.com/document_detail/98726.html

 

posted @ 2019-05-16 11:22  字节悦动  阅读(627)  评论(0编辑  收藏  举报