<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【進階篇】Redis實戰(zhàn)之Jedis使用技巧詳解,純干活

          共 67348字,需瀏覽 135分鐘

           ·

          2022-12-31 08:36


          一、摘要

          在上一篇文章中,我們詳細的介紹了 redis 的安裝和常見的操作命令,以及可視化工具的介紹。

          剛知道服務(wù)端的操作知識,還是遠遠不夠的,如果想要真正在項目中得到應(yīng)用,我們還需要一個 redis 的客戶端,然后將其集成到項目中,讓程序自動根據(jù)我們的業(yè)務(wù)需要自動處理。

          基于 redis 開放的通信協(xié)議,大神們紛紛開發(fā)了各種語言的 redis 客戶端,有 c、c++、java、python、php、nodeJs 等等開發(fā)語言的客戶端,準(zhǔn)確來說其實這些客戶端都是基于 redis 命令做了一層封裝,然后打包成工具以便大家更佳方便的操作 redis,以 Java 項目為例,使用最廣的就是以下三種客戶端:

          • Jedis
          • Lettuce
          • Redisson

          由于篇幅的原因,我們分三篇文章來詳細的講解每個客戶端的使用方式以及它的優(yōu)缺點。

          廢話不多說,直奔主題!

          二、Jedis

          Jedis 是老牌的 Redis 的 Java 客戶端,提供了比較全面的 Redis 命令的操作支持,也是目前使用最廣泛的客戶端。

          官方網(wǎng)址如下:

          https://github.com/redis/jedis

          如何在項目中集成 Jedis 呢?請看下文!

          2.1、基本使用

          首先創(chuàng)建一個普通的 Maven 項目,然后添加Jedis依賴包!

          <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.9.0</version>
          </dependency>

          然后創(chuàng)建一個簡單的測試,即可實現(xiàn)連接!

          public class JedisMain {

              public static void main(String[] args) {
                  // 1.構(gòu)造一個 Jedis 對象,因為這里使用的默認(rèn)端口 6379,所以不用配置端口
                  Jedis jedis = new Jedis("127.0.0.1"6379);
                  // 2.密碼認(rèn)證
                  jedis.auth("111111");
                  // 3.測試是否連接成功
                  String ping = jedis.ping();
                  // 4.返回 pong 表示連接成功
                  System.out.println(ping);
              }
          }

          對于 Jedis 而言,一旦連接上了 Redis 服務(wù)器,剩下的操作就非常容易了,由于 Jedis 中的 API 和 Redis 的命令高度一致,所以,Jedis 中的方法見名知意,直接使用即可。

          2.2、連接池

          雖然 redis 服務(wù)端是單線程操作,但是在實際項目中,使用 Jedis 對象來操作 redis 時,每次操作都需要新建/關(guān)閉 TCP 連接,連接資源開銷很高,同時 Jedis 對象的個數(shù)不受限制,在極端情況下可能會造成連接泄漏,同時 Jedis 存在多線程不安全的問題。

          為什么說 Jedis 線程不安全,更加詳細的原因可以訪問這個地址https://www.cnblogs.com/gxyandwmm/p/13485226.html

          所以我們需要將 Jedis 交給線程池來管理,使用 Jedis 對象時,從連接池獲取 Jedis,使用完成之后,再還給連接池。

          在使用之前,需要添加common-pool線程池依賴包!

          <dependency>
           <groupId>org.apache.commons</groupId>
           <artifactId>commons-pool2</artifactId>
           <version>2.11.1</version>
          </dependency>

          創(chuàng)建一個簡單的使用線程池測試用例。

          public class JedisPoolMain {

              public static void main(String[] args) {
                  // 1. 構(gòu)造一個 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服務(wù)器地址
               */

              private static String addr = "127.0.0.1";

              /**
               * redis服務(wù)器端口
               */

              private static int port = 6379;

              /**
               * redis服務(wù)器密碼
               */

              private static String auth = "111111";


              static{
                  try {
                      JedisPoolConfig config = new JedisPoolConfig();
                      //連接耗盡時是否阻塞, false報異常,ture阻塞直到超時, 默認(rèn)true
                      config.setBlockWhenExhausted(true);
                      //設(shè)置的逐出策略類名, 默認(rèn)DefaultEvictionPolicy(當(dāng)連接超過最大空閑時間,或連接數(shù)超過最大空閑連接數(shù))
                      config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");
                      //是否啟用pool的jmx管理功能, 默認(rèn)true
                      config.setJmxEnabled(true);
                      //MBean ObjectName = new ObjectName("org.apache.commons.pool2:type=GenericObjectPool,name=" + "pool" + i); 默認(rèn)為"pool", JMX不熟,具體不知道是干啥的...默認(rèn)就好.
                      config.setJmxNamePrefix("pool");
                      //是否啟用后進先出, 默認(rèn)true
                      config.setLifo(true);
                      //最大空閑連接數(shù), 默認(rèn)8個
                      config.setMaxIdle(8);
                      //最大連接數(shù), 默認(rèn)8個
                      config.setMaxTotal(8);
                      //獲取連接時的最大等待毫秒數(shù)(如果設(shè)置為阻塞時BlockWhenExhausted),如果超時就拋異常, 小于零:阻塞不確定的時間,  默認(rèn)-1
                      config.setMaxWaitMillis(-1);
                      //逐出連接的最小空閑時間 默認(rèn)1800000毫秒(30分鐘)
                      config.setMinEvictableIdleTimeMillis(1800000);
                      //最小空閑連接數(shù), 默認(rèn)0
                      config.setMinIdle(0);
                      //每次逐出檢查時 逐出的最大數(shù)目 如果為負(fù)數(shù)就是 : 1/abs(n), 默認(rèn)3
                      config.setNumTestsPerEvictionRun(3);
                      //對象空閑多久后逐出, 當(dāng)空閑時間>該值 且 空閑連接>最大空閑數(shù) 時直接逐出,不再根據(jù)MinEvictableIdleTimeMillis判斷  (默認(rèn)逐出策略)
                      config.setSoftMinEvictableIdleTimeMillis(1800000);
                      //在獲取連接的時候檢查有效性, 默認(rèn)false
                      config.setTestOnBorrow(false);
                      //在空閑時檢查有效性, 默認(rèn)false
                      config.setTestWhileIdle(false);
                      //逐出掃描的時間間隔(毫秒) 如果為負(fù)數(shù),則不運行逐出線程, 默認(rèn)-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("清空數(shù)據(jù):"+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("系統(tǒng)中所有的鍵如下:");
              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("設(shè)置鍵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);
          }

          運行結(jié)果如下:

          清空數(shù)據(jù):OK
          判斷某個鍵是否存在:false
          新增<'username','xmr'>的鍵值對:OK
          true
          新增<'password','password'>的鍵值對:OK
          系統(tǒng)中所有的鍵如下:[password, username]
          刪除鍵password:1
          判斷鍵password是否存在:false
          設(shè)置鍵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命令操作失敗,請求參數(shù):{}", key,e);
                  }
                  return null;
              }


              /**
               * 設(shè)置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命令操作失敗,參數(shù)key:{},參數(shù)value:{}", key, value,e);
                  }
                  return null;
              }


              /**
               * 刪除指定的key,返回值:被刪除 key 的數(shù)量
               * 返回值:被刪除 key 的數(shù)量
               * @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命令操作失敗,參數(shù)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命令操作失敗,參數(shù)key:{},參數(shù)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命令操作失敗,參數(shù)key:{}", key,e);
                  }
                  return false;
              }


              /**
               * 設(shè)置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命令操作失敗,參數(shù)key:{},參數(shù)seconds:{}", key, seconds,e);
                  }
                  return 0L;
              }

              /**
               * 返回 key 的剩余過期時間(單位秒)
               * 返回值:當(dāng) key 不存在時,返回 -2 。 當(dāng) key 存在但沒有設(shè)置剩余生存時間時,返回 -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命令操作失敗,參數(shù)key:{}", key,e);
                  }
                  return 0L;
              }


              /**
               * 設(shè)置指定key的值為value,當(dāng)key不存在時才設(shè)置
               * 返回值:設(shè)置成功返回 1,設(shè)置失敗返回 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命令操作失敗,參數(shù)key:{},參數(shù)value:{}", key, value,e);
                  }
                  return 0L;
              }

              /**
               * 設(shè)置指定key的值為value,并設(shè)置過期時間
               * 返回值:設(shè)置成功時返回 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命令操作失敗,參數(shù)key:{},參數(shù)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命令操作失敗,參數(shù)key:{},參數(shù)value:{},參數(shù)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命令操作失敗,參數(shù)key:{}", keys.toString(),e);
                  }
                  return null;
              }

              /**
               * 批量的設(shè)置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命令操作失敗,參數(shù)key:{}", keysValues.toString(),e);
                  }
                  return null;
              }


              /**
               * 設(shè)置key的值,并返回一個舊值
               * 返回值:返回給定 key 的舊值,當(dāng) 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命令操作失敗,參數(shù)key:{},參數(shù)value:{}", key, value,e);
                  }
                  return null;
              }

              /**
               * 通過下標(biāo)和 key 獲取指定下標(biāo)位置的 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命令操作失敗,參數(shù)key:{},參數(shù)startOffset:{},參數(shù)offset:{}", key, startOffset, endOffset,e);
                  }
                  return null;
              }


              /**
               * 通過key 對value進行加值+1操作,當(dāng)value不是int類型時會返回錯誤,當(dāng)key不存在是則value為1
               * 返回值:執(zhí)行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命令操作失敗,參數(shù)key:{}", key, e);
                  }
                  return 0L;
              }


              /**
               * 通過key給指定的value加值
               * 返回值:執(zhí)行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命令操作失敗,參數(shù)key:{},參數(shù)increment:{}", key, increment,e);
                  }
                  return 0L;
              }

              /**
               * 對key的值做減減操作
               * 返回值:執(zhí)行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命令操作失敗,參數(shù)key:{}", key, e);
                  }
                  return 0L;
              }

              /**
               * 對key的值做減減操作,減去指定的值
               * 返回值:執(zhí)行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命令操作失敗,參數(shù)key:{},參數(shù)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命令操作失敗,參數(shù)key:{}", key, e);
                  }
                  return 0L;
              }
          }

          2.5、哈希常用 API 操作

          public class RedisClientUtil {

              private static final Logger log = LoggerFactory.getLogger(RedisClientUtil.class);


              /**
               * 通過key 和 field 獲取指定的 value
               * 返回值:對應(yīng)的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命令操作失敗,參數(shù)key:{},參數(shù)field:{}", key, field,e);
                  }
                  return null;
              }

              /**
               * 通過key給field設(shè)置指定的值,如果key不存在,則先創(chuàng)建
               * 返回值:如果字段是哈希表中的一個新建字段,并且值設(shè)置成功,返回 1 ;如果哈希表中域字段已經(jīng)存在且舊值已被新值覆蓋,返回 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命令操作失敗,參數(shù)key:{},參數(shù)field:{},參數(shù)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命令操作失敗,參數(shù)key:{},參數(shù)field:{}", key, field,e);
                  }
                  return false;
              }


              /**
               * 通過key返回field的數(shù)量
               * 返回值:field的數(shù)量
               * @param key
               * @return
               */

              public static Long hlen(String key) {
                  try (Jedis jedis = jedisPool.getResource()) {
                      return jedis.hlen(key);
                  } catch (Exception e){
                      log.error("hlen命令操作失敗,參數(shù)key:{}", key,e);
                  }
                  return 0L;
              }


              /**
               * 通過key 刪除指定的 field
               * 返回值:刪除的數(shù)量
               * @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命令操作失敗,參數(shù)key:{},參數(shù)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命令操作失敗,參數(shù)key:{}", key,e);
                  }
                  return null;
              }


              /**
               * 通過key獲取所有的field和value
               * 返回值:map對象
               * @param key
               * @return
               */

              public static Map<String, String> hgetAll(String key) {
                  try (Jedis jedis = jedisPool.getResource()) {
                      return jedis.hgetAll(key);
                  } catch (Exception e){
                      log.error("hgetAll命令操作失敗,參數(shù)key:{}", key,e);
                  }
                  return null;
              }
          }

          2.6、列表常用 API 操作

          public class RedisClientUtil {

              private static final Logger log = LoggerFactory.getLogger(RedisClientUtil.class);


              /**
               * 過key向list頭部添加字符串
               * 返回值:執(zhí)行 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命令操作失敗,參數(shù)key:{},參數(shù)strs:{}", key, strs.toString(),e);
                  }
                  return null;
              }


              /**
               * 通過key向list尾部添加字符串
               * 返回值:執(zhí)行 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命令操作失敗,參數(shù)key:{},參數(shù)strs:{}", key, strs.toString(),e);
                  }
                  return null;
              }

              /**
               * 通過key設(shè)置list指定下標(biāo)位置的value 如果下標(biāo)超過list里面value的個數(shù)則報錯
               * 返回值:操作成功返回 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命令操作失敗,參數(shù)key:{},參數(shù)index:{},參數(shù)value:{}", key, index, value,e);
                  }
                  return null;
              }


              /**
               * 通過key從對應(yīng)的list中刪除指定的count個 和 value相同的元素
               * 返回值:返回被刪除的個數(shù)
               * @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命令操作失敗,參數(shù)key:{},參數(shù)count:{},參數(shù)value:{}", key, count, value,e);
                  }
                  return null;
              }



              /**
               * 通過key保留list中從strat下標(biāo)開始到end下標(biāo)結(jié)束的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命令操作失敗,參數(shù)key:{},參數(shù)start:{},參數(shù)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命令操作失敗,參數(shù)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命令操作失敗,參數(shù)key:{}", key,e);
                  }
                  return null;
              }


              /**
               * 通過key獲取list中指定下標(biāo)位置的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命令操作失敗,參數(shù)key:{},參數(shù)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命令操作失敗,參數(shù)key:{}", key,e);
                  }
                  return null;
              }


              /**
               * 通過key獲取list指定下標(biāo)位置的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命令操作失敗,參數(shù)key:{},參數(shù)start:{},參數(shù)end:{}", key, start, end,e);
                  }
                  return null;
              }

          }

          2.7、集合常用 API 操作

          public class RedisClientUtil {

              private static final Logger log = LoggerFactory.getLogger(RedisClientUtil.class);


              /**
               * 通過key向指定的set中添加value
               * 返回值:添加成功的個數(shù)
               * @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命令操作失敗,參數(shù)key:{},參數(shù)members:{}", key, members.toString(),e);
                  }
                  return null;
              }

              /**
               * 通過key刪除set中對應(yīng)的value值
               * 返回值:刪除成功的個數(shù)
               * @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命令操作失敗,參數(shù)key:{},參數(shù)members:{}", key, members.toString(),e);
                  }
                  return null;
              }

              /**
               * 通過key獲取set中value的個數(shù)
               * 返回值:value的個數(shù)
               * @param key
               * @return
               */

              public static Long scard(String key) {
                  try (Jedis jedis = jedisPool.getResource()) {
                      return jedis.scard(key);
                  } catch (Exception e){
                      log.error("scard命令操作失敗,參數(shù)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命令操作失敗,參數(shù)key:{},參數(shù)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命令操作失敗,參數(shù)key:{}", key,e);
                  }
                  return null;
              }

          }

          2.8、有序集合常用 API 操作

          public class RedisClientUtil {

              private static final Logger log = LoggerFactory.getLogger(RedisClientUtil.class);

              /**
               * 通過key向zset中添加value,score,其中score就是用來排序的 如果該value已經(jīng)存在則根據(jù)score更新元素
               * 返回值:被成功添加的新成員的數(shù)量,不包括那些被更新的、已經(jīng)存在的成員
               * @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命令操作失敗,參數(shù)key:{},參數(shù)score:{},參數(shù)member:{}", key, score, member,e);
                  }
                  return null;
              }


              /**
               * 通過key刪除在zset中指定的value
               * 返回值:刪除個數(shù)
               * @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命令操作失敗,參數(shù)key:{},參數(shù)members:{}", key, members.toString(),e);
                  }
                  return null;
              }


              /**
               * 通過key增加該zset中value的score的值
               * 返回值:member 成員的新分?jǐn)?shù)值
               * @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命令操作失敗,參數(shù)key:{},參數(shù)score:{},參數(shù)member:{}", key, score, member,e);
                  }
                  return null;
              }

              /**
               * 通過key返回zset中value的排名 下標(biāo)從小到大排序
               * 返回值:返回 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命令操作失敗,參數(shù)key:{},參數(shù)member:{}", key, member,e);
                  }
                  return null;
              }


              /**
               * 通過key將獲取score從start到end中zset的value socre從大到小排序 當(dāng)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命令操作失敗,參數(shù)key:{},參數(shù)start:{},參數(shù)end:{}", key, start, end,e);
                  }
                  return null;
              }

              /**
               * 返回指定區(qū)間內(nèi)zset中value的數(shù)量
               * 返回值:返回 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命令操作失敗,參數(shù)key:{},參數(shù)min:{},參數(shù)max:{}", key, min, max,e);
                  }
                  return null;
              }


              /**
               * 通過key返回zset中的value個數(shù)
               * 返回值:返回 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命令操作失敗,參數(shù)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命令操作失敗,參數(shù)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命令操作失敗,參數(shù)key:{}", key,e);
                  }
                  return null;
              }

          }

          三、集群配置

          在實際的項目生產(chǎn)環(huán)境中,redis 通常不是以單臺服務(wù)實例來運行的,因為一旦服務(wù)器掛了,可能所有的下游服務(wù)都會受到影響,因此為了保障單臺服務(wù)器即使出現(xiàn)故障也能運行,通常運維組會搭建集群環(huán)境,來保證服務(wù)高可用。

          搭建的方式有兩種,哨兵模式和 Cluster 模式。

          • 哨兵模式:對redis服務(wù)器進行監(jiān)控,如果有宕機的,就從備機里面選一個出來作為主機,實現(xiàn)自動切換
          • Cluster 模式:將數(shù)據(jù)進行分片存儲,避免全部節(jié)點數(shù)據(jù)都一樣,浪費空間

          3.1、哨兵模式

          哨兵模式簡單的說,就是一臺主機,一臺備機,外加一臺監(jiān)控服務(wù),當(dāng)監(jiān)控服務(wù)觀測到主機已經(jīng)宕機,就會將備用機切換成主機,以便繼續(xù)提供服務(wù)。

          public class RedisPoolUtils {

              private static Jedis jedis;

              private static JedisSentinelPool jedisSentinelPool;

              static{
                  try {
                      JedisPoolConfig config = new JedisPoolConfig();
                      //最大空閑連接數(shù), 默認(rèn)8個
                      config.setMaxIdle(8);
                      //最大連接數(shù), 默認(rèn)8個
                      config.setMaxTotal(8);
                      //最小空閑連接數(shù), 默認(rèn)0
                      config.setMinIdle(0);
                      //獲取連接時的最大等待毫秒數(shù)(如果設(shè)置為阻塞時BlockWhenExhausted),如果超時就拋異常, 小于零:阻塞不確定的時間,  默認(rèn)-1
                      config.setMaxWaitMillis(3000);
                      //在獲取連接的時候檢查有效性,表示取出的redis對象可用, 默認(rèn)false
                      config.setTestOnBorrow(true);


                      //redis服務(wù)器列表
                      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();
                  }
              }
              
          }

          3.2、集群模式

          為了保證高可用,redis-cluster集群通常會引入主從復(fù)制模型,一個主節(jié)點對應(yīng)一個或者多個從節(jié)點,當(dāng)主節(jié)點宕機的時候,就會啟用從節(jié)點。

          public class RedisPoolUtils {

              static{
                  try {
                      JedisPoolConfig config = new JedisPoolConfig();
                      //最大空閑連接數(shù), 默認(rèn)8個
                      config.setMaxIdle(8);
                      //最大連接數(shù), 默認(rèn)8個
                      config.setMaxTotal(8);
                      //最小空閑連接數(shù), 默認(rèn)0
                      config.setMinIdle(0);
                      //獲取連接時的最大等待毫秒數(shù)(如果設(shè)置為阻塞時BlockWhenExhausted),如果超時就拋異常, 小于零:阻塞不確定的時間,  默認(rèn)-1
                      config.setMaxWaitMillis(3000);
                      //在獲取連接的時候檢查有效性,表示取出的redis對象可用, 默認(rèn)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();
                  }
              }
          }

          四、小結(jié)

          jedis客戶端是目前使用最廣泛的一款 java 客戶端,也是老牌的 Redis 的 Java 實現(xiàn)客戶端。

          優(yōu)點很突出:

          • 比較全面的提供了 Redis 的操作特性,也就是說你能用 redis 命令操作的,Jedis 包都也給你封裝好了,直接使用即可
          • 使用廣泛,易上手

          當(dāng)然,缺點也有:

          • Jedis 客戶端實例不是線程安全的,需要借助連接池來管理和使用 Jedis
          • 使用阻塞的I/O,且其方法調(diào)用都是同步的,程序流需要等到 sockets 處理完 I/O 才能執(zhí)行,不支持異步

          本文主要是圍繞jedis客戶端做了一次知識總結(jié),希望能幫助到大家,內(nèi)容難免有所遺漏,歡迎批評指出!

          五、參考

          1、redis - 中文文檔

          2、騰訊云 - redis幾種java客戶端比較

          3、runoob - redis教程

          4、簡書 - redis java 客戶端


          END


          關(guān)注 Stephen,一起學(xué)習(xí),一起成長。


          “在看”支持下吧

          瀏覽 24
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色成人在线观看 | 亚洲韩日中文 | 91豆花成人网站 | 美女喷水网站 | 日本熟妇在线播放 |