从分库分表的业务来讲,需要根据某个key
将数据分散到N个数据表中,该做法有2种类型。
第一个方法:很显然当N变动的时候,原始取模的做法存在数据抖动很大,但是如果采用一致性hash,当数据表有变更的时候,抖动会很小。
第二个是一致性Hash,那么他的原理是什么?简单来说:
2^32
次方想象为组成圆环上的刻度2^32
次方取模代码参考如下,假如有2W条数据插入5个、6个 数据表,可以很明显的对比出,传统的取模抖动是一致性hash的6倍。
fun main() {
consistentHash1()
normalHash()
}
/**
* 28103
*/
private fun consistentHash1() {
val hash1 = ConsistentHash(20, listOf("1", "2", "3", "4", "5"))
val map1 = (1..200000).associateWith { hash1.get(it) }
val hash2 = ConsistentHash(20, listOf<String>("1", "2", "3", "4", "5", "6"))
val map2 = (1..200000).associateWith { hash2.get(it) }
val size = (1..200000).count { map1[it] != map2[it] }
println("一致性Hash 不同的size为:${size}")
}
/**
* 166666
*/
private fun normalHash() {
val map1 = (1..200000).associateWith { it.hashCode() % 5 }
val map2 = (1..200000).associateWith { it.hashCode() % 6 }
val size = (1..200000).count { map1[it] != map2[it] }
println("取模 不同的size为:${size}")
}