Hash
Hash 原意为:n. 剁碎的食物,肉丁,vt. 把...弄乱,切碎...
在计算机应用中称为散列函数, 或者直接音译为哈希。就是把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。
特点:
hash的主要原理就是将大范围的二进制文件通过hash算法映射到较小的杂乱的hash码中保存。在相同的算法下,相同的二进制文件的hash值相同,而不同的二进制文件(即便是只有一丁点的不同)经过hash算法都会产生截然不同的hash值。
Hash函数逼近单向函数,所以可以用来对数据进行加密。(单项函数:如果某个函数在给定输入的时候,很容易计算出其结果来;而当给定结果的时候,很难计算出输入来)。不同的应用对Hash函数有着不同的要求:用于加密的Hash函数主要考虑它和单项函数的差距,而用于查找的Hash函数主要考虑它映射到小范围的冲突率。
Hash 的算法不在此处列出,可参考链接:https://www.cnblogs.com/coder2012/p/3954736.html (感谢博主的分享)
一致性Hash 算法:
一致性hash算法设计的目的解决互联网中的热点问题,但是现在在分布式系统中得到了广泛的应用。在使用一致性hash算法之前,分布式系统在解决资源存储的负载均衡时是通过将资源的hash值对系统的服务器数量取模,然后在决定将资源缓存到哪一台服务器当中。当用户访问资源的时候,也通过资源的hash值取模查找该资源缓存于哪一台服务器,然后再区对应的服务器取出资源即可。
在系统服务器数量不变且不考虑服务器异常或崩溃的情况下,一般情况这种方法没有问题。但是如果所需要的缓存任务量激增,造成某台服务器崩溃的情况,就会出现严重的问题。
假设一个分布式系统中有3台服务器A(编号0), B(编号1),C(编号2) ,3台服务器中分别缓存有名为1、2、3、4、5、6的图片资源。 那么6张图片资源中,1、4号图片资源存放于B服务器,2、5号图片资源存放于C服务器,3,6号图片资源存放于A服务器。在添加服务器之前,用户访问2号图片资源,则2%3=2,需要到编号为2的服务器C上查找资源,而2号图片也存储与C服务器上,能够找到该资源。
现在由于大量用户同时访问4号图片,造成服务器C崩溃,此时有一个用户再次访问图片2, 则2%2 = 0; 系统判定用户需要去0号服务器A中寻找资源,则无法找到该资源。此时整个系统的资源与路径将无法对应,系统要达到正常访问的目的必须重新缓存资源,从而造成资源的极大浪费,甚至造成整个系统的雪崩。
也就是说这种缓存方法的问题在于:
当服务器数量发生变化的时候,会导致几乎所有的缓存资源同时失效,必须重新缓存,此时几乎所有资源的位置将会发生改变,系统资源造成极大浪费,甚至可能会引起整个系统压力过大而集体崩溃。
一致性Hash算法则很好地解决了这个问题。
一致性hash算法通过计算分布式系统的每个服务器的hash值,将服务器散列到一个0-2^32-1的hash环上。当需要有资源缓存的时候,计算缓存资源的hash值,根据hash值,将资源映射到hash环上,并将该资源沿着顺时针的方向映射到离该资源hash值最近的服务器中。需要访问资源的时候,计算要访问的资源的hash值,然后根据hash值到hash环上查询其映射的服务器即可。
当hash环上某台服务器崩溃时,系统会到该台服务器的下一台服务器中去查找资源(没有资源),则下一台服务器会重新缓存原崩溃的服务器所缓存的资源,而其他服务器并不重新缓存。这样就解决了一台服务器崩溃整个系统缓存资源失效的问题。
当然这个方法还是有一个缺点就是当少数的服务器集成一个分布式系统的时候,可能会造成的hash偏移问题(服务器集中在hash环的某一段,而其他很大一段空间上没有服务器的情况,这种情况会造成大段连续空间的下一台服务器压力倍增)。解决这个问题的方法是为每一台服务器虚拟出若干的虚拟服务器节点并挂载到hash环上,从而解决此问题。关于一致性hash算法的详细点不再此处罗列。此文仅限于应对简单面试。
若想进一步了解,请参考博文:http://www.zsythinkf.net/archives/1182 (感谢朱双印的分享:http://www.zsythink.net/)