Redis实战之Jedis使用技巧详解
偷偷努力,悄无声息地变强,然后惊艳所有人!哈哈,小伙伴们又来学习啦~今天我将给大家介绍《Redis实战之Jedis使用技巧详解》,这篇文章主要会讲到RedisJedis等等知识点,不知道大家对其都有多少了解,下面我们就一起来看一吧!当然,非常希望大家能多多评论,给出合理的建议,我们一起学习,一起进步!
一、摘要
在上一篇文章中,我们详细的介绍了 redis 的安装和常见的操作命令,以及可视化工具的介绍。
刚知道服务端的操作知识,还是远远不够的,如果想要真正在项目中得到应用,我们还需要一个 redis 的客户端,然后将其集成到项目中,让程序自动根据我们的业务需要自动处理。
基于 redis 开放的通信协议,大神们纷纷开发了各种语言的 redis 客户端,有 c、c++、java、python、php、nodeJs 等等开发语言的客户端,准确来说其实这些客户端都是基于 redis 命令做了一层封装,然后打包成工具以便大家更佳方便的操作 redis,以 Java 项目为例,使用最广的就是以下三种客户端:
- Jedis
- Lettuce
- Redisson
由于篇幅的原因,我们分三篇文章来详细的讲解每个客户端的使用方式以及它的优缺点。
废话不多说,直奔主题!
二、Jedis
Jedis 是老牌的 Redis 的 Java 客户端,提供了比较全面的 Redis 命令的操作支持,也是目前使用最广泛的客户端。
官方网址如下:
https://github.com/redis/jedis
如何在项目中集成 Jedis 呢?请看下文!
2.1、基本使用
首先创建一个普通的 Maven 项目,然后添加Jedis依赖包!
<dependency> <groupid>redis.clients</groupid> <a target='_blank' href='https://www.17golang.com/gourl/?redirect=MDAwMDAwMDAwML57hpSHp6VpkrqbYLx2eayza4KafaOkbLS3zqSBrJvPsa5_0Ia6sWuR4Juaq6t9nq6ycKaUbJ1rsdDWoYKGfNrGoYeUhJWqspytnJrEeYWqsqObp36jkmqx0M5oloWEz62tfs6Sqrlph6pxYLyGm2S_fYGofmuDorLN0WyDhp_Rsa6VzoXdsqWGvX1iu6ybcQ' rel='nofollow'>使用Jedis面临的非线程安全问题详解</a></p> <p>所以我们需要将 Jedis 交给线程池来管理,使用 Jedis 对象时,从连接池获取 Jedis,使用完成之后,再还给连接池。</p> <p>在使用之前,需要添加<code>common-pool</code>线程池依赖包!</p> <pre class="brush:xml;"><dependency> <groupid>org.apache.commons</groupid> <artifactid>commons-pool2</artifactid> <version>2.11.1</version></dependency>
创建一个简单的使用线程池测试用例。
public class JedisPoolMain {
public static void main(String[] args) {
// 1. 构造一个 Jedis 连接池
JedisPool pool = new JedisPool("127.0.0.1", 6379);
// 2. 从连接池中获取一个 Jedis 连接
Jedis jedis = pool.getResource();
jedis.auth("111111");
// 3. Jedis 操作
String ping = jedis.ping();
System.out.println(ping);
// 4. 归还连接
jedis.close();
}
}
2.3、连接池配置
在实际的使用过程中,我们常常会这样来初始化线程池JedisPool,详细代码如下:
public class RedisPoolUtils {
private static JedisPool jedisPool = null;
/**
* redis服务器地址
*/
private static String addr = "127.0.0.1";
/**
* redis服务器端口
*/
private static int port = 6379;
/**
* redis服务器密码
*/
private static String auth = "111111";
static{
try {
JedisPoolConfig config = new JedisPoolConfig();
//连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
config.setBlockWhenExhausted(true);
//设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数)
config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");
//是否启用pool的jmx管理功能, 默认true
config.setJmxEnabled(true);
//MBean ObjectName = new ObjectName("org.apache.commons.pool2:type=GenericObjectPool,name=" + "pool" + i); 默认为"pool", JMX不熟,具体不知道是干啥的...默认就好.
config.setJmxNamePrefix("pool");
//是否启用后进先出, 默认true
config.setLifo(true);
//最大空闲连接数, 默认8个
config.setMaxIdle(8);
//最大连接数, 默认8个
config.setMaxTotal(8);
//获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
config.setMaxWaitMillis(-1);
//逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
config.setMinEvictableIdleTimeMillis(1800000);
//最小空闲连接数, 默认0
config.setMinIdle(0);
//每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
config.setNumTestsPerEvictionRun(3);
//对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数 时直接逐出,不再根据MinEvictableIdleTimeMillis判断 (默认逐出策略)
config.setSoftMinEvictableIdleTimeMillis(1800000);
//在获取连接的时候检查有效性, 默认false
config.setTestOnBorrow(false);
//在空闲时检查有效性, 默认false
config.setTestWhileIdle(false);
//逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
config.setTimeBetweenEvictionRunsMillis(-1);
jedisPool = new JedisPool(config, addr, port, 3000, auth);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取 Jedis 资源
* @return
*/
public static Jedis getJedis() {
if (jedisPool != null) {
return jedisPool.getResource();
}
return null;
}
/**
* 释放Jedis资源
*/
public static void close(final Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
}
简单测试
public static void main(String[] args) throws InterruptedException {
//获取 jedis 客户端
Jedis jedis = RedisPoolUtils.getJedis();
System.out.println("清空数据:"+jedis.flushDB());
System.out.println("判断某个键是否存在:"+jedis.exists("username"));
System.out.println("新增的键值对:"+jedis.set("username", "xmr"));
System.out.println(jedis.exists("username"));
System.out.println("新增的键值对:"+jedis.set("password", "123"));
System.out.print("系统中所有的键如下:");
Set<string> keys = jedis.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);
}
</string>
运行结果如下:
清空数据:OK
判断某个键是否存在:false
新增的键值对:OK
true
新增的键值对:OK
系统中所有的键如下:[password, username]
删除键password:1
判断键password是否存在:false
设置键username的过期时间为5s:1
查看键username的剩余生存时间:7
移除键username的生存时间:1
查看键username的剩余生存时间:-1
查看键username所存储的值的类型:string
2.4、字符串常用 API 操作
public class RedisClientUtil {
private static final Logger log = LoggerFactory.getLogger(RedisClientUtil.class);
/**
* 获取指定key的值,如果key不存在返回null
* 返回值:返回 key 的值,如果 key 不存在时,返回 nil
* @param key
* @return
*/
public static String get(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.get(key);
} catch (Exception e){
log.error("get命令操作失败,请求参数:{}", key,e);
}
return null;
}
/**
* 设置key的值为value
* 返回值:操作成功完成时返回 OK
* @param key
* @return
*/
public static String set(String key, String value) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.set(key, value);
} catch (Exception e){
log.error("set命令操作失败,参数key:{},参数value:{}", key, value,e);
}
return null;
}
/**
* 删除指定的key,返回值:被删除 key 的数量
* 返回值:被删除 key 的数量
* @param key
* @return
*/
public static Long del(String key) {
try (Jedis jedis = jedisPool.getResource()) {
Long result = jedis.del(key);
return jedis.del(key);
} catch (Exception e){
log.error("del命令操作失败,参数key:{}", key,e);
}
return 0L;
}
/**
* 通过key向指定的value值追加值
* 返回值:追加指定值之后, key中字符串的长度
* @param key
* @return
*/
public static Long append(String key, String value) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.append(key, value);
} catch (Exception e){
log.error("append命令操作失败,参数key:{},参数value:{}", key, value,e);
}
return 0L;
}
/**
* 判断key是否存在
* 返回值:true/false
* @param key
* @return
*/
public static Boolean exists(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.exists(key);
} catch (Exception e){
log.error("exists命令操作失败,参数key:{}", key,e);
}
return false;
}
/**
* 设置key的超时时间为seconds
* 返回值:若 key 存在返回 1 ,否则返回 0
* @param key
* @return
*/
public static Long expire(String key, long seconds) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.expire(key, seconds);
} catch (Exception e){
log.error("expire命令操作失败,参数key:{},参数seconds:{}", key, seconds,e);
}
return 0L;
}
/**
* 返回 key 的剩余过期时间(单位秒)
* 返回值:当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以秒为单位,返回 key 的剩余生存时间
* @param key
* @return
*/
public static Long ttl(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.ttl(key);
} catch (Exception e){
log.error("ttl命令操作失败,参数key:{}", key,e);
}
return 0L;
}
/**
* 设置指定key的值为value,当key不存在时才设置
* 返回值:设置成功返回 1,设置失败返回 0
* @param key
* @return
*/
public static Long setnx(String key, String value) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.setnx(key, value);
} catch (Exception e){
log.error("setnx命令操作失败,参数key:{},参数value:{}", key, value,e);
}
return 0L;
}
/**
* 设置指定key的值为value,并设置过期时间
* 返回值:设置成功时返回 OK
* @param key
* @return
*/
public static String setex(String key, String value, long seconds) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.setex(key, seconds, value);
} catch (Exception e){
log.error("setex命令操作失败,参数key:{},参数value:{}", key, value,e);
}
return null;
}
/**
* 通过key 和offset 从指定的位置开始将原先value替换
* 返回值:被修改后的字符串长度
* @param key
* @return
*/
public static Long setrange(String key, int offset, String value) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.setrange(key, offset, value);
} catch (Exception e){
log.error("setrange命令操作失败,参数key:{},参数value:{},参数offset:{}", key, value, offset,e);
}
return null;
}
/**
* 通过批量的key获取批量的value
* 返回值:一个包含所有给定 key 的值的列表。
* @param keys
* @return
*/
public static List<string> mget(String... keys) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.mget(keys);
} catch (Exception e){
log.error("mget命令操作失败,参数key:{}", keys.toString(),e);
}
return null;
}
/**
* 批量的设置key:value,也可以一个
* 返回值:总是返回 OK
* @param keysValues
* @return
*/
public static String mset(String... keysValues) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.mset(keysValues);
} catch (Exception e){
log.error("mset命令操作失败,参数key:{}", keysValues.toString(),e);
}
return null;
}
/**
* 设置key的值,并返回一个旧值
* 返回值:返回给定 key 的旧值,当 key 没有旧值时,即 key 不存在时,返回 nil
* @param key
* @return
*/
public static String getSet(String key, String value) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.getSet(key, value);
} catch (Exception e){
log.error("getSet命令操作失败,参数key:{},参数value:{}", key, value,e);
}
return null;
}
/**
* 通过下标和 key 获取指定下标位置的 value
* 返回值:截取得到的子字符串
* @param key
* @return
*/
public static String getrange(String key, int startOffset, int endOffset) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.getrange(key, startOffset, endOffset);
} catch (Exception e){
log.error("getrange命令操作失败,参数key:{},参数startOffset:{},参数offset:{}", key, startOffset, endOffset,e);
}
return null;
}
/**
* 通过key 对value进行加值+1操作,当value不是int类型时会返回错误,当key不存在是则value为1
* 返回值:执行INCR命令之后 key 的值
* @param key
* @return
*/
public static Long incr(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.incr(key);
} catch (Exception e){
log.error("incr命令操作失败,参数key:{}", key, e);
}
return 0L;
}
/**
* 通过key给指定的value加值
* 返回值:执行INCR命令之后 key 的值
* @param key
* @return
*/
public static Long incrBy(String key, long increment) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.incrBy(key, increment);
} catch (Exception e){
log.error("incrBy命令操作失败,参数key:{},参数increment:{}", key, increment,e);
}
return 0L;
}
/**
* 对key的值做减减操作
* 返回值:执行INCR命令之后 key 的值
* @param key
* @return
*/
public static Long decr(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.decr(key);
} catch (Exception e){
log.error("decr命令操作失败,参数key:{}", key, e);
}
return 0L;
}
/**
* 对key的值做减减操作,减去指定的值
* 返回值:执行INCR命令之后 key 的值
* @param key
* @return
*/
public static Long decrBy(String key, long decrement) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.decrBy(key, decrement);
} catch (Exception e){
log.error("decrBy命令操作失败,参数key:{},参数decrement:{}", key, decrement,e);
}
return 0L;
}
/**
* 通过key获取value值的长度
* 返回值:value值的长度
* @param key
* @return
*/
public static Long strlen(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.strlen(key);
} catch (Exception e){
log.error("strlen命令操作失败,参数key:{}", key, e);
}
return 0L;
}
}
</string>
2.5、哈希常用 API 操作
public class RedisClientUtil {
private static final Logger log = LoggerFactory.getLogger(RedisClientUtil.class);
/**
* 通过key 和 field 获取指定的 value
* 返回值:对应的value值
* @param key
* @return
*/
public static String hget(String key, String field) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.hget(key, field);
} catch (Exception e){
log.error("hget命令操作失败,参数key:{},参数field:{}", key, field,e);
}
return null;
}
/**
* 通过key给field设置指定的值,如果key不存在,则先创建
* 返回值:如果字段是哈希表中的一个新建字段,并且值设置成功,返回 1 ;如果哈希表中域字段已经存在且旧值已被新值覆盖,返回 0 。
* @param key
* @return
*/
public static Long hset(String key, String field, String value) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.hset(key, field, value);
} catch (Exception e){
log.error("hset命令操作失败,参数key:{},参数field:{},参数value:{}", key, field, value,e);
}
return 0L;
}
/**
* 通过key和field判断是否有指定的value存在
* 返回值:true/false
* @param key
* @return
*/
public static Boolean hexists(String key, String field) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.hexists(key, field);
} catch (Exception e){
log.error("hexists命令操作失败,参数key:{},参数field:{}", key, field,e);
}
return false;
}
/**
* 通过key返回field的数量
* 返回值:field的数量
* @param key
* @return
*/
public static Long hlen(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.hlen(key);
} catch (Exception e){
log.error("hlen命令操作失败,参数key:{}", key,e);
}
return 0L;
}
/**
* 通过key 删除指定的 field
* 返回值:删除的数量
* @param key
* @return
*/
public static Long hdel(String key, String... fields) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.hdel(key, fields);
} catch (Exception e){
log.error("hdel命令操作失败,参数key:{},参数fields:{}", key, fields.toString(),e);
}
return 0L;
}
/**
* 通过key返回所有的field
* 返回值:field集合
* @param key
* @return
*/
public static Set<string> hkeys(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.hkeys(key);
} catch (Exception e){
log.error("hkeys命令操作失败,参数key:{}", key,e);
}
return null;
}
/**
* 通过key获取所有的field和value
* 返回值:map对象
* @param key
* @return
*/
public static Map<string> hgetAll(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.hgetAll(key);
} catch (Exception e){
log.error("hgetAll命令操作失败,参数key:{}", key,e);
}
return null;
}
}
</string></string>
2.6、列表常用 API 操作
public class RedisClientUtil {
private static final Logger log = LoggerFactory.getLogger(RedisClientUtil.class);
/**
* 过key向list头部添加字符串
* 返回值:执行 LPUSH 命令后,列表的长度
* @param key
* @return
*/
public static Long lpush(String key, String... strs) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.lpush(key, strs);
} catch (Exception e){
log.error("lpush命令操作失败,参数key:{},参数strs:{}", key, strs.toString(),e);
}
return null;
}
/**
* 通过key向list尾部添加字符串
* 返回值:执行 RPUSH 命令后,列表的长度
* @param key
* @return
*/
public static Long rpush(String key, String... strs) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.rpush(key, strs);
} catch (Exception e){
log.error("rpush命令操作失败,参数key:{},参数strs:{}", key, strs.toString(),e);
}
return null;
}
/**
* 通过key设置list指定下标位置的value 如果下标超过list里面value的个数则报错
* 返回值:操作成功返回 ok ,否则返回错误信息
* @param key
* @return
*/
public static String lset(String key, Long index, String value) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.lset(key, index, value);
} catch (Exception e){
log.error("lset命令操作失败,参数key:{},参数index:{},参数value:{}", key, index, value,e);
}
return null;
}
/**
* 通过key从对应的list中删除指定的count个 和 value相同的元素
* 返回值:返回被删除的个数
* @param key
* @return
*/
public static Long lrem(String key, long count, String value) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.lrem(key, count, value);
} catch (Exception e){
log.error("lrem命令操作失败,参数key:{},参数count:{},参数value:{}", key, count, value,e);
}
return null;
}
/**
* 通过key保留list中从strat下标开始到end下标结束的value值
* 返回值:操作成功返回 ok ,否则返回错误信息
* @param key
* @return
*/
public static String ltrim(String key, long start, long end) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.ltrim(key, start, end);
} catch (Exception e){
log.error("ltrim命令操作失败,参数key:{},参数start:{},参数end:{}", key, start, end,e);
}
return null;
}
/**
* 通过key从list的头部删除一个value,并返回该value
* 返回值:value值
* @param key
* @return
*/
public static String lpop(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.lpop(key);
} catch (Exception e){
log.error("lpop命令操作失败,参数key:{}", key,e);
}
return null;
}
/**
* 通过key从list尾部删除一个value,并返回该元素
* 返回值:value值
* @param key
* @return
*/
public static String rpop(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.rpop(key);
} catch (Exception e){
log.error("rpop命令操作失败,参数key:{}", key,e);
}
return null;
}
/**
* 通过key获取list中指定下标位置的value
* 返回值:value值
* @param key
* @return
*/
public static String lindex(String key, long index){
try (Jedis jedis = jedisPool.getResource()) {
return jedis.lindex(key, index);
} catch (Exception e){
log.error("lindex命令操作失败,参数key:{},参数index:{}", key, index,e);
}
return null;
}
/**
* 通过key返回list的长度
* 返回值:value值
* @param key
* @return
*/
public static Long llen(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.llen(key);
} catch (Exception e){
log.error("llen命令操作失败,参数key:{}", key,e);
}
return null;
}
/**
* 通过key获取list指定下标位置的value 如果start 为 0 end 为 -1 则返回全部的list中的value
* 返回值:value值
* @param key
* @return
*/
public static List<string> lrange(String key, long start, long end) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.lrange(key, start, end);
} catch (Exception e){
log.error("lrange命令操作失败,参数key:{},参数start:{},参数end:{}", key, start, end,e);
}
return null;
}
}
</string>
2.7、集合常用 API 操作
public class RedisClientUtil {
private static final Logger log = LoggerFactory.getLogger(RedisClientUtil.class);
/**
* 通过key向指定的set中添加value
* 返回值:添加成功的个数
* @param key
* @return
*/
public static Long sadd(String key, String... members) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.sadd(key, members);
} catch (Exception e){
log.error("sadd命令操作失败,参数key:{},参数members:{}", key, members.toString(),e);
}
return null;
}
/**
* 通过key删除set中对应的value值
* 返回值:删除成功的个数
* @param key
* @return
*/
public static Long srem(String key, String... members) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.srem(key, members);
} catch (Exception e){
log.error("srem命令操作失败,参数key:{},参数members:{}", key, members.toString(),e);
}
return null;
}
/**
* 通过key获取set中value的个数
* 返回值:value的个数
* @param key
* @return
*/
public static Long scard(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.scard(key);
} catch (Exception e){
log.error("scard命令操作失败,参数key:{}", key,e);
}
return 0L;
}
/**
* 通过key判断value是否是set中的元素
* 返回值:true/false
* @param key
* @return
*/
public static Boolean sismember(String key, String member) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.sismember(key, member);
} catch (Exception e){
log.error("sismember命令操作失败,参数key:{},参数member:{}", key, member,e);
}
return false;
}
/**
* 通过key获取set中所有的value
* 返回值:所有的value
* @param key
* @return
*/
public static Set<string> smembers(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.smembers(key);
} catch (Exception e){
log.error("smembers命令操作失败,参数key:{}", key,e);
}
return null;
}
}
</string>
2.8、有序集合常用 API 操作
public class RedisClientUtil {
private static final Logger log = LoggerFactory.getLogger(RedisClientUtil.class);
/**
* 通过key向zset中添加value,score,其中score就是用来排序的 如果该value已经存在则根据score更新元素
* 返回值:被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员
* @param key
* @return
*/
public static Long zadd(String key, double score, String member) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.zadd(key, score, member);
} catch (Exception e){
log.error("zadd命令操作失败,参数key:{},参数score:{},参数member:{}", key, score, member,e);
}
return null;
}
/**
* 通过key删除在zset中指定的value
* 返回值:删除个数
* @param key
* @return
*/
public static Long zrem(String key, String... members) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.zrem(key, members);
} catch (Exception e){
log.error("zrem命令操作失败,参数key:{},参数members:{}", key, members.toString(),e);
}
return null;
}
/**
* 通过key增加该zset中value的score的值
* 返回值:member 成员的新分数值
* @param key
* @return
*/
public static Double zincrby(String key, double score, String member) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.zincrby(key, score, member);
} catch (Exception e){
log.error("zincrby命令操作失败,参数key:{},参数score:{},参数member:{}", key, score, member,e);
}
return null;
}
/**
* 通过key返回zset中value的排名 下标从小到大排序
* 返回值:返回 member 的排名
* @param key
* @return
*/
public static Long zrank(String key, String member) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.zrank(key, member);
} catch (Exception e){
log.error("zrank命令操作失败,参数key:{},参数member:{}", key, member,e);
}
return null;
}
/**
* 通过key将获取score从start到end中zset的value socre从大到小排序 当start为0 end为-1时返回全部
* 返回值:返回 member 集合
* @param key
* @return
*/
public static Set<string> zrevrange(String key, long start, long end) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.zrevrange(key, start, end);
} catch (Exception e){
log.error("zrevrange命令操作失败,参数key:{},参数start:{},参数end:{}", key, start, end,e);
}
return null;
}
/**
* 返回指定区间内zset中value的数量
* 返回值:返回 member 集合
* @param key
* @return
*/
public static Long zcount(String key, String min, String max) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.zcount(key, min, max);
} catch (Exception e){
log.error("zcount命令操作失败,参数key:{},参数min:{},参数max:{}", key, min, max,e);
}
return null;
}
/**
* 通过key返回zset中的value个数
* 返回值:返回 member 集合
* @param key
* @return
*/
public static Long zcard(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.zcard(key);
} catch (Exception e){
log.error("zcard命令操作失败,参数key:{}", key,e);
}
return null;
}
/**
* 返回满足pattern表达式的所有key keys(*) 返回所有的key
* 返回值:返回 key 集合
* @param pattern
* @return
*/
public static Set<string> keys(String pattern) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.keys(pattern);
} catch (Exception e){
log.error("keys命令操作失败,参数pattern:{}", pattern,e);
}
return null;
}
/**
* 通过key判断值得类型
* 返回值:值的类型
* @param key
* @return
*/
public static String type(String key) {
try (Jedis jedis = jedisPool.getResource()) {
return jedis.type(key);
} catch (Exception e){
log.error("type命令操作失败,参数key:{}", key,e);
}
return null;
}
}
</string></string>
三、集群配置
在实际的项目生产环境中,redis 通常不是以单台服务实例来运行的,因为一旦服务器挂了,可能所有的下游服务都会受到影响,因此为了保障单台服务器即使出现故障也能运行,通常运维组会搭建集群环境,来保证服务高可用。
搭建的方式有两种,哨兵模式和 Cluster 模式。
- 哨兵模式:对redis服务器进行监控,如果有宕机的,就从备机里面选一个出来作为主机,实现自动切换
- Cluster 模式:将数据进行分片存储,避免全部节点数据都一样,浪费空间
3.1、哨兵模式
哨兵模式简单的说,就是一台主机,一台备机,外加一台监控服务,当监控服务观测到主机已经宕机,就会将备用机切换成主机,以便继续提供服务。
public class RedisPoolUtils {
private static Jedis jedis;
private static JedisSentinelPool jedisSentinelPool;
static{
try {
JedisPoolConfig config = new JedisPoolConfig();
//最大空闲连接数, 默认8个
config.setMaxIdle(8);
//最大连接数, 默认8个
config.setMaxTotal(8);
//最小空闲连接数, 默认0
config.setMinIdle(0);
//获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
config.setMaxWaitMillis(3000);
//在获取连接的时候检查有效性,表示取出的redis对象可用, 默认false
config.setTestOnBorrow(true);
//redis服务器列表
Set<string> sentinels = new HashSet();
sentinels.add(new HostAndPort("192.168.43.212", 26379).toString());
sentinels.add(new HostAndPort("192.168.43.213", 26379).toString());
sentinels.add(new HostAndPort("192.168.43.214", 26379).toString());
//初始化连接池
jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels, config, "111111");
// 从池中获取一个Jedis对象
jedis = jedisSentinelPool.getResource();
} catch (Exception e) {
e.printStackTrace();
}
}
}
</string>
3.2、集群模式
为了保证高可用,redis-cluster集群通常会引入主从复制模型,一个主节点对应一个或者多个从节点,当主节点宕机的时候,就会启用从节点。
public class RedisPoolUtils {
static{
try {
JedisPoolConfig config = new JedisPoolConfig();
//最大空闲连接数, 默认8个
config.setMaxIdle(8);
//最大连接数, 默认8个
config.setMaxTotal(8);
//最小空闲连接数, 默认0
config.setMinIdle(0);
//获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间, 默认-1
config.setMaxWaitMillis(3000);
//在获取连接的时候检查有效性,表示取出的redis对象可用, 默认false
config.setTestOnBorrow(true);
Set<hostandport> nodes = new HashSet();
nodes.add(new HostAndPort("192.168.43.212", 26379));
nodes.add(new HostAndPort("192.168.43.213", 26379));
nodes.add(new HostAndPort("192.168.43.214", 26379));
JedisCluster jedisCluster = new JedisCluster(nodes, config);
jedisCluster.set("key", "hello world");
jedisCluster.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
</hostandport>
四、小结
jedis客户端是目前使用最广泛的一款 java 客户端,也是老牌的 Redis 的 Java 实现客户端。
优点很突出:
- 比较全面的提供了 Redis 的操作特性,也就是说你能用 redis 命令操作的,Jedis 包都也给你封装好了,直接使用即可
- 使用广泛,易上手
当然,缺点也有:
- Jedis 客户端实例不是线程安全的,需要借助连接池来管理和使用 Jedis
- 使用阻塞的I/O,且其方法调用都是同步的,程序流需要等到 sockets 处理完 I/O 才能执行,不支持异步
今天关于《Redis实战之Jedis使用技巧详解》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!
Redis慢查询日志与监视器问题
- 上一篇
- Redis慢查询日志与监视器问题
- 下一篇
- Redis中的慢日志
-
- 数据库 · Redis | 15小时前 |
- 监控Redis集群健康状态的工具与指标
- 112浏览 收藏
-
- 数据库 · Redis | 1星期前 |
- Redis数据安全防护全攻略
- 252浏览 收藏
-
- 数据库 · Redis | 2星期前 |
- Redis主从复制故障排查与修复技巧
- 302浏览 收藏
-
- 数据库 · Redis | 2星期前 |
- Redis与HBase存储方案详解
- 325浏览 收藏
-
- 数据库 · Redis | 2星期前 |
- Redis数据安全防护全攻略
- 157浏览 收藏
-
- 数据库 · Redis | 2星期前 |
- 高并发Redis优化技巧分享
- 257浏览 收藏
-
- 数据库 · Redis | 2星期前 |
- Redis数据安全防护全攻略
- 398浏览 收藏
-
- 数据库 · Redis | 3星期前 |
- Redis配置加密方法与安全设置
- 232浏览 收藏
-
- 数据库 · Redis | 3星期前 |
- RedisHyperLogLog高效统计技巧
- 283浏览 收藏
-
- 数据库 · Redis | 3星期前 |
- Redis与MySQL缓存同步方法详解
- 141浏览 收藏
-
- 数据库 · Redis | 3星期前 |
- Redis布隆过滤器防穿透原理解析
- 312浏览 收藏
-
- 数据库 · Redis | 1个月前 |
- Redis容器化部署实战技巧分享
- 195浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3167次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3380次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3409次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4513次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3789次使用
-
- redis复制有可能碰到的问题汇总
- 2023-01-01 501浏览
-
- 使用lua+redis解决发多张券的并发问题
- 2023-01-27 501浏览
-
- Redis应用实例分享:社交媒体平台设计
- 2023-06-21 501浏览
-
- 使用Python和Redis构建日志分析系统:如何实时监控系统运行状况
- 2023-08-08 501浏览
-
- 如何利用Redis和Python实现消息队列功能
- 2023-08-16 501浏览

