我们正在使用针对2节点redis部署运行的ServiceStack.Redis客户端。
我们注意到了方法:ServiceStack.Redis.Support.ConsistentHash.AddTarget 使用以下代码将节点映射到圆上:
string identifier = node.GetHashCode()。ToString()+“ - ”+ i;
在这种情况下,节点的类型为ShardedConnectionPool,其中GetHashCode被覆盖为:
返回name.GetHashCode();
我认为这有问题:
首先,不能保证GetHashCode结果在部署中保持一致。来自http://msdn.microsoft.com/en-us/library/system.string.gethashcode.aspx
“哈希代码本身不能保证稳定。相同字符串的哈希代码可能因.NET Framework版本和跨平台(例如32位和64位)的单个版本而异。 NET Framework“
分片的含义相当严重,因为在不同的实例上运行的客户端会以不同的方式映射密钥。
其次,其他类(例如Dictionary)依赖于GetHashCode(),这种实现可能会导致一些问题。 GetHashCode有很多要求,例如 “覆盖GetHashCode的派生类也必须重写Equals以保证两个被认为相等的对象具有相同的哈希码;否则,Hashtable类型可能无法正常工作。”
我想,目的是对“节点”类型没有额外的限制,但是如上所述,要求类使用提供应该形成键的字段的方法来实现接口可能更清晰。
作为一个快速修复(我们实际遇到了这个问题),我们只是重写了ToString()方法以返回名称并调整了AddTarget方法。
思想?