使用.Net Core实现FNV分布式hash一致性算法
說到FNV哈希算法不得不提Memcached,我們先簡單介紹一下Memcached。
Memcached
Memcached分為客戶端與服務端,Memcached是服務端,服務端本身不提供分布式實現,只是一個單獨的k-v緩存;Memcached的分布式是在客戶端類庫中實現的,也就是說你可以根據自己的需要實現不同的分布式方案,不一定非得使用FNV哈希算法。
Memcached通過FNV算法實現了服務的分布式,并通過引入虛擬節點的辦法盡量是服務器分布的更均勻。已經有很多文章在介紹Memcached的分布式實現原理了,所以我就不那么多廢話了。
FNV分布式hash算法實現
如果你還不了解FNV哈希算法,可以先看一下我之前的文章,在那里我摘錄了wiki上的FNV哈希算法實現公式。
FNV1算法實現
代碼實現上我將參考MD5算法的實現來編寫FNV1算法:
首先,我將創建一個FNV1類,該類需要實現HashAlgorithm,之所以實現HashAlgorithm,是因為該抽象類定義了hash算法通用的接口,這樣也可以使我們的實現與.net框架集成的更好,當然如果你不喜歡也可以不實現HashAlgorithm,就當是寫了一個獨立的幫助類。
然后,我們重寫Create方法,這里我們將創建一個FNV1類的實例
最后,我們去實現這個FNV1類
所有實現代碼如下:
FNV其實還有FNV1a算法,與FNV1有些許的區別,這里我就不一一實現了,你可以參考FNV1的實現和FNV哈希算法來實現FNV1a算法。我有一個幫助類MicroFx.Cryptography分別實現了FNV1和FNV1a的32bit、64bit算法版本。
為什么使用FNV算法實現hash一致性
無論是分布式算法還是hash一致性算法都不只有一種或幾種實現方案,但Memached為什么會選擇FNV算法,而不是md5,不是sha呢?我有自己的認識。
我們先看幾行代碼,分別使用MD5,sha,FNV算法計算一個Test字符串的哈希值,然后對比hash結果中數組的長度
var bytes = Encoding.UTF8.GetBytes("Test");var shabytes = SHA1.Create().ComputeHash(bytes); //shabytes長度為20,及160bitvar md5bytes=MD5.Create().ComputeHash(bytes); ? ?//md5bytes長度為16,及128bitvar fnvbytes = FNV1a.Create().ComputeHash(bytes); //fnvbytes長度為4,及32bit| sha1 | [0,2^160-1] |
| md5 | [0,2^128-1] |
| fnv | [0,2^32-1] |
從上表我們可以看出,FNV的取值范圍最小,如果將區間內的每一個整數看做一個Memcached服務端節點,那么FNV容納的數量最少,但相對于實際的環境下已經足夠多了,這樣我們每次在計算一臺服務器屬于哪個節點的時候速度上會比md5、sha1快很多。
FNV的32bit計算結果值剛好是一個uint類型,.net core最大支持ulong也就是uint64,再大的話就需要我們自己實現,所以這也是選擇FNV的一個原因。(或許我這里不應該拿.net舉例,但實際常用的高級語言最大也是64bit)
原文地址:https://www.cnblogs.com/guodf/p/9681543.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的使用.Net Core实现FNV分布式hash一致性算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IdentityServer4实战 -
- 下一篇: asp.net ajax控件工具集 Au