Skip to content
xiaoyu.zhang edited this page Jul 14, 2020 · 1 revision

Welcome to the ConsistentHash wiki!

1. 什么是缓存

缓存Cache0和缓冲Buffer的区别?

都是加快速度的。 缓存:通过多次读取,加快访问速度。 缓冲:处理cpu和网卡或磁盘,速度不匹配的,提高读写性能。

分布式和集群的区别?

集群是分布式的子集,多个相同节点构成的分布式,就是集群。

Tip: 没有哪一个技术是万能的,使用的干净利落一点。

缓存是允许不命中的。redis为什么不设置缓存永久有效。答案是:扩容

集群中有3个节点,当增加一个节点Node3,会有1/4的数据匹配到Node3上,导致命中不到,经过访问后,加载到Node3上。原先存储在Node1上的数据key0、key1会过期删除。如果永久有效的话,则会一直存在集群当中成为僵尸数据。

一致性哈希算法

hash的缺点是扩容导致数据失效。 分析:

  1. hash是对节点数进行余数取模,之所以导致失效就是节点数改变了。
  2. 想办法对固定值取模,3、4个节点都太小了,干脆搞一个几乎不可能达到的集群规模,以后不管加多少台机器,key始终都对这个值取模,得到的结果就是一致的,名曰:一致性哈希。实际上hash值有2^32(4个字节的大小),使用此值就不用取模了。
  3. 经过以上算法,同一个key不管集群数如何变化,hash后的结果始终固定一致。问题是,hash结果又2^32种结果,但真实的服务器只有几台,如何匹配存储,答案是对服务器也进行2^32取模,key和服务器都在一个环上,然后离那个近就存哪里。名曰hash环
  4. 最后回到集群伸缩的问题上来,当增加或减少一台机器,唯一的就是导致一小部分数据的失效而已,不影响整体。
  5. 扩展思维:理想情况我们希望真实服务器能均匀的散落在hash环上,这样就能避免数据倾斜导致热点问题和访问压力不均衡问题了。怎么办?
  6. 答案就是:把1台真实节点,编程200个虚拟节点(server1-1, server1-2,.... server1-200),经过hash算法,相对均匀的散列在环的不同位置上。
  7. 最后说下redis的实现: redis集群预先分好16384个桶,也叫solt槽,每个服务器都分配一些桶。当有新机器添加时,可以从其他机器分一部分桶过来。redis的hash算法是CRC16(key),当有key-value要存储,通过CRC16(key)%16384一致性hash计算后,得到桶,然后根据桶的分配,知道在哪个服务器。reids是服务器端负载均衡,每一台机器之间都相互感知对方的存在,所以集群中只要连接到一台机器,就能顺利的存储读取数据。

重点知识答疑

热点key怎么办?

某一个key超过访问量,对缓存服务器构成压力。解决办法:本地缓存,缓存到每一台jvm中。

hash环为什么是2^32?

hash环上是放hash值的,hashcode本身就是2^32这么大。

原生的一致性hash算法还需要取模吗?

不需要,因为2^32

不同的类有不同的hashcode实现,但返回值都是int,int是4个字节,也就是2^32方能标识的范围,有正有负。

“散列算法”和就“摘要算法”,是一个概念

散列:如hashcode、CRC16、CRC32 其中hashcode不是固定长度,可以0可以-1287798718,但是"一定长度",小于2的32次方。目的是在某个区间内均匀分布。

摘要:如MD5,始终是固定的长度, 做数字签名用的。目的是保证不可逆,

我们作业【实现一致性哈希算法】:数据的散列程度完全由,散列函数来决定的,可以是hashcode,也可以是redis用的CRC16,您说您有更牛的标准差,难道是您实现了更牛的散列算法?

作业:

1,用你熟悉的编程语言实现一致性hash算法。 2,编写测试用例测试这个算法,测试100万KV数据, 10个服务器节点的情况下,计算这些KV数据在服务器上分布数量的标准差,以评估算法的存储负载不均衡性。

Clone this wiki locally