Redis cluster使用pipeline

一般解決思路

redis集群有16384個(gè)slot传藏,例如有3個(gè)節(jié)點(diǎn),那么每個(gè)節(jié)點(diǎn)可能分配的slot為Node A是0-5500,Node B是5501-11000邦危,Node C是11001-16383洋侨。pipeline是要基于某個(gè)節(jié)點(diǎn)的,所以如果要用pipeline查詢某些key的值倦蚪,那么就需要通過JedisClusterCRC16.getSlot(key)計(jì)算key的slot值希坚,通過上面每個(gè)節(jié)點(diǎn)的slot分布,就知道了哪些key應(yīng)該在哪些節(jié)點(diǎn)上陵且。再獲取這個(gè)節(jié)點(diǎn)的JedisPool就可以使用pipeline進(jìn)行讀寫了裁僧。實(shí)現(xiàn)上面的過程可以有很多種方式,本文將介紹一種也許是代碼量最少的一種解決方法慕购。本文基于redis 3.2.9(如何安裝redis集群請(qǐng)參考http://www.reibang.com/p/64d05c4e0ae2)以及

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

解決方案

上一節(jié)提到的過程聊疲,其實(shí)在JedisClusterInfoCache對(duì)象中都已經(jīng)幫助開發(fā)人員實(shí)現(xiàn)了,但是這個(gè)對(duì)象在JedisClusterConnectionHandler中為protected并沒有對(duì)外開放沪悲,而且通過JedisCluster的API也無(wú)法拿到JedisClusterConnectionHandler對(duì)象获洲。所以通過下面兩個(gè)類將這些對(duì)象暴露出來,這樣使用getJedisPoolFromSlot就可以知道每個(gè)key對(duì)應(yīng)的JedisPool了殿如。

class JedisClusterPlus extends JedisCluster {

    public JedisClusterPlus(Set<HostAndPort> jedisClusterNode, int connectionTimeout, int soTimeout, final GenericObjectPoolConfig poolConfig) {
        super(jedisClusterNode);
        super.connectionHandler = new JedisSlotAdvancedConnectionHandler(jedisClusterNode, poolConfig,
                connectionTimeout, soTimeout);
    }

    public JedisSlotAdvancedConnectionHandler getConnectionHandler() {
        return (JedisSlotAdvancedConnectionHandler)this.connectionHandler;
    }
}
public class JedisSlotAdvancedConnectionHandler extends JedisSlotBasedConnectionHandler{

    public JedisSlotAdvancedConnectionHandler(Set<HostAndPort> nodes, GenericObjectPoolConfig poolConfig, int connectionTimeout, int soTimeout) {
        super(nodes, poolConfig, connectionTimeout, soTimeout);
    }

    public JedisPool getJedisPoolFromSlot(int slot) {
        JedisPool connectionPool = cache.getSlotPool(slot);
        if (connectionPool != null) {
            // It can't guaranteed to get valid connection because of node
            // assignment
            return connectionPool;
        } else {
            renewSlotCache(); //It's abnormal situation for cluster mode, that we have just nothing for slot, try to rediscover state
            connectionPool = cache.getSlotPool(slot);
            if (connectionPool != null) {
                return connectionPool;
            } else {
                throw new JedisNoReachableClusterNodeException("No reachable node in cluster for slot " + slot);
            }
        }
    }
}

Demo

public class Tester {
    public static void main(String[] args) {
        Set<HostAndPort> jedisClusterNode = new HashSet<>();
        HostAndPort hostAndPort1 = new HostAndPort("hostA",7000);
        HostAndPort hostAndPort2 = new HostAndPort("hostB",7001);
        HostAndPort hostAndPort3 = new HostAndPort("hostC",7002);
        jedisClusterNode.add(hostAndPort1);
        jedisClusterNode.add(hostAndPort2);
        jedisClusterNode.add(hostAndPort3);

        JedisClusterPlus jedisClusterPlus = new JedisClusterPlus(jedisClusterNode, 2000, 2000, new JedisPoolConfig());
        JedisSlotAdvancedConnectionHandler jedisSlotAdvancedConnectionHandler = jedisClusterPlus.getConnectionHandler();

        String[] testKeys = {"foo","bar","xyz"};

        Map<JedisPool, List<String>> poolKeys = new HashMap<>();

        for (String key : testKeys) {
            int slot = JedisClusterCRC16.getSlot(key);
            JedisPool jedisPool = jedisSlotAdvancedConnectionHandler.getJedisPoolFromSlot(slot);
            if (poolKeys.keySet().contains(jedisPool)){
                List<String> keys = poolKeys.get(jedisPool);
                keys.add(key);
            }else {
                List<String> keys = new ArrayList<>();
                keys.add(key);
                poolKeys.put(jedisPool, keys);
            }
        }

        for (JedisPool jedisPool : poolKeys.keySet()) {
            Jedis jedis = jedisPool.getResource();
            Pipeline pipeline = jedis.pipelined();

            List<String> keys = poolKeys.get(jedisPool);

            keys.forEach(key ->pipeline.get(key));

            List result = pipeline.syncAndReturnAll();

            System.out.println(result);

            jedis.close();
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贡珊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子涉馁,更是在濱河造成了極大的恐慌飞崖,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谨胞,死亡現(xiàn)場(chǎng)離奇詭異固歪,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)胯努,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門牢裳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人叶沛,你說我怎么就攤上這事蒲讯。” “怎么了灰署?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵判帮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我溉箕,道長(zhǎng)晦墙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任肴茄,我火速辦了婚禮晌畅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寡痰。我一直安慰自己抗楔,他們只是感情好棋凳,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著连躏,像睡著了一般剩岳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上入热,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天拍棕,我揣著相機(jī)與錄音,去河邊找鬼才顿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛尤蒿,可吹牛的內(nèi)容都是我干的郑气。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼腰池,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼尾组!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起示弓,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤讳侨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后奏属,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體跨跨,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年囱皿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了勇婴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嘱腥,死狀恐怖耕渴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情凯正,我是刑警寧澤水泉,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布膳沽,位于F島的核電站,受9級(jí)特大地震影響添诉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜医寿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一吻商、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧糟红,春花似錦艾帐、人聲如沸乌叶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)准浴。三九已至,卻和暖如春捎稚,著一層夾襖步出監(jiān)牢的瞬間乐横,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工今野, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留葡公,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓条霜,卻偏偏與公主長(zhǎng)得像催什,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宰睡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354

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

  • redis集群分為服務(wù)端集群和客戶端分片蒲凶,redis3.0以上版本實(shí)現(xiàn)了集群機(jī)制,即服務(wù)端集群拆内,3.0以下使用客戶...
    hadoop_null閱讀 1,589評(píng)論 0 6
  • 轉(zhuǎn)發(fā):Redis Cluster探索與思考 Redis Cluster的基本原理和架構(gòu) Redis Cluster...
    meng_philip123閱讀 3,587評(píng)論 0 14
  • NOSQL類型簡(jiǎn)介鍵值對(duì):會(huì)使用到一個(gè)哈希表旋圆,表中有一個(gè)特定的鍵和一個(gè)指針指向特定的數(shù)據(jù),如redis麸恍,volde...
    MicoCube閱讀 3,981評(píng)論 2 27
  • 請(qǐng)求路由 目前我們已經(jīng)搭建好Redis集群并且理解了通信和伸縮細(xì)節(jié)灵巧,但還沒有使用客戶端去操作集群。Redis集群對(duì)...
    達(dá)微閱讀 1,144評(píng)論 0 1
  • 1 Redis介紹1.1 什么是NoSql為了解決高并發(fā)、高可擴(kuò)展采够、高可用肄方、大數(shù)據(jù)存儲(chǔ)問題而產(chǎn)生的數(shù)據(jù)庫(kù)解決方...
    克魯?shù)吕?/span>閱讀 5,291評(píng)論 0 36