首页 > 编程知识 正文

哈希算法原理和用途,一致性hash算法 java

时间:2023-05-04 05:23:46 阅读:165395 作者:2782

1、一致性哈希算法的经典使用场景在数据库存储空间中单表数据量较大时,通常采用分库表。 缓存区域也同样需要库。 以下,以非常一般的Redis库体系结构为例进行说明。

将上述三个Redis节点称为片,各节点需要存储数据的一部分,使用负载平衡算法尽量将数据分布在各节点上,充分利用分布的优势,提高系统缓存访问的性能。

在分布式缓存区域中,数据中存在新的和查询。 这意味着,在数据通过路由算法存储到一个节点后,查询应该尽量路由到同一个节点。 否则,查询可能不会命中缓存。这也是与分布式服务调用领域的负载算法一个不同点。

分布式高速缓存类空间负载平衡算法通常使用字段分片键,在加载之前,先求出与分片字段对应的HashCode,然后将其建模为当前节点数。即 hashcode(分片键) % 节点总数(分片总数)

1.1分布式缓存区域中上述算法的弊端lhdbg重取魔可以简单有效地实现,但分布式缓存区域中存在致命的痛点,对缩放不友好,降低了缓存命中率。

以下是扩展导致的数据命中率问题。

例如,当前集群中存储有3个节点,例如当前集群中写入6个数据,其分片密钥的hashcode为1-6,数据的分布如上所述,但随着业务的急剧增加,3台redis可以满足业务的需求此时,项目组决定去缓存找k1,k2,k3

根据hashcode重取方式,由于数量从3台到4台,用算法路由后,k4试图从3.169的机器上寻找,但对应的数据存储在3.166中,上面6个key的命中占50%

上述问题的第一个解决方案:缓存穿透将原始三个节点的数量加倍,新添加的第一台数据来自第一台,同样,第六台数据来自第三台。 这样,k6经过新的负载平衡算法落入第6台。 数据原本存在于第3台,第6台的数据来源于第3台。 这避免了成倍扩容

缓存穿透,还有其他更好的方法吗?

一致性哈希算法问世。

1.2一致性哈希算法一致性哈希算法是1997年麻省理工学院的Karger等人在解决分布式缓存时提出的,以解决互联网上的热点问题为目标,与CARP非常相似。 一致性散列修正了CARP使用的简单散列算法带来的问题,使DHT可以在P2P环境中实际应用。

但是,目前一致的hash算法在分布式系统中也得到了广泛的应用,研究memcached缓存数据库的人都知道memcached服务器端本身并不提供分布式缓存的一致性,而是在客户端提供具体来说,在计算一致的散列时采用以下步骤。

首先求出memcached服务器(节点)的散列值,将其配置到0(232的圆(continuum )中。 然后用同样的方法求出存储数据的密钥的哈希值,映射在同一圆上。 然后,从数据映射到的位置开始顺时针搜索,并将数据保存到找到的第一个服务器。 如果超过232仍找不到服务器,则将其保存在第一个memcached服务器上。

整个空间按顺时针方向组织。 0和232-1在零点的中方向重合。

然后,每个服务器对散列使用Hash。 具体来说,它使用服务器的ip地址或主机名作为密钥进行散列,以便每台计算机可以在散列上定位。 在此,假设上述4台服务器使用了ip地址散列后,在环形空间上的位置如下。

然后,使用以下算法确定数据并访问相应的服务器。 使用相同的函数Hash计算数据key的哈希值,以确定该数据在环上的位置。 从这个位置沿着环顺时针“走”,第一个遇到的服务器就是应该确定其位置的服务器。

例如,有四个数据对象: Object A、Object B、Object C和Object D。 经过散列计算,环空间上的位置如下。

通过一致性哈希算法,数据a被决定为节点a,b被决定为节点b,c被决定为节点c,d被决定为节点d。

分析一致性哈希算法的容错性和可扩展性。 现在,如果Node C不幸瘫痪的话,这时对象a、b、d没有受到影响,可以知道只有c对象被重新配置在Node D上。 一般来说,对于一致性哈希算法,如果一台服务器不可用,则受影响的数据只是该服务器与环路空间中的上一台服务器(即第一个逆时针行走遇到的服务器)之间的数据,其他不受影响。

考虑向系统中添加服务Node X的情况,如下图所示。

在这种情况下,对象Object A、b和d不受影响,只有对象c需要重新定位到新的Node X。 一般来说,在一致性哈希算法中,

如果增加一台服务器,则受影响的数据仅仅是新服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它数据也不会受到影响。

综上所述,一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。

另外,一致性哈希算法在服务节点太少时,容易因为节点分部不均匀而造成数据倾斜问题。例如系统中只有两台服务器,其环分布如下,

此时必然造成大量数据集中到Node A上,而只有极少量会定位到Node B上。为了解决这种数据倾斜问题,一致性哈希算法引入了虚拟节点机制,即对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点。具体做法可以在服务器ip或主机名的后面增加编号来实现。例如上面的情况,可以为每台服务器计算三个虚拟节点,于是可以分别计算 “Node A#1”、“Node A#2”、“Node A#3”、“Node B#1”、“Node B#2”、“Node B#3”的哈希值,于是形成六个虚拟节点:

同时数据定位算法不变,只是多了一步虚拟节点到实际节点的映射,例如定位到“Node A#1”、“Node A#2”、“Node A#3”三个虚拟节点的数据均定位到Node A上。这样就解决了服务节点少时数据倾斜的问题。在实际应用中,通常将虚拟节点数设置为32甚至更大,因此即使很少的服务节点也能做到相对均匀的数据分布。

2、一致性hash的应用

Dubbo中为了实现客户端在服务调用时对服务提供者进行负载均衡,官方提供了一致性哈希算法;

RocketMQ集群消费模式时消费队列的负载均衡机制也实现了一致性哈希算法

使用场景:分布式缓存负载均衡,特别是突出扩容、缩容能有效避免缓存穿透的问题。同时需要阐述一致性哈希算法的缺陷以及其应对策略(虚拟节点)。

参考文章:

https://mp.weixin.qq.com/s/Ti2AA5AKXzt6Fnqn2pXiwg

https://www.cnblogs.com/williamjie/p/9477852.html

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。