1. 程式人生 > 實用技巧 >一致性Hash(基於google Guava實現)

一致性Hash(基於google Guava實現)

背景

一般我們使用的hash就是md5 sha 之類的工具類,在負載均衡會要求類似同一個ip在增加節點時還是定位到之前的節點,這時就要用到一致性hash。具體實現程式碼參考(基於google Guava):

使用谷歌 Guava 實現 Java 一致性雜湊 (用於根據雜湊Hash值平均分配的場景)​my.oschina.net

一、介紹

MurmurHash演算法:高運算效能,低碰撞率,由Austin Appleby創建於2008年,現已應用到Hadoop、libstdc++、nginx、libmemcached等開源系統。2011年Appleby被Google僱傭,隨後Google推出其變種的CityHash演算法。

Java界中Redis,Memcached,Cassandra,HBase,Lucene都用它。

在Java的實現,Guava的Hashing類裡有,上面提到的Jedis,Cassandra裡都有Util類。

但存在的問題是由於Java的資料型別long與C語言中無符號長整型uint64_t有區別,導致Java輸出版本存在負數,針對這個問題進行了修改;另外需要注意的是中文不同編碼(UTF-8或GBK)會導致輸出結果的不同,使用中需要統一編碼。

p.s.一致性hash的實現演算法,murmurhash和ketamahash。下面這篇文章有詳細的說明。

淺析ketamahash和murmurhash - 程式詩人 - 部落格園​www.cnblogs.com

二、原理

演算法圖例

三、效能測試對比

import java.nio.charset.StandardCharsets;
import org.apache.commons.codec.digest.DigestUtils;
import com.google.common.hash.Hashing;
 
public class Test {
 
	public static void main(String[] args) {
		
		System.out.println(murmur3Test("334324324234234sfsfsdfwwrtregreg"));
		
		 long startTime=System.currentTimeMillis();
		 for (int i = 0; i < 10000000; i++) {
			 Test.md5Test("KFETHGRETWERFSDFWEFWEFWF");
	     }
	     long endTime=System.currentTimeMillis();
	     System.out.println("1000萬次md5Test演算法程式執行時間: " + (endTime - startTime ) + "ms");
	     
	     long startTime2=System.currentTimeMillis();
		 for (int i = 0; i < 10000000; i++) {
			 Test.murmur3Test("KFETHGRETWERFSDFWEFWEFWF");
	     }
	     long endTime2=System.currentTimeMillis();
	     System.out.println("1000萬次murmur3Test演算法程式執行時間: " + (endTime2 - startTime2 ) + "ms");
		
	}
	
	public static String murmur3Test(String primaryKey) {
        return Hashing.murmur3_32().hashString(primaryKey, StandardCharsets.UTF_8).toString() + 
            "_" + primaryKey;
    }
	
	public static String md5Test(String primaryKey) {
	        return DigestUtils.md5Hex(primaryKey)+ "_" + primaryKey;
	}
 
}


結論:

MurmurHash演算法比md5快一倍。

四、使用場景

1、根據uuid,通過hash演算法進行取模分庫分表

2、用來計算出key的slot值

3、短連結

五、其他演算法

ketamahash一致性雜湊演算法

由若干固定的虛擬節點來計算出每個虛擬節點的slots,資料儲存的時候,算出key的slot值,然後存入相鄰最近的虛擬節點

轉載
hash函式MurmurHash_luoqinglong的專欄-CSDN部落格​blog.csdn.net