1

我们正在使用针对 2 节点 redis 部署运行的 ServiceStack.Redis 客户端。

我们注意到方法:ServiceStack.Redis.Support.ConsistentHash.AddTarget 使用以下代码将节点映射到圆上:

字符串标识符 = node.GetHashCode().ToString() + "-" + i;

在这种情况下,节点的类型为 ShardedConnectionPool,GetHashCode 被覆盖为:

返回名称.GetHashCode();

我认为这有问题:

首先,GetHashCode 结果不能保证在不同的部署中是相同的。来自http://msdn.microsoft.com/en-us/library/system.string.getashcode.aspx

“哈希码本身不能保证是稳定的。相同字符串的哈希码可能因 .NET Framework 版本和单一 .NET Framework 版本的不同平台(例如 32 位和 64 位)而异”

分片的影响相当严重,因为在稍微不同的实例上运行的客户端会以不同的方式映射键。

其次,GetHashCode() 被其他类(例如 Dictionary)所依赖,这种实现可能会导致一些问题。围绕 GetHashCode 有许多要求,例如“覆盖 GetHashCode 的派生类也必须覆盖 Equals 以保证被认为相等的两个对象具有相同的哈希码;否则,Hashtable 类型可能无法正常工作。”

我想这样做的目的是对 in 中的“节点”类型没有额外的限制,但是在上面给出的情况下,要求类实现一个接口,该接口提供应该形成键的字段的方法可能会更清晰。

作为快速修复(我们实际上遇到了这个问题),我们只是重写了 ToString() 方法以返回名称并调整了 AddTarget 方法。

想法?

4

0 回答 0