Jedis的使用及配置優(yōu)化

Jedis是什么

jedis就是基于java語言的redis客戶端批狱,集成了redis的命令操作态坦,提供了連接池管理廉邑。
redis-cli是redis官方提供的客戶端音婶,可以看作一個shell程序慨畸,它可以發(fā)送命令對redis進行操作。
對于jedis同理是使用java語言操作redis衣式,雙方都遵循redis提供的協(xié)議寸士,按照協(xié)議開發(fā)對應(yīng)的客戶端。

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

Jedis直連

jedis直連碴卧,本質(zhì)是定義一個tcp連接弱卡,然后使用socket技術(shù)進行通信

    //1.生成一個jedis對象,這個對象負責和指定Redis節(jié)點進行通信
    Jedis jedis = new Jedis("119.23.226.29", 6379);
    //帶密碼需要執(zhí)行認證方法
    //jedis.auth("123456");
    //2.jedis執(zhí)行set操作
    jedis.set("hello", "world");
    //3.jedis執(zhí)行g(shù)et操作住册,value="world"
    String value = jedis.get("hello");
構(gòu)造方法參數(shù)介紹

Jedis簡單使用

字符串
// 1.string
//輸出結(jié)果: OK
jedis.set("hello", "world");
//輸出結(jié)果: world
jedis.get("hello");
//輸出結(jié)果:1
jedis.incr("counter");
哈希
// 2.hash
jedis.hset("myhash", "f1", "v1");
jedis.hset("myhash", "f2", "v2");
//輸出結(jié)果 : {f1=v1, f2=v2}
jedis.hgetAll("myhash");
列表
// 3.list
jedis.rpush("mylist", "1");
jedis.rpush("mylist", "2");
jedis.rpush(" mylist", "3");
//輸出結(jié)果 : [1, 2, 3]
jedis.lrange("mylist", 0, -1);
集合
// 4.set
jedis.sadd(" myset", "a");
jedis.sadd(" myset", "b");
jedis.sadd(" myset", "a");
//輸出結(jié)果 : [b, a]
jedis.smembers("myset");
有序集合
// 5.zset
jedis.zadd("myzset", 99, "tom");
jedis.zadd("myzset", 66, "peter");
jedis.zadd("myzset", 33, "james");
//輸出結(jié)果 : [[["james"],33.0], [["peter"],66.0], [["tom"],99.0]]
jedis.zrangeWithScores("myzset", 0, -1);

Jedis連接池

jedis直連

每次操作創(chuàng)建一個jedis對象婶博,執(zhí)行完畢后關(guān)閉連接,對應(yīng)的就是一次Tcp連接界弧。

jedis連接池

預先生成一批jedis連接對象放入連接池中凡蜻,當需要對redis進行操作時從連接池中借用jedis對象搭综,操作完成后歸還。這樣jedis對象可以重復使用划栓,避免了頻繁創(chuàng)建socket連接兑巾,節(jié)省了連接開銷。

方案對比

連接池簡單使用

這里只是對連接池進行一個簡單使用忠荞,實際開發(fā)通常會對JedisPool進行封裝蒋歌,進行一些參數(shù)配置和方法定義等,在使用Jedis API時委煤,也會對常用API進行封裝堂油,方便程序調(diào)用

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class Demo {
    
    public static void main(String[] args) {
        //連接池配置對象,包含了很多默認配置
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        //初始化Jedis連接池,通常來講JedisPool是單例的
        JedisPool jedisPool = new JedisPool(poolConfig, "119.23.226.29", 6379);
        Jedis jedis = null;
        try {
            //1.從連接池獲取jedis對象
            jedis = jedisPool.getResource();
            //2.執(zhí)行操作
            jedis.set("hello", "jedis");
            System.out.println(jedis.get("hello"));
        } catch (Exception e) {
            e.printStackTrace();
        } finally{
            //如果使用JedisPool碧绞,那么close操作不是關(guān)閉連接府框,代表歸還連接池
            if(jedis != null){
                jedis.close();
            }
        }   
    }
}

Jedis配置優(yōu)化

對于企業(yè)級開發(fā)來說,連接池的合理使用是非常重要的讥邻,如果設(shè)置不當會引起很多不必要的麻煩迫靖,容易造成線上的故障。
其實關(guān)于配置是一個比較難或者說沒有確定答案的部分兴使,這里只能給出一些思路和解決一些異常的方法系宜。

連接池重要配置

為了方便使用,Jedis提供了JedisPoolConfig发魄,它本身繼承了GenericObjectPoolConfig設(shè)置了一些空閑監(jiān)測設(shè)置

資源數(shù)控制
借還參數(shù)
適合的maxTotal

其實這個參數(shù)是比較難確定的盹牧,舉個例子:

  • 命令平均執(zhí)行時間0.1ms = 0.001s
  • 業(yè)務(wù)需要50000 QPS
  • maxTotal理論值 = 0.001 * 50000 = 50個。實際值要偏大一些

對于適合的maxTotal而言励幼,我們需要考慮

  • 業(yè)務(wù)希望Redis并發(fā)量
  • 客戶端執(zhí)行命令時間
  • Redis資源:例如 nodes(例如應(yīng)用個數(shù)) * maxTotal 是不能超過redis的最大連接數(shù)
  • 資源開銷:例如雖然希望控制空閑連接汰寓,但是不希望因為連接池的頻繁釋放創(chuàng)建連接造成不必靠開銷
適合的maxIdle和minIdle
  • 建議maxIdle = maxTotal,減少創(chuàng)建新連接的開銷
  • 建議預熱minIdle苹粟,減少第一次啟動后的新連接開銷
常見問題

無法從資源池獲取到資源踩寇,原因是獲取空閑連接超時了。

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)

無法從資源池獲取到資源六水,原因是池子中資源已經(jīng)耗盡了。

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)
解決思路
  1. 慢查詢阻塞:池子連接都被hang住辣卒。
  2. 資源池參數(shù)不合理:例如QPS高掷贾、池子小。
  3. 連接泄露(沒有close()):此類問題比較難定位荣茫,例如client list想帅、netstat等,最重要的是寫合理的代碼啡莉。
  4. DNS異常等港准。
例如連接泄漏
    public static void main(String[] args){

        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(10);
        jedisPoolConfig.setMaxWaitMillis(1000);
    
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, "127.0.0.1", 6379);
    
        for(int i = 0; i < 10; i++){
            Jedis jedis = null;
            try{
                jedis = jedisPool.getResource();
                jedis.ping();
                //沒有進行連接的歸還
            }catch(Exception e){
                e.printStackTrace();
            }
            //再次獲取資源就會出錯
            jedisPool.getResource().ping();
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旨剥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子浅缸,更是在濱河造成了極大的恐慌轨帜,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衩椒,死亡現(xiàn)場離奇詭異蚌父,居然都是意外死亡,警方通過查閱死者的電腦和手機毛萌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門苟弛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人阁将,你說我怎么就攤上這事膏秫。” “怎么了做盅?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵缤削,是天一觀的道長。 經(jīng)常有香客問我言蛇,道長僻他,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任腊尚,我火速辦了婚禮吨拗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘婿斥。我一直安慰自己劝篷,他們只是感情好,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布民宿。 她就那樣靜靜地躺著娇妓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪活鹰。 梳的紋絲不亂的頭發(fā)上哈恰,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音志群,去河邊找鬼着绷。 笑死,一個胖子當著我的面吹牛锌云,可吹牛的內(nèi)容都是我干的荠医。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼彬向!你這毒婦竟也來了兼贡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤娃胆,失蹤者是張志新(化名)和其女友劉穎遍希,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缕棵,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡孵班,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了招驴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片篙程。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖别厘,靈堂內(nèi)的尸體忽然破棺而出虱饿,到底是詐尸還是另有隱情,我是刑警寧澤触趴,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布氮发,位于F島的核電站,受9級特大地震影響冗懦,放射性物質(zhì)發(fā)生泄漏爽冕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一披蕉、第九天 我趴在偏房一處隱蔽的房頂上張望颈畸。 院中可真熱鬧,春花似錦没讲、人聲如沸眯娱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽徙缴。三九已至,卻和暖如春嘁信,著一層夾襖步出監(jiān)牢的瞬間于样,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工潘靖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留百宇,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓秘豹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親昌粤。 傳聞我的和親對象是個殘疾皇子既绕,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容