什么是hash算法?
把不规则的二进制数据转换成固定长度的二进制映射,这个固定长度的二进制映射就是hash值
原始hash取值规则
存值快,取值慢 原始hash不知道集合中的序号,所以取值的时候需要从头到位的遍历,时间复杂度位O(n+1)/2
Map的hash计算规则
存值慢,取值快 Map的hash算法改良了上面的存储规则是,key.hashCode/list.length 表示下标,如果一旦修改元素后就需要重新组排顺序(rehash)
redis的一致性hash算法
- 在redis3.0 之后集群的概念才很明显。 它先将hashcode 在 0 到2^32之间的值做成了一个环形的结构。
- 在集群环境中改动了机器和产生意外宕机时候,数据就会按照顺时针顺序进行数据的 rehash,而不需要进行全量的rehash
- 为了满足平衡性,redis会做一些虚拟映射,而不实际存储数据。
概念性内容:
一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义
- 平衡性(Balance):
平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。 - 单调性(Monotonicity):
单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。 - 分散性(Spread):在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。
- 负载(Load):负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同 的内容。与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷。