Ip hash 和一致性hash的区别与选择(Nginx配置一致性hash)

ip hash 和一致性hash的区别与选择

我们都知道hash(散列)是一种算法,常常用于解决请求命中或者缓存命中的问题,而hash也有一致性hash(consistent_hash)和普通hash(uri_hash ,ip_hash两种,今天我们共同来学习下hash的概念以及这两种hash的区别。

什么是hash

散列算法(Hash Algorithm),又称哈希算法,杂凑算法,是一种从任意文件中创造小的数字「指纹」的方法。与指纹一样,散列算法就是一种以较短的信息来保证文件唯一性标志,这种标志与文件的每一个字节都相关,而且难以找到逆向规律。因此,当原有文件发生改变时,其标志值也会发生改变,从而告诉文件使用者当前的文件已经不是你所需求的文件。

这种标志有何意义呢?之前文件下载过程就是一个很好的例子,事实上,现在大部分的网络部署和版本控制工具都在使用散列算法来保证文件可靠性。而另一方面,我们在进行文件系统同步、备份等工具时,使用散列算法来标志文件唯一性能帮助我们减少系统开销,这一点在很多云存储服务器中都有应用。另外我们web业务有时候需要让同一个用户的请求始终到达一台机器上,这时候就需要hash这个唯一性来标记,还有一个就是Memcache的主要原理也是利用一致性hash来增加缓存的命中率

hash算法的特点

一个优秀的 hash 算法,将能实现:

  • 正向快速:给定明文和 hash 算法,在有限时间和有限资源内能计算出 hash 值。
  • 逆向困难:给定(若干) hash 值,在有限时间内很难(基本不可能)逆推出明文。
  • 输入敏感:原始输入信息修改一点信息,产生的 hash 值看起来应该都有很大不同。
  • 冲突避免:很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。即对于任意两个不同的数据块,其hash值相同的可能性极小;对于一个给定的数据块,找到和它hash值相同的数据块极为困难。

hash有哪些流行的算法

目前流行的 Hash 算法包括 MD5、SHA-1 和 SHA-2。

  • MD4(RFC 1320)是 MIT 的 Ronald L. Rivest 在 1990 年设计的,MD 是 Message Digest 的缩写。其输出为 128 位。MD4 已证明不够安全。
  • MD5(RFC 1321)是 Rivest 于1991年对 MD4 的改进版本。它对输入仍以 512 位分组,其输出是 128 位。MD5 比 MD4 复杂,并且计算速度要慢一点,更安全一些。MD5 已被证明不具备”强抗碰撞性”。
  • SHA (Secure Hash Algorithm)是一个 Hash 函数族,由 NIST(National Institute of Standards and Technology)于 1993 年发布第一个算法。目前知名的 SHA-1 在 1995 年面世,它的输出为长度 160 位的 hash 值,因此抗穷举性更好。SHA-1 设计时基于和 MD4 相同原理,并且模仿了该算法。SHA-1 已被证明不具”强抗碰撞性”。
  • 为了提高安全性,NIST 还设计出了 SHA-224、SHA-256、SHA-384,和 SHA-512 算法(统称为 SHA-2),跟 SHA-1 算法原理类似。SHA-3 相关算法也已被提出。

可以看出,上面这几种流行的算法,它们最重要的一点区别就是”强抗碰撞性”。

普通hash

1.普通hash常见的有 hash $request_uri 、$ip_hash ,前者根据客户端的uri来进行hash计算,后者是根据客户端的ip进行计算。

过程:每个ip,或者uri进行hash 计算得到一个数值,然后用这个数值除以整个节点数量取余

缺点:如果一个节点挂了,被除数发生改变,会导致所有缓存受影响,需要重新计算。

一致性hash

memcache采用的就是一致性hash原理,一致性hash采用的除数不再是节点,而是一个特别大的除数,假设有一个hash环。是个闭环。把32位二进制的整数转换为十进制后均匀分布在整个环上。hash结果是除以2的32次方-1(hash是除以). 那么结果一定是落在环上的。那么,这个点靠近谁,就缓存在谁那里。假设a节点坏了。那么下一次的计算结果就是旁边的邻居。但邻居的缓存不会受到影响。只是坏掉的A节点会从新去缓存。

场景需求:

公司新业务上线,要求需要通过请求的uri进行一致性hash,由于用的nginx做的代理,默认的ip_hash算法是普通hash不合适,所以采用安装第三方模块ngx_http_consistent_hash来根据客户端请求的uri实现一致性hash

安装方式:

1.下载第三方模块:github 下载地址:https://github.com/replay/ngx_http_consistent_hash 

2.重新编译nginx     ./configure  –with以前的模块 –add-module=ngx_http_consistent_hash-master

3.  make  不要make install   然后 将原来的nginx启动文件做备份用于故障回滚,然后拷贝新的nginx 启动文件

4.kill – USR2 <nginx的pid>用于平滑升级

备注: kill -USR1  nginx.pid   等同于 nginx -s reopen 重新读取日志

Nginx配置文件展示:

该模块有多种hash方式常见的有:

  • consistent_hash $remote_addr 可以根据客户端ip映射
  • consistent_hash $request_uri 根据客户端请求的url映射
  • consistent_hash $根据客户端携带的参数进行映射

总结

原生的nginx需要编译第三方模块来实现,但是像tengine 和openrestry基于nginx二次开发的已经默认支持一致性hash了,并且在编译时候可以选择启用还是禁用。

 

 

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Loading...