2011-07-14 21 views
0

我需要跨N個節點的分佈式緩存平分數據。分區數據的Hash函數

下面的代碼將採取緩存鍵和確定使用哪個節點:

public static int GetNodeIDByCacheKey(string key) 
{ 
    return Math.Abs(key.GetHashCode()) % TotalNumberOfNodes(); 
} 

不幸的代碼是不是在不同的機實例可靠。 在測試中,它似乎有時會爲相同的密鑰返回不同的節點。

上得到的東西更好地工作,任何想法或意見?

+0

所以你聲稱的'key'的按位相同的值,你會得到不同的函數結果? – 2011-07-14 03:55:15

+0

它是什麼我目前懷疑的是我通過 –

+1

可能重複工作的問題[GetHashCode()方法提供了不同的服務器上不同的結果?](http://stackoverflow.com/questions/6114772/gethashcode-gives-不同-成果上不同的服務器) –

回答

3

除了相等值的字符串會產生相同的哈希碼這一事實之外,您不應該依賴於stringGetHashCode()的實現 - 但是哈希碼的特定值將只需要與每documentation用於應用的當前執行 - 可以應用程序是否再次運行返回不同的散列碼。

同樣的GetHashCodemight be different實施,如果你有問題的機器上不同的.NET CLR版本:

的GetHashCode的行爲取決於它的實現,這 可能會從普通的一個版本中改變語言運行時到 另一個。這可能發生的原因是爲了提高GetHashCode的性能 。

相反,你可以只定義從您的字符串鍵始終映射成一個數值,這將讓你斌您的跨重新啓動和機器邊界一致的節點,這即可以由字符串轉換成字節數組實現(即使用Encoding.UTF8.GetBytes()),然後將字節數組轉換爲數字(使用僅使用64位的有損轉換或即使用BigInteger

+0

我讀這上運行的Web角色的兩個實例,但我遇到了在Azure的開發環境這個問題(同一web.role的兩個實例) –

+0

@Andrew:你自己定義一個映射到你的字符串鍵的數字值不應該太難,總會有衝突,但你必須能夠保證相同的字符串值將始終映射到同一個bin – BrokenGlass

2

特定實例(實例化的字符串)將生成相同的哈希,但兩個實例(例如在機器A和機器B上)相同的字符串(例如「Hello」)很可能具有不同的hashCode。我認爲如果你想在機器和實例之間進行相同的操作,你將需要實現自己的散列函數,該函數只使用字符串的內容。