普通hash与一致性hash算法
hash算法是一类算法,不是某一个算法。
一、普通hash算法(求模)
hash查找:相对于顺序查找
和二分查找
,查找速度快。
对数据求模,根据余数确定存储下标,可能导致hash冲突
,有两种方式解决:每个下标存放一个数组或者一个链表,hash查找的效率直接决定于hash算法
应用场景
分布式集群架构如Redis、Hadoop、Elasticsearch、Mysql分库分表、Nginx负载均衡
。
请求负载均衡(nginx的ip_hash,是处理session共享的一种方式)
对ip或sessionId计算hash值,对服务器数量取模,得到路由后的服务器编号。这样可以保证同一个客户端发送来的请求被路由到指定的服务器上。
redis负载均衡也是同样,先对key进行hash计算,将得到的结果作为目标服务器的id。
普通hash算法(线性结构)存在的问题
在服务器扩容、缩容时,导致服务器原来的客户端请求需要重新hash计算
二、一致性hash算法
普通hash算法的问题可以由一致性hash算法解决
一致性hash算法(环形结构)
:服务器扩容/缩容后,只影响一部分请求,重新计算服务器节点hash值(客户端和服务器ip经过hash计算后都会落在一个hash环上,客户端请求会被分发到顺时针离他最近的服务器上)
以上可以得知,一致性hash算法对分布式集群来说是非常合适的,避免了服务器扩容和缩容后大量的请求迁移。
1、什么是数据倾斜?
然而,环形结构有利有弊,分布式集群节点越多,请求越能够均匀分布到服务器上。如果只有两台服务器,就有可能会造成数据倾斜
,即大量请求落在指定的一台服务器上,这时需要引入虚拟节点
,一个服务器设置n个虚拟节点,这样hash环被虚拟节点均匀分割,请求也会均匀分配到服务器集群中。
2、nginx配置一致性hash
通过upstream中配置ip_hash;
由于处理服务器扩容缩容后会引发大量请求迁移问题,nginx负载均衡建议使用一致性hash算法
来配置,使用该模块需要下载并安装到nginx中,
1)下载
https://github.com/replay/ngx_http_consistent_hash
2)安装
找到nginx的configure脚本执行以下命令行
./configure —add-module=/root/ngx_http_consistent_hash-master
make && make install
3)修改upstream配置
upstream myServer {
#请求url
consistent_hash $request_uri;
#consistent_hash $remote_addr;请求ip
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}