一、摘要 在上一篇文章中,我们详细的介绍了redis的安装和常见的操作命令,以及可视化工具的介绍。 刚知道服务端的操作知识,还是远远不够的,如果想要真正在项目中得到应用,我们还需要一个redis的客户端,然后将其集成到项目中,让程序自动根据我们的业务需要自动处理。 基于redis开放的通信协议,大神们纷纷开发了各种语言的redis客户端,有c、c、java、python、php、nodeJs等等开发语言的客户端,准确来说其实这些客户端都是基于redis命令做了一层封装,然后打包成工具以便大家更加方便的操作redis,以Java项目为例,使用最广的就是以下三种客户端:JedisLettuceRedisson 由于篇幅的原因,我们分三篇文章来详细的讲解每个客户端的使用方式以及它的优缺点。 废话不多说,直奔主题!二、Jedis Jedis是老牌的Redis的Java客户端,提供了比较全面的Redis命令的操作支持,也是目前使用最广泛的客户端。 官方网址如下:https:github。comredisjedis 如何在项目中集成Jedis呢?请看下文!2。1、基本使用 首先创建一个普通的Maven项目,然后添加Jedis依赖包!dependencygroupIdredis。clientsgroupIdjedisartifactIdversion3。9。0versiondependency 然后创建一个简单的测试,即可实现连接!publicclassJedisMain{publicstaticvoidmain(String〔〕args){1。构造一个Jedis对象,因为这里使用的默认端口6379,所以不用配置端口JedisjedisnewJedis(127。0。0。1,6379);2。密码认证jedis。auth(111111);3。测试是否连接成功Stringpingjedis。ping();4。返回pong表示连接成功System。out。println(ping);}} 对于Jedis而言,一旦连接上了Redis服务器,剩下的操作就非常容易了,由于Jedis中的API和Redis的命令高度一致,所以,Jedis中的方法见名知意,直接使用即可。2。2、连接池 虽然redis服务端是单线程操作,但是在实际项目中,使用Jedis对象来操作redis时,每次操作都需要新建关闭TCP连接,连接资源开销很高,同时Jedis对象的个数不受限制,在极端情况下可能会造成连接泄漏,同时Jedis存在多线程不安全的问题。 为什么说Jedis线程不安全,更加详细的原因可以访问这个地址https:www。cnblogs。comgxyandwmmp13485226。html! 所以我们需要将Jedis交给线程池来管理,使用Jedis对象时,从连接池获取Jedis,使用完成之后,再还给连接池。 在使用之前,需要添加commonpool线程池依赖包!dependencygroupIdorg。apache。commonsgroupIdcommonspool2artifactIdversion2。11。1versiondependency 创建一个简单的使用线程池测试用例。publicclassJedisPoolMain{publicstaticvoidmain(String〔〕args){1。构造一个Jedis连接池JedisPoolpoolnewJedisPool(127。0。0。1,6379);2。从连接池中获取一个Jedis连接Jedisjedispool。getResource();jedis。auth(111111);3。Jedis操作Stringpingjedis。ping();System。out。println(ping);4。归还连接jedis。close();}}2。3、连接池配置 在实际的使用过程中,我们常常会这样来初始化线程池JedisPool,详细代码如下:publicclassRedisPoolUtils{privatestaticJedisPooljedisPoolnull;redis服务器地址privatestaticStringaddr127。0。0。1;redis服务器端口privatestaticintport6379;redis服务器密码privatestaticStringauth111111;static{try{JedisPoolConfigconfignewJedisPoolConfig();连接耗尽时是否阻塞,false报异常,ture阻塞直到超时,默认trueconfig。setBlockWhenExhausted(true);设置的逐出策略类名,默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数)config。setEvictionPolicyClassName(org。apache。commons。pool2。impl。DefaultEvictionPolicy);是否启用pool的jmx管理功能,默认trueconfig。setJmxEnabled(true);MBeanObjectNamenewObjectName(org。apache。commons。pool2:typeGenericObjectPool,namepooli);默认为pool,JMX不熟,具体不知道是干啥的。。。默认就好。config。setJmxNamePrefix(pool);是否启用后进先出,默认trueconfig。setLifo(true);最大空闲连接数,默认8个config。setMaxIdle(8);最大连接数,默认8个config。setMaxTotal(8);获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常,小于零:阻塞不确定的时间,默认1config。setMaxWaitMillis(1);逐出连接的最小空闲时间默认1800000毫秒(30分钟)config。setMinEvictableIdleTimeMillis(1800000);最小空闲连接数,默认0config。setMinIdle(0);每次逐出检查时逐出的最大数目如果为负数就是:1abs(n),默认3config。setNumTestsPerEvictionRun(3);对象空闲多久后逐出,当空闲时间该值且空闲连接最大空闲数时直接逐出,不再根据MinEvictableIdleTimeMillis判断(默认逐出策略)config。setSoftMinEvictableIdleTimeMillis(1800000);在获取连接的时候检查有效性,默认falseconfig。setTestOnBorrow(false);在空闲时检查有效性,默认falseconfig。setTestWhileIdle(false);逐出扫描的时间间隔(毫秒)如果为负数,则不运行逐出线程,默认1config。setTimeBetweenEvictionRunsMillis(1);jedisPoolnewJedisPool(config,addr,port,3000,auth);}catch(Exceptione){e。printStackTrace();}}获取Jedis资源returnpublicstaticJedisgetJedis(){if(jedisPool!null){returnjedisPool。getResource();}returnnull;}释放Jedis资源publicstaticvoidclose(finalJedisjedis){if(jedis!null){jedis。close();}}} 简单测试publicstaticvoidmain(String〔〕args)throwsInterruptedException{获取jedis客户端JedisjedisRedisPoolUtils。getJedis();System。out。println(清空数据:jedis。flushDB());System。out。println(判断某个键是否存在:jedis。exists(username));System。out。println(新增username,xmr的键值对:jedis。set(username,xmr));System。out。println(jedis。exists(username));System。out。println(新增password,password的键值对:jedis。set(password,123));System。out。print(系统中所有的键如下:);SetStringkeysjedis。keys();System。out。println(keys);System。out。println(删除键password:jedis。del(password));System。out。println(判断键password是否存在:jedis。exists(password));System。out。println(设置键username的过期时间为5s:jedis。expire(username,8L));TimeUnit。SECONDS。sleep(1);System。out。println(查看键username的剩余生存时间:jedis。ttl(username));System。out。println(移除键username的生存时间:jedis。persist(username));System。out。println(查看键username的剩余生存时间:jedis。ttl(username));System。out。println(查看键username所存储的值的类型:jedis。type(username));RedisPoolUtils。close(jedis);} 运行结果如下:清空数据:OK判断某个键是否存在:false新增username,xmr的键值对:OKtrue新增password,password的键值对:OK系统中所有的键如下:〔password,username〕删除键password:1判断键password是否存在:false设置键username的过期时间为5s:1查看键username的剩余生存时间:7移除键username的生存时间:1查看键username的剩余生存时间:1查看键username所存储的值的类型:string2。4、字符串常用API操作publicclassRedisClientUtil{privatestaticfinalLoggerlogLoggerFactory。getLogger(RedisClientUtil。class);获取指定key的值,如果key不存在返回null返回值:返回key的值,如果key不存在时,返回nilparamkeyreturnpublicstaticStringget(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。get(key);}catch(Exceptione){log。error(get命令操作失败,请求参数:{},key,e);}returnnull;}设置key的值为value返回值:操作成功完成时返回OKparamkeyreturnpublicstaticStringset(Stringkey,Stringvalue){try(JedisjedisjedisPool。getResource()){returnjedis。set(key,value);}catch(Exceptione){log。error(set命令操作失败,参数key:{},参数value:{},key,value,e);}returnnull;}删除指定的key,返回值:被删除key的数量返回值:被删除key的数量paramkeyreturnpublicstaticLongdel(Stringkey){try(JedisjedisjedisPool。getResource()){Longresultjedis。del(key);returnjedis。del(key);}catch(Exceptione){log。error(del命令操作失败,参数key:{},key,e);}return0L;}通过key向指定的value值追加值返回值:追加指定值之后,key中字符串的长度paramkeyreturnpublicstaticLongappend(Stringkey,Stringvalue){try(JedisjedisjedisPool。getResource()){returnjedis。append(key,value);}catch(Exceptione){log。error(append命令操作失败,参数key:{},参数value:{},key,value,e);}return0L;}判断key是否存在返回值:truefalseparamkeyreturnpublicstaticBooleanexists(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。exists(key);}catch(Exceptione){log。error(exists命令操作失败,参数key:{},key,e);}returnfalse;}设置key的超时时间为seconds返回值:若key存在返回1,否则返回0paramkeyreturnpublicstaticLongexpire(Stringkey,longseconds){try(JedisjedisjedisPool。getResource()){returnjedis。expire(key,seconds);}catch(Exceptione){log。error(expire命令操作失败,参数key:{},参数seconds:{},key,seconds,e);}return0L;}返回key的剩余过期时间(单位秒)返回值:当key不存在时,返回2。当key存在但没有设置剩余生存时间时,返回1。否则,以秒为单位,返回key的剩余生存时间paramkeyreturnpublicstaticLongttl(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。ttl(key);}catch(Exceptione){log。error(ttl命令操作失败,参数key:{},key,e);}return0L;}设置指定key的值为value,当key不存在时才设置返回值:设置成功返回1,设置失败返回0paramkeyreturnpublicstaticLongsetnx(Stringkey,Stringvalue){try(JedisjedisjedisPool。getResource()){returnjedis。setnx(key,value);}catch(Exceptione){log。error(setnx命令操作失败,参数key:{},参数value:{},key,value,e);}return0L;}设置指定key的值为value,并设置过期时间返回值:设置成功时返回OKparamkeyreturnpublicstaticStringsetex(Stringkey,Stringvalue,longseconds){try(JedisjedisjedisPool。getResource()){returnjedis。setex(key,seconds,value);}catch(Exceptione){log。error(setex命令操作失败,参数key:{},参数value:{},key,value,e);}returnnull;}通过key和offset从指定的位置开始将原先value替换返回值:被修改后的字符串长度paramkeyreturnpublicstaticLongsetrange(Stringkey,intoffset,Stringvalue){try(JedisjedisjedisPool。getResource()){returnjedis。setrange(key,offset,value);}catch(Exceptione){log。error(setrange命令操作失败,参数key:{},参数value:{},参数offset:{},key,value,offset,e);}returnnull;}通过批量的key获取批量的value返回值:一个包含所有给定key的值的列表。paramkeysreturnpublicstaticListStringmget(String。。。keys){try(JedisjedisjedisPool。getResource()){returnjedis。mget(keys);}catch(Exceptione){log。error(mget命令操作失败,参数key:{},keys。toString(),e);}returnnull;}批量的设置key:value,也可以一个返回值:总是返回OKparamkeysValuesreturnpublicstaticStringmset(String。。。keysValues){try(JedisjedisjedisPool。getResource()){returnjedis。mset(keysValues);}catch(Exceptione){log。error(mset命令操作失败,参数key:{},keysValues。toString(),e);}returnnull;}设置key的值,并返回一个旧值返回值:返回给定key的旧值,当key没有旧值时,即key不存在时,返回nilparamkeyreturnpublicstaticStringgetSet(Stringkey,Stringvalue){try(JedisjedisjedisPool。getResource()){returnjedis。getSet(key,value);}catch(Exceptione){log。error(getSet命令操作失败,参数key:{},参数value:{},key,value,e);}returnnull;}通过下标和key获取指定下标位置的value返回值:截取得到的子字符串paramkeyreturnpublicstaticStringgetrange(Stringkey,intstartOffset,intendOffset){try(JedisjedisjedisPool。getResource()){returnjedis。getrange(key,startOffset,endOffset);}catch(Exceptione){log。error(getrange命令操作失败,参数key:{},参数startOffset:{},参数offset:{},key,startOffset,endOffset,e);}returnnull;}通过key对value进行加值1操作,当value不是int类型时会返回错误,当key不存在是则value为1返回值:执行INCR命令之后key的值paramkeyreturnpublicstaticLongincr(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。incr(key);}catch(Exceptione){log。error(incr命令操作失败,参数key:{},key,e);}return0L;}通过key给指定的value加值返回值:执行INCR命令之后key的值paramkeyreturnpublicstaticLongincrBy(Stringkey,longincrement){try(JedisjedisjedisPool。getResource()){returnjedis。incrBy(key,increment);}catch(Exceptione){log。error(incrBy命令操作失败,参数key:{},参数increment:{},key,increment,e);}return0L;}对key的值做减减操作返回值:执行INCR命令之后key的值paramkeyreturnpublicstaticLongdecr(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。decr(key);}catch(Exceptione){log。error(decr命令操作失败,参数key:{},key,e);}return0L;}对key的值做减减操作,减去指定的值返回值:执行INCR命令之后key的值paramkeyreturnpublicstaticLongdecrBy(Stringkey,longdecrement){try(JedisjedisjedisPool。getResource()){returnjedis。decrBy(key,decrement);}catch(Exceptione){log。error(decrBy命令操作失败,参数key:{},参数decrement:{},key,decrement,e);}return0L;}通过key获取value值的长度返回值:value值的长度paramkeyreturnpublicstaticLongstrlen(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。strlen(key);}catch(Exceptione){log。error(strlen命令操作失败,参数key:{},key,e);}return0L;}}2。5、哈希常用API操作publicclassRedisClientUtil{privatestaticfinalLoggerlogLoggerFactory。getLogger(RedisClientUtil。class);通过key和field获取指定的value返回值:对应的value值paramkeyreturnpublicstaticStringhget(Stringkey,Stringfield){try(JedisjedisjedisPool。getResource()){returnjedis。hget(key,field);}catch(Exceptione){log。error(hget命令操作失败,参数key:{},参数field:{},key,field,e);}returnnull;}通过key给field设置指定的值,如果key不存在,则先创建返回值:如果字段是哈希表中的一个新建字段,并且值设置成功,返回1;如果哈希表中域字段已经存在且旧值已被新值覆盖,返回0。paramkeyreturnpublicstaticLonghset(Stringkey,Stringfield,Stringvalue){try(JedisjedisjedisPool。getResource()){returnjedis。hset(key,field,value);}catch(Exceptione){log。error(hset命令操作失败,参数key:{},参数field:{},参数value:{},key,field,value,e);}return0L;}通过key和field判断是否有指定的value存在返回值:truefalseparamkeyreturnpublicstaticBooleanhexists(Stringkey,Stringfield){try(JedisjedisjedisPool。getResource()){returnjedis。hexists(key,field);}catch(Exceptione){log。error(hexists命令操作失败,参数key:{},参数field:{},key,field,e);}returnfalse;}通过key返回field的数量返回值:field的数量paramkeyreturnpublicstaticLonghlen(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。hlen(key);}catch(Exceptione){log。error(hlen命令操作失败,参数key:{},key,e);}return0L;}通过key删除指定的field返回值:删除的数量paramkeyreturnpublicstaticLonghdel(Stringkey,String。。。fields){try(JedisjedisjedisPool。getResource()){returnjedis。hdel(key,fields);}catch(Exceptione){log。error(hdel命令操作失败,参数key:{},参数fields:{},key,fields。toString(),e);}return0L;}通过key返回所有的field返回值:field集合paramkeyreturnpublicstaticSetStringhkeys(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。hkeys(key);}catch(Exceptione){log。error(hkeys命令操作失败,参数key:{},key,e);}returnnull;}通过key获取所有的field和value返回值:map对象paramkeyreturnpublicstaticMapString,StringhgetAll(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。hgetAll(key);}catch(Exceptione){log。error(hgetAll命令操作失败,参数key:{},key,e);}returnnull;}}2。6、列表常用API操作publicclassRedisClientUtil{privatestaticfinalLoggerlogLoggerFactory。getLogger(RedisClientUtil。class);过key向list头部添加字符串返回值:执行LPUSH命令后,列表的长度paramkeyreturnpublicstaticLonglpush(Stringkey,String。。。strs){try(JedisjedisjedisPool。getResource()){returnjedis。lpush(key,strs);}catch(Exceptione){log。error(lpush命令操作失败,参数key:{},参数strs:{},key,strs。toString(),e);}returnnull;}通过key向list尾部添加字符串返回值:执行RPUSH命令后,列表的长度paramkeyreturnpublicstaticLongrpush(Stringkey,String。。。strs){try(JedisjedisjedisPool。getResource()){returnjedis。rpush(key,strs);}catch(Exceptione){log。error(rpush命令操作失败,参数key:{},参数strs:{},key,strs。toString(),e);}returnnull;}通过key设置list指定下标位置的value如果下标超过list里面value的个数则报错返回值:操作成功返回ok,否则返回错误信息paramkeyreturnpublicstaticStringlset(Stringkey,Longindex,Stringvalue){try(JedisjedisjedisPool。getResource()){returnjedis。lset(key,index,value);}catch(Exceptione){log。error(lset命令操作失败,参数key:{},参数index:{},参数value:{},key,index,value,e);}returnnull;}通过key从对应的list中删除指定的count个和value相同的元素返回值:返回被删除的个数paramkeyreturnpublicstaticLonglrem(Stringkey,longcount,Stringvalue){try(JedisjedisjedisPool。getResource()){returnjedis。lrem(key,count,value);}catch(Exceptione){log。error(lrem命令操作失败,参数key:{},参数count:{},参数value:{},key,count,value,e);}returnnull;}通过key保留list中从strat下标开始到end下标结束的value值返回值:操作成功返回ok,否则返回错误信息paramkeyreturnpublicstaticStringltrim(Stringkey,longstart,longend){try(JedisjedisjedisPool。getResource()){returnjedis。ltrim(key,start,end);}catch(Exceptione){log。error(ltrim命令操作失败,参数key:{},参数start:{},参数end:{},key,start,end,e);}returnnull;}通过key从list的头部删除一个value,并返回该value返回值:value值paramkeyreturnpublicstaticStringlpop(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。lpop(key);}catch(Exceptione){log。error(lpop命令操作失败,参数key:{},key,e);}returnnull;}通过key从list尾部删除一个value,并返回该元素返回值:value值paramkeyreturnpublicstaticStringrpop(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。rpop(key);}catch(Exceptione){log。error(rpop命令操作失败,参数key:{},key,e);}returnnull;}通过key获取list中指定下标位置的value返回值:value值paramkeyreturnpublicstaticStringlindex(Stringkey,longindex){try(JedisjedisjedisPool。getResource()){returnjedis。lindex(key,index);}catch(Exceptione){log。error(lindex命令操作失败,参数key:{},参数index:{},key,index,e);}returnnull;}通过key返回list的长度返回值:value值paramkeyreturnpublicstaticLongllen(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。llen(key);}catch(Exceptione){log。error(llen命令操作失败,参数key:{},key,e);}returnnull;}通过key获取list指定下标位置的value如果start为0end为1则返回全部的list中的value返回值:value值paramkeyreturnpublicstaticListStringlrange(Stringkey,longstart,longend){try(JedisjedisjedisPool。getResource()){returnjedis。lrange(key,start,end);}catch(Exceptione){log。error(lrange命令操作失败,参数key:{},参数start:{},参数end:{},key,start,end,e);}returnnull;}}2。7、集合常用API操作publicclassRedisClientUtil{privatestaticfinalLoggerlogLoggerFactory。getLogger(RedisClientUtil。class);通过key向指定的set中添加value返回值:添加成功的个数paramkeyreturnpublicstaticLongsadd(Stringkey,String。。。members){try(JedisjedisjedisPool。getResource()){returnjedis。sadd(key,members);}catch(Exceptione){log。error(sadd命令操作失败,参数key:{},参数members:{},key,members。toString(),e);}returnnull;}通过key删除set中对应的value值返回值:删除成功的个数paramkeyreturnpublicstaticLongsrem(Stringkey,String。。。members){try(JedisjedisjedisPool。getResource()){returnjedis。srem(key,members);}catch(Exceptione){log。error(srem命令操作失败,参数key:{},参数members:{},key,members。toString(),e);}returnnull;}通过key获取set中value的个数返回值:value的个数paramkeyreturnpublicstaticLongscard(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。scard(key);}catch(Exceptione){log。error(scard命令操作失败,参数key:{},key,e);}return0L;}通过key判断value是否是set中的元素返回值:truefalseparamkeyreturnpublicstaticBooleansismember(Stringkey,Stringmember){try(JedisjedisjedisPool。getResource()){returnjedis。sismember(key,member);}catch(Exceptione){log。error(sismember命令操作失败,参数key:{},参数member:{},key,member,e);}returnfalse;}通过key获取set中所有的value返回值:所有的valueparamkeyreturnpublicstaticSetStringsmembers(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。smembers(key);}catch(Exceptione){log。error(smembers命令操作失败,参数key:{},key,e);}returnnull;}}2。8、有序集合常用API操作publicclassRedisClientUtil{privatestaticfinalLoggerlogLoggerFactory。getLogger(RedisClientUtil。class);通过key向zset中添加value,score,其中score就是用来排序的如果该value已经存在则根据score更新元素返回值:被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员paramkeyreturnpublicstaticLongzadd(Stringkey,doublescore,Stringmember){try(JedisjedisjedisPool。getResource()){returnjedis。zadd(key,score,member);}catch(Exceptione){log。error(zadd命令操作失败,参数key:{},参数score:{},参数member:{},key,score,member,e);}returnnull;}通过key删除在zset中指定的value返回值:删除个数paramkeyreturnpublicstaticLongzrem(Stringkey,String。。。members){try(JedisjedisjedisPool。getResource()){returnjedis。zrem(key,members);}catch(Exceptione){log。error(zrem命令操作失败,参数key:{},参数members:{},key,members。toString(),e);}returnnull;}通过key增加该zset中value的score的值返回值:member成员的新分数值paramkeyreturnpublicstaticDoublezincrby(Stringkey,doublescore,Stringmember){try(JedisjedisjedisPool。getResource()){returnjedis。zincrby(key,score,member);}catch(Exceptione){log。error(zincrby命令操作失败,参数key:{},参数score:{},参数member:{},key,score,member,e);}returnnull;}通过key返回zset中value的排名下标从小到大排序返回值:返回member的排名paramkeyreturnpublicstaticLongzrank(Stringkey,Stringmember){try(JedisjedisjedisPool。getResource()){returnjedis。zrank(key,member);}catch(Exceptione){log。error(zrank命令操作失败,参数key:{},参数member:{},key,member,e);}returnnull;}通过key将获取score从start到end中zset的valuesocre从大到小排序当start为0end为1时返回全部返回值:返回member集合paramkeyreturnpublicstaticSetStringzrevrange(Stringkey,longstart,longend){try(JedisjedisjedisPool。getResource()){returnjedis。zrevrange(key,start,end);}catch(Exceptione){log。error(zrevrange命令操作失败,参数key:{},参数start:{},参数end:{},key,start,end,e);}returnnull;}返回指定区间内zset中value的数量返回值:返回member集合paramkeyreturnpublicstaticLongzcount(Stringkey,Stringmin,Stringmax){try(JedisjedisjedisPool。getResource()){returnjedis。zcount(key,min,max);}catch(Exceptione){log。error(zcount命令操作失败,参数key:{},参数min:{},参数max:{},key,min,max,e);}returnnull;}通过key返回zset中的value个数返回值:返回member集合paramkeyreturnpublicstaticLongzcard(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。zcard(key);}catch(Exceptione){log。error(zcard命令操作失败,参数key:{},key,e);}returnnull;}返回满足pattern表达式的所有keykeys()返回所有的key返回值:返回key集合parampatternreturnpublicstaticSetStringkeys(Stringpattern){try(JedisjedisjedisPool。getResource()){returnjedis。keys(pattern);}catch(Exceptione){log。error(keys命令操作失败,参数pattern:{},pattern,e);}returnnull;}通过key判断值得类型返回值:值的类型paramkeyreturnpublicstaticStringtype(Stringkey){try(JedisjedisjedisPool。getResource()){returnjedis。type(key);}catch(Exceptione){log。error(type命令操作失败,参数key:{},key,e);}returnnull;}}三、集群配置 在实际的项目生产环境中,redis通常不是以单台服务实例来运行的,因为一旦服务器挂了,可能所有的下游服务都会受到影响,因此为了保障单台服务器即使出现故障也能运行,通常运维组会搭建集群环境,来保证服务高可用。 搭建的方式有两种,哨兵模式和Cluster模式。哨兵模式:对redis服务器进行监控,如果有宕机的,就从备机里面选一个出来作为主机,实现自动切换Cluster模式:将数据进行分片存储,避免全部节点数据都一样,浪费空间3。1、哨兵模式 哨兵模式简单的说,就是一台主机,一台备机,外加一台监控服务,当监控服务观测到主机已经宕机,就会将备用机切换成主机,以便继续提供服务。publicclassRedisPoolUtils{privatestaticJedisjedis;privatestaticJedisSentinelPooljedisSentinelPool;static{try{JedisPoolConfigconfignewJedisPoolConfig();最大空闲连接数,默认8个config。setMaxIdle(8);最大连接数,默认8个config。setMaxTotal(8);最小空闲连接数,默认0config。setMinIdle(0);获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常,小于零:阻塞不确定的时间,默认1config。setMaxWaitMillis(3000);在获取连接的时候检查有效性,表示取出的redis对象可用,默认falseconfig。setTestOnBorrow(true);redis服务器列表SetStringsentinelsnewHashSet();sentinels。add(newHostAndPort(192。168。43。212,26379)。toString());sentinels。add(newHostAndPort(192。168。43。213,26379)。toString());sentinels。add(newHostAndPort(192。168。43。214,26379)。toString());初始化连接池jedisSentinelPoolnewJedisSentinelPool(mymaster,sentinels,config,111111);从池中获取一个Jedis对象jedisjedisSentinelPool。getResource();}catch(Exceptione){e。printStackTrace();}}}3。2、集群模式 为了保证高可用,rediscluster集群通常会引入主从复制模型,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。publicclassRedisPoolUtils{static{try{JedisPoolConfigconfignewJedisPoolConfig();最大空闲连接数,默认8个config。setMaxIdle(8);最大连接数,默认8个config。setMaxTotal(8);最小空闲连接数,默认0config。setMinIdle(0);获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常,小于零:阻塞不确定的时间,默认1config。setMaxWaitMillis(3000);在获取连接的时候检查有效性,表示取出的redis对象可用,默认falseconfig。setTestOnBorrow(true);SetHostAndPortnodesnewHashSet();nodes。add(newHostAndPort(192。168。43。212,26379));nodes。add(newHostAndPort(192。168。43。213,26379));nodes。add(newHostAndPort(192。168。43。214,26379));JedisClusterjedisClusternewJedisCluster(nodes,config);jedisCluster。set(key,helloworld);jedisCluster。close();}catch(Exceptione){e。printStackTrace();}}}四、小结 jedis客户端是目前使用最广泛的一款java客户端,也是老牌的Redis的Java实现客户端。 优点很突出:比较全面的提供了Redis的操作特性,也就是说你能用redis命令操作的,Jedis包都也给你封装好了,直接使用即可使用广泛,易上手 当然,缺点也有:Jedis客户端实例不是线程安全的,需要借助连接池来管理和使用Jedis使用阻塞的IO,且其方法调用都是同步的,程序流需要等到sockets处理完IO才能执行,不支持异步 本文主要是围绕jedis客户端做了一次知识总结,希望能帮助到大家,内容难免有所遗漏,欢迎批评指出!五、参考 1、redis中文文档 2、腾讯云redis几种java客户端比较 3、runoobredis教程 4、简书redisjava客户端 原文链接:https:mp。weixin。qq。comsXRRmiWXEgpKmf04Rp48lQ