Jedis下的ShardedJedis(分布式)使用方法(二),jedisshardedjedis

來源:互聯網
上載者:User

Jedis下的ShardedJedis(分布式)使用方法(二),jedisshardedjedis

上一篇中介紹了ShardedJedis的基本使用方法以及示範了一個簡單的例子,在這一篇中我們來介紹了ShardedJedis的原理。

 

1.ShardedJedis內部實現

首先我們來看一下ShardedJedis的一個繼承關係

 

看完了圖,那麼我們一步一步跟著我們的代碼調用來看,以我們最簡單的 ShardedJedis.get(key)方法為例:

  public String get(String key) {    Jedis j = getShard(key);    return j.get(key);  }

 

這邊有調用一個getShard 方法,參數為我們傳入的key,然後返回一個普通的jedis對象,那麼這個getShard是用來做什麼的呢,大家可能已經猜到了,這個方法就是會根據我們傳入的key做一致性雜湊判斷,然後返回key落到的那個redis執行個體上的一個redis串連,不同的key返回的redis串連可能是不同的。

 

進入getShard 方法,你會發現這個實現是在Sharded類中實現的(看上面的類圖可以發現頂層的Sharded類),代碼如下:

public R getShard(String key) {    return resources.get(getShardInfo(key));  }  public S getShardInfo(byte[] key) {    SortedMap<Long, S> tail = nodes.tailMap(algo.hash(key));    if (tail.isEmpty()) {      return nodes.get(nodes.firstKey());    }    return tail.get(tail.firstKey());  }  public S getShardInfo(String key) {    return getShardInfo(SafeEncoder.encode(getKeyTag(key)));  }

 

上面的方法是層層調用的關係,在這邊不細說,我們主要看下第二個方法(getShardInfo(byte[] key))實現(上面的nodes變數是一個TreeMap 類型, algo Hashing類型,即key分區所使用的hash演算法,這個在前一篇有簡單說過),那麼這段代碼的含義我們大概成猜出來了,

 

那麼這個S R對象各自代表什麼呢?看下面的代碼

public class Sharded<R, S extends ShardInfo<R>>
public class BinaryShardedJedis extends Sharded<Jedis, JedisShardInfo> implements    BinaryJedisCommands

可以得出  S = JedisShardInfo, R = Jedis 對象,即在TreeMap儲存了伺服器劃分的虛擬節點的資訊,LinkedHashMap中儲存了伺服器的物理串連。 

 

JedisShardInfo具體資訊如下:裡麵包含了jedis伺服器的一些資訊,最重要的是它的父類中有一個weight欄位,作為本jedis伺服器的權值。

ShardedJedis去查一個key時,首先它會把這個key進行一個hash演算法

  • 根據這個hash值然後去treeMap中,查出這個key落在哪個執行個體中,並返回redis執行個體對應的具體資訊
  • 根據這個redis的執行個體資訊,到一個儲存jedis連結和執行個體資訊對應關係的LinkedHashMap中找到這個jedis串連
  • 最終返回jedis串連,執行對象的命令操作(到這步後實際上和單機操作一樣了)
  • 那麼我們的nodes 伺服器虛擬節點和resources 伺服器物理串連是什麼時候初始化的呢,接下來繼續看

     

    2.redis虛擬節點(nodes)和物理串連(resources) 初始化

    我們繼續看Sharded的構造方法

    public Sharded(List<S> shards, Hashing algo) {    this.algo = algo;    initialize(shards);  }public Sharded(List<S> shards, Hashing algo, Pattern tagPattern) {    this.algo = algo;    this.tagPattern = tagPattern;    initialize(shards);  }

     

    這邊有一個initialize方法,就是用來對虛擬節點和物理串連進行初始化的,看其實現

    private void initialize(List<S> shards) {    nodes = new TreeMap<Long, S>();    for (int i = 0; i != shards.size(); ++i) {      final S shardInfo = shards.get(i);      if (shardInfo.getName() == null) for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {        nodes.put(this.algo.hash("SHARD-" + i + "-NODE-" + n), shardInfo);      }      else for (int n = 0; n < 160 * shardInfo.getWeight(); n++) {        nodes.put(this.algo.hash(shardInfo.getName() + "*" + shardInfo.getWeight() + n), shardInfo);      }      resources.put(shardInfo, shardInfo.createResource());    }  }

     

    具體細節就不說了,根據上面的,我們就知道是在這邊進行了初始化,將每台伺服器節點採用hash演算法劃分為160個虛擬節點(可以配置劃分權重),儲存在TreeMap中,

    然後把每台伺服器節點的資訊和物理串連以索引值對儲存LinkedHashMap中。

     

    然後通過一系列的尋找,發現Sharded的構造方法其實是在我們 jedisPool.getResource() 時就完成的

      //初始化ShardedJedisPool        List<JedisShardInfo> infoList = Arrays.asList(shardInfo1, shardInfo2, shardInfo3);        ShardedJedisPool jedisPool = new ShardedJedisPool(poolConfig, infoList);        ShardedJedis jedis = jedisPool.getResource();

     

     

    納尼? 每次jedisPool.getResource() 才初始化?那會不會造成很慢呢,其實不用擔心,其底層是使用了commons.pool來進行串連池的一些操作,會根據我們配置的串連池參數來產生對應的串連並儲存,其中的細節很複雜,博主沒有繼續深究,實現其實和資料庫連接池是一致的。

     

    3.總結

     

    ShardedJedis分布式具體的的實現思路:

     
    • redis伺服器節點劃分:將每台伺服器節點採用hash演算法劃分為160個虛擬節點(可以配置劃分權重)

    • 將劃分虛擬節點採用TreeMap儲存

    • 對每個redis伺服器的物理串連採用LinkedHashMap儲存

    • 對Key or KeyTag 採用同樣的hash演算法,然後從TreeMap擷取大於等於鍵hash值得節點,取最鄰近節點儲存;當key的hash值大於虛擬節點hash值得最大值時,存入第一個虛擬節點

    • sharded採用的hash演算法:MD5 和 MurmurHash兩種;預設採用64位的MurmurHash演算法;

     好了,大概的實現如上面所說的,都是圖可能會有點亂,大家如果有什麼問題或者發現了什麼錯誤,please tell me!

     

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.