哈希算法在分布式系统中有哪些应用
哈希算法应用之负载均衡
负载均衡的算法有很多,诸如:轮询,随机,加权轮询等等。哈希算法可以帮助我们实现一个会话粘滞的负载均衡算法。会话粘滞:让同一个客户端每次请求访问的时候,固定的访问某台服务器。
简单直接的方法:维护一张客户端与服务端映射关系的表。每次客户端发起请求的时候,从映射表中查找到映射关系,再路由到对应的服务端。但是这种方法存在下面几种弊端:1,如果客户端数量增加,那么势必造成这张关系表数据庞大,浪费内存空间。2,客户端上线下线,需要我们不断维护关系表的数据,不断地扩容缩容,维护成个变大。
优化的方法:针对客户端的 IP 或者是会话的 ID 哈希求值,然后在与服务端服务器个数求膜运算,最终得到的数字,就是该客户端需要路由到的服务器编号。这样我们就是保证了固定客户端发送的请求,会访问固定的服务器。
哈希算法应用之数据分片
举例一:统计 “搜索关键词” 的次数。
如果我们有 1T 的搜索日志文件,想要对其中搜索关键词出现的次数进行统计,必须要考虑到下面两个难点:文件过大无法放入一台机器内存中,只用一台机器处理这么多的数据效率肯定很低。
为了解决上述两个难点,提供如下思路:先利用哈希算法对数据分片,然后采用多机器处理,提高效率。假设要用 n 台机器处理,依次读取文件中的搜索关键。关键词哈希求值,然后将哈希值与 n 求模得 x,x 就是 n 台机器中某个机器的编号,将该搜索关键词交由编号为 x 的机器统计次数。
这样下来,相同的搜索关键词哈希值相同,所以会被放在同一台机器上做统计。最终,将多台机器的统计结果汇总,就得出问题最终结果。
举例二:快速判断图片是否在图库中
上篇总结中,快速查找图片是基于图片的二进制串哈希求值,然后放入哈希表中,实现快速查找。如果图片数量过大,比如说 1 亿张图片,构建单机哈希表是不可能实现的,内存是不够的。
这里我们还是用到数据分片的思路。准备 n 台服务器构建图片的哈希表,将图片的哈希值与 n 求模,得到的数字对应服务器的编号,该服务器就构建此图片的散列表。当获取图片的时候,同样的将图片的哈希值与 n 求模,根据得到的数字到对应服务器的哈希表中获取图片的信息。
关于 1 亿张图片构建散列表所需机器的估算。
散列表中一个数据单元包含散列值和图片文件路径。假设用 MD5 哈希求值,长度是 128 Bit,16字节。图片路径上限是 256 字节,平均长度按 128 字节计算,如果送链表法解决散列冲突,还需要一个指针,指针占用 8 字节。则,一个散列表中每个单元格詹内存约为 152 字节。
假设一台机器内存 2GB,散列表装载因子 0.75,一台机器大约存储 1000(2GB * 0.75 / 152) 万张图片。那么存储 1 亿张图片,大约需要十几台这样服务器。在资源投入之初,这样的估算对于项目的可行性分析很有必要。
针对海量数据的处理,都可以采用数据分片的方式解决。借助这种方式,可以突破单机内存和 CPU 等资源的限制。
哈希算法应用之分布式存储
互联网面对的是海量的数据海量的存储,为了提高访问效率,我们都会提供分布式缓存。
对于构建分布式缓存,可以采用数据分片的思想,构建多机缓存。但是,如果缓存数据不断增加,现有的多机器构建的缓存需要扩充,必须添加更多的机器构建分布式缓存的时候,我们要警惕雪崩效应。
如果是单纯的增加 n 台机器,那么原有的哈希算法求模的数值就需要增加 n 的值。如此,原始缓存数据的哈希值必将发生该表,大量的缓存数据将会失效,稻城缓存穿透。这个时候,一致性哈希算法就排上用处了。
现在有 n 台机器构建分布式缓存,我们对要缓存的数据哈希求值,在与 Max 求模,Max 远大于 n 。哈希值与 Max 求模的值会落在 [0 到 Max] 区间,然后我们对 0 至 Max 划分区间,然后将划分后的区间与 n 台机器创建映射关系。那么,访问缓存数据的时候,得到哈希值与 Max 的求模值,查找出该值所在的 0 至 Max 的区间,然后在根据区间和机器的映射关系得出对应的机器,然后访问该机器的缓存。
如果现有的分布式缓存需要扩容,增加新的机器的时候,只需将 0 至 Max 划分出的部分区间分配给新的机器,就完成了扩容。在这个过程当中,只会影响到少部分的数据缓存穿透,大量数据的缓存依旧可用。
总结
本文创作灵感来源于 极客时间 王争老师的《数据结构与算法之美》课程,通过课后反思以及借鉴各位学友的发言总结,现整理出自己的知识架构,以便日后温故知新,查漏补缺。
初入算法学习,必是步履蹒跚,一路磕磕绊绊跌跌撞撞。看不懂别慌,也别忙着总结,先读五遍文章先,无他,唯手熟尔~
与诸君共勉