常见数据结构-哈希算法

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 常见数据结构-哈希算法

一,什么是哈希算法

哈希和散列其实意思是一样的,只是中文翻译的区别,英文是 Hash

哈希算法也叫 hash 算法或散列算法。哈希算法的定义:将任意长度的二进制串映射为固定长度(一般是 128 bit)的二进制串,这个映射的规则就是哈希算法。而通过原始数据映射之后得到的二进制值串就是哈希值

一个优秀的哈希算法一般需要满足以下几点要求(来源:《数据结构和算法之美》作者-王争的经验):

  • 从哈希值不能反向推导出原始数据(所以哈希算法也叫单向哈希算法);
  • 对输入数据非常敏感,哪怕原始数据只修改了一个 Bit,最后得到的哈希值也大不相同;
  • 散列冲突的概率要很小,对于不同的原始数据,哈希值相同的概率非常小;
  • 哈希算法的执行效率要尽量高效,针对较长的文本,也能快速地计算出哈希值。

hash(key) 中的 key 可以是字符串、数字、对象等,但其底层都是二进制串。

对应的哈希算法的特点如下:

  1. 不可逆,即通过密文无法反推生成明文。
  2. 原始字符串不一样,得到的哈希结果不一样。
  3. 冲突的概率要很小。
  4. 执行效率要高,理论上来说执行时间越长的冲突概率越小。

二,哈希算法的应用场景

1,安全加密

最常用于加密的哈希算法是 MD5(MD5 Message-Digest Algorithm,MD5 消息摘要算法)和 SHA(Secure Hash Algorithm,安全散列算法)。

对用于加密的哈希算法来说,有两点格外重要。第一点是很难根据哈希值反向推导出原始数据,第二点是散列冲突的概率要很小。

对于第二点要求,实际上,不管是什么哈希算法,我们只能尽量减少碰撞冲突的概率,理论上是没办法做到完全不冲突的。为什么这么说呢?依据是基于组合数学中一个非常基础的理论:鸽巢原理(也叫抽屉原理)。鸽巢原理: 槽是固定的,数据是无限的(不定的),冲突是有概率存在的。

2,唯一标识

用在图片上的情况比较多,如果同一张图片上传多次,会通过哈希算法对图片的二进制内容进行计算,以计算结果为标识一张图片是否已经上传过。如果一张图片过大,可以采用部分二进制,比如开头 100K,中间 100K ,最后 100K 相加进行哈希算法来保证一定的执行效率。

3,文件完整性校验

比如迅雷等 p2p 下载器,从不同主机下载文件分片最终在本地合成一个文件。种子文件里面一般存储了各个文件分片的哈希结果,下载完成后通过本地计算各个分片的哈希再跟种子里面存储的核实来确保文件分片没有被恶意更改过。

4,散列函数

在散列表中需要的哈希算法,一般对执行效率要求高,对是否冲突要求比较低,因为散列表通常都会有冲突的解决方式,比如开放寻址法跟链表法。

5,负载均衡

何谓一个会话粘滞(session sticky)的负载均衡算法?即在同一个客户端上,在一次会话中的所有请求都路由到同一个服务器上

通过哈希算法,对客户端 IP 地址或者会话 ID 计算哈希值,将取得的哈希值与服务器列表的大小进行取模运算,最终得到的值就是应该被路由到的服务器编号。 这样,我们就可以把同一个 IP 过来的所有请求,都路由到同一个后端服务器上。

6,数据分片

哈希算法用于数据分片的一个例子是统计“搜索关键字”出现的次数。

假如有一个 1T 的日志文件,这里面记录了用户的搜索关键词,如果想要快速统计出每个关键词被搜索的次数,解决方案是什么?

分析问题:1,1T 的日志文件很大,内存中基本不可能放下这么多数据;2,数据很多,1 台机器处理速度会很慢。

解题思路:参考 Map-Reduce 原理。先对数据进行切片,然后使用多台机器并行处理。

解题方案:使用 n 台机器进行数据处理,首先从日志文件中顺序依次读取每个关键字,并用哈希函数计算得到哈希值,并跟 n 取模,取模得到的值就是对应的机器编号,这样哈希值相同的关键字就被分配到同一台机器上进行处理

最后每台机器分配统计关键字出现的次数,然后合并在一起就是最终的结果。

从上可以看出,针对这种海量数据的处理问题,我们可以采用多机分布式处理。借助这种分片的思路,可以突破单机内存、CPU 等资源的限制。

7,分布式存储

负载均衡、数据分片、分布式存储,这三个应用都跟分布式系统有关,也就是说哈希算法是可以解决这些分布式系统问题。

现在互联网面对的都是海量的数据、海量的用户。我们为了提高数据的读取、写入能力,一般都采用分布式的方式来存储数据,比如分布式缓存。我们有海量的数据需要缓存,所以一个缓存机器肯定是不够的。于是,我们就需要将数据分布在多台机器上。

该如何决定将哪个数据放到哪个机器上呢?我们可以借用前面数据分片的思想,即通过哈希算法对数据取哈希值,然后对机器个数取模,这个最终值就是应该存储的缓存机器编号。

但是这会产生一个问题,就是当数据增多的情况下,机器要扩容,增加机器数量,原来的 n 假设是 10,现在变成了 20,这样按照之前的方法所有的数据都要重新计算哈希值,然后重新搬移到正确的机器上。这样就相当于,缓存中的数据一下子就都失效了。所有的数据请求都会穿透缓存,直接去请求数据库。这样就可能发生雪崩效应,压垮数据库。

所以,我们需要一种方法,使得在新加入一个机器后,并不需要做大量的数据搬移。

这就是一致性哈希算法。假设我们有 kkk 个机器,数据的哈希值的范围是[0,MAX][0, MAX][0,MAX],我们将整个范围划分成 mmm 个小区间(mmm 远大于 kkk),那么每个机器就负责 m/km/km/k 个小区间。当有新机器加入的时候,我们就将某几个小区间的数据,从原来的机器中搬移到新的机器中。这样,既不用全部重新哈希、搬移数据,也保持了各个机器上数据数量的均衡。

总结

在负载均衡应用中,利用哈希算法替代映射表,可以实现一个会话粘滞的负载均衡策略。在数据分片应用中,通过哈希算法对处理的海量数据进行分片,多机分布式处理,可以突破单机资源的限制。在分布式存储应用中,利用一致性哈希算法,可以解决缓存等分布式系统的扩容、缩容导致数据大量搬移的难题。

参考资料

《数据结构与算法之美-王争》-哈希算法(下):哈希算法在分布式系统中有哪些应用?


相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
3天前
|
算法 Python
数据结构算法--4堆排序
堆排序过程概述:建立大根堆,将堆顶最大元素移出并替换为末尾元素,调整保持堆性质,重复此过程直至堆为空,实现排序。时间复杂度为O(nlogn)。Python中可用heapq模块进行堆操作。
|
12天前
|
算法
数据结构中的KMP算法及其改进算法
KMP算法通过引入部分匹配表,有效避免了重复计算,从而将字符串匹配的时间复杂度降低到O(m+n)。通过进一步优化next数组,KMP算法的效率得到了进一步提升。对于大规模字符串匹配问题,KMP算法及其改进算法提供了高效的解决方案,是计算机科学领域的经典算法之一。
19 3
|
3天前
|
算法 搜索推荐
数据结构算法--6 希尔排序和计数排序
**希尔排序**是插入排序的改进版,通过分组插入来提高效率。它逐步减少元素间的间隔(增量序列),每次对每个间隔内的元素进行插入排序,最终增量为1时进行最后一次直接插入排序,实现整体接近有序到完全有序的过程。例如,对数组`5, 7, 4, 6, 3, 1, 2, 9, 8`,先以间隔`d=4`排序,然后`d=2`,最后`d=1`,完成排序。计数排序则适用于0到100的数值,通过统计每个数出现次数,创建对应计数数组,再根据计数重建有序数组,时间复杂度为`O(n)`。
|
4天前
|
算法 C++ Python
数据结构与算法===贪心算法
数据结构与算法===贪心算法
|
3天前
|
机器学习/深度学习 算法 搜索推荐
数据结构算法--2 冒泡排序,选择排序,插入排序
**基础排序算法包括冒泡排序、选择排序和插入排序。冒泡排序通过相邻元素比较交换,逐步将最大值“冒”到末尾,平均时间复杂度为O(n^2)。选择排序每次找到剩余部分的最小值与未排序部分的第一个元素交换,同样具有O(n^2)的时间复杂度。插入排序则类似玩牌,将新元素插入到已排序部分的正确位置,也是O(n^2)复杂度。这些算法适用于小规模或部分有序的数据。**
|
3天前
|
机器学习/深度学习 算法 索引
数据结构算法--1 顺序查找二分查找
**顺序查找时间复杂度为O(n)**,适合无序列表,可以通过`enumerate`或直接遍历索引来实现。**二分查找时间复杂度为O(logn)**,适用于有序列表,利用Python中`left`、`right`指针和`mid`点不断缩小搜索范围。效率上二分查找更优。
|
3天前
|
存储 算法 Java
Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。
【6月更文挑战第21天】Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。简单哈希表实现未涵盖冲突解决和删除操作。
10 1
|
6天前
|
存储 算法 搜索推荐
数据结构中的常用算法
数据结构中的常用算法
|
7天前
|
搜索推荐 算法
【排序】数据结构——排序算法概念及代码详解(插入、冒泡、快速、希尔)
【排序】数据结构——排序算法概念及代码详解(插入、冒泡、快速、希尔)
|
10天前
|
存储 算法 关系型数据库
【MySQL技术内幕】5.7- InnoDB存储引擎中的哈希算法
【MySQL技术内幕】5.7- InnoDB存储引擎中的哈希算法
14 1