Guava 中的一致性哈希

之前寫過一篇博客分析了一致性哈希,最近發現在Guava中有一個Hashing類簡單實現了一個一致性哈希的算法。

它使用起來非常簡單,里面有一個consistentHash()靜態方法


int bucket = Hashing.consistentHash(id, buckets) // bucket 的范圍在 0 ~ buckets 之間

傳入數據主鍵id(分片片鍵)和集群中機器數量buckets,返回一個固定的數字,表示數據應當落在第幾個機器上。

而這個方法內部實現也非常簡單:

public static int consistentHash(long input, int buckets) {
    // 檢查
    checkArgument(buckets > 0, "buckets must be positive: %s", buckets);
    // 利用內部的LCG算法實現,產生偽隨機數
    LinearCongruentialGenerator generator = new LinearCongruentialGenerator(input);
    int candidate = 0;
    int next;

    // Jump from bucket to bucket until we go out of range
    while (true) {
        // generator.nextDouble() 產生偽隨機數
        // 每次hash的循環中每一個的next的值總是會固定 :
        // 比如:
        //      hash 1 round 1 -> 9  hash 2 round 1 -> 9
        //      hash 1 round 2 -> 7  hash 2 round 2 -> 7
        //      hash 1 round 3 -> 2  hash 2 round 3 -> 2
        next = (int) ((candidate + 1) / generator.nextDouble());

        if (next >= 0 && next < buckets) {
            //  如果在 0 到 bucket 范圍之外, 將這個next值賦值給candidate,重新計算
            candidate = next;
        } else {
            //  如果在 0 到 bucket 范圍之內, 就返回這個 candidate 值,作為 input數據存儲的槽
            return candidate;
        }
    }
}

// LCG偽隨機數的算法實現,關于LCG的解釋可以參考 http://en.wikipedia.org/wiki/Linear_congruential_generator
private static final class LinearCongruentialGenerator {
    private long state;

    public LinearCongruentialGenerator(long seed) {
        this.state = seed;
    }

    public double nextDouble() {
        state = 2862933555777941757L * state + 1;
        return ((double) ((int) (state >>> 33) + 1)) / (0x1.0p31);
    }
}

通過Guava的這個方法,我們就可以輕松地在項目中使用一致性哈希了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容