如何处理海量数据

news2024/9/22 20:31:10

目录

1.海量数据简介

海量数据的产生

海量数据的处理

2.利用位图解决

题目一

题目二 

题目三

题目一变形

3.利用布隆过滤器解决

题目一

4.哈希切割解决

题目一

题目二

5.海量数据处理总结

1.海量数据简介

海量数据的产生

随着互联网的迅速发展,互联网已经深度融合进了人们的生活,随处可见互联网的影子,数据来源日益丰富;人们对互联网的依赖,这些数据源不断产生大量数据,形成了前所未有的数据规模。并且随着人口规模的增加,互联网中的数据增长只会越来越快,越来越多。

并且,在大数据中隐藏着巨大的商业价值和社会价值。通过对海量数据的分析,企业可以洞察市场趋势、消费者行为、产品偏好等,从而做出更精准的决策,优化资源配置,提升竞争力。因此,这要求我们必须有高效的海量数据处理技术来应对。

海量数据的处理

处理海量数据时,因为数据量太大,所以通常是存储在磁盘空间,可以理解为存储在文件中;而这些大量的数据通常是无法直接加载到内存中,但是程序的运行必须要加载到内存中,这个时候,我们就需要考虑如何利用有限的内存空间,处理大量的数据?

思路一:节约的思想 —— 减少数据在内存中所占用的空间。

比如:存储一个整形数据需要占用4字节的空间,那么存储十亿个整形数据就需要占用40亿个字节的空间,换算成GB的话大约是4GB;但是如果我们能利用计算机中的最小单位bit位来标记这十亿个整数的话,就能大大的减少内存空间的占用。我们可以算一下,1字节 == 8bit位,一个整形就需要32个bit位,如果用1个bit位来标记一个整形数据,那么,标识一个整形数据就能节省31个bit位,标识十亿个整形数据就能节省310个bit位,大约是3.61GB。因此,节约的思想是处理海量数据时一种非常实用的思想。

思路二:分批的思想 —— 分批次的将大量的数据加载进内存中处理。

比如:一个文件中有100亿个字符串数据需要我们处理,这个时候我们就可以把这个大文件分割成多个小文件,然后依次处理每个小文件,也就是进行逐个击破;如果小文件还是太大了,小问题,继续切分。直到切分出的小文件能够加载到内存空间中处理为止。分批处理的思想也是处理海量数据的一种实用思想。

如果使用节约的思想,我们可以尝试使用位图布隆过滤器来解决海量数据的问题,如果你不了解位图和布隆过滤器,可以参考这两篇文章 —— 位图 、布隆过滤器。

如果使用分批的思想,我们可以尝试使用哈希切割的方法。(文章后面会讲解哈希切割)

当然,路是死的,人是活的,我们还可以将两种方法结合使用,这样就能处理更多的数据了。接下来,笔者我将针对两种思想进行例题讲解。

2.利用位图解决

题目一

题目一:给定100亿个整数,设计算法找到只出现一次的整数?

思路一:使用map

着眼一看,这不就是个统计次数的问题吗?嗯,可以使用STL中的map解决,但是别忘了,这是100亿个整数啊,前面我们算过,存储十亿个整形数据需要4GB的内存空间,那么存储100亿个整形数据,就需要40GB的内存空间,内存铁铁装不下,我们可以考虑使用位图解决。

思路二:位图

如果使用位图来解决,我们可以如何使用位图呢?要知道,位图中的bit位只有两个取值,只能表示两种状态;如果将该题目中的状态划分为两种状态,那只能是出现次数是一次的整数和出现次数不是一次的整数。OK我们可以尝试使用这种思路来解决一下。

数据是几,就映射第几个bit位;没有出现的数据对应的bit位肯定是0,数据出现之后,对应的bit位加1,如:2和4。判断6的时候,出现第一个6的时候,将对应的bit位置为1,出现第二个6的时候怎么办呢?好像没有办法了,毕竟bit位只有两个取值;所以一个位图是解决不了这个问题的。

一个位图不行就增加一个位图,即使是增加一个位图,空间成本也足够低。下面,我们看看如果使用两个位图解决这个问题吧。

我们可以使用两个长度相等的位图,两个位图中相同位置的bit位共同判断。这个时候,一个位置就有四种状态了,分别是 00、01 、10、11 ;我们可以使用00表示数据出现了0次,使用01表示数据出现了1次,使用10表示数据出现了1次以上,使用11表示…… 额,不需要了,用三种状态就足够了。​

还是这组数据,通过上面的约定之后,我们很轻松的就完成了数据的映射工作。映射完数据之后,我们只需要判断相同位置的bit位组合是否为01来判断数据是否出现了一次。 

 封装两个位图的类,调用其中的接口即可;代码如下所示:

	template<size_t N>
	class two_bit_set
	{
	public:
		void set(size_t x)
		{
			// 00 -> 01
			if (_bs1.test(x) == false
				&& _bs2.test(x) == false)
			{
				_bs2.set(x);
			}
			else if (_bs1.test(x) == false
				&& _bs2.test(x) == true)
			{
				// 01 -> 10
				_bs1.set(x);
				_bs2.reset(x);
			}
		}

		bool test(size_t x)
		{
			if (_bs1.test(x) == false
				&& _bs2.test(x) == true)
			{
				return true;
			}

			return false;
		}
	private:
		bitset<N> _bs1;
		bitset<N> _bs2;
	};

题目二 

题目二:给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?

题目分析:

一个文件中就有100亿个整数,前面我们分析过,存储100亿个整数需要40GB的内存空间,所以我们可以使用位图来映射,以减少内存空间的使用;

那我们需要多少个bit位呢?100亿个整数是不是需要100亿bit位呢?非也,整形数据的取值范围是-2,147,483,648 ~ 2,147,483,647;满打满算也才42亿九千多万个数据,根据鸽巢原理可知,其中必然出现重复的数据,也就是说,我们要映射所有的整形数据,只需要42亿九千多万个bit位,因此,我们得出一个重要的结论 “使用位图处理海量数据时,开多少个bit位与数据量无关,而是取决于数据类型所能表示的范围” ,42亿九千多万个bit位大约等于511.367MB。

我们有1GB的内存,因此,我们最多可以使用两个位图来解决这个问题。

使用一个位图解决:

先读取一个文件中的数据,映射到位图中,再读取另一个文件中的数据,检测该数据所映射的bit位是否为1,如果bit位已经为1,说明该数据是交集。

使用两个位图解决:

将A文件中的数据映射到第一个位图中,将B文件中的数据映射到第二个位图中,将两个位图中对应位置进行按位与操作;结果为1,则表示这个数是交集。

 

题目三

题目三:1个文件中有100亿个int类型的数据,我们有1G内存,设计算法找到出现次数不超过2次的所有整数。

题目分析:这个题目和题目一类似,我们依然可以使用两个位图来解决。两个位图中对应的位置配合起来,可以表示4种情况;00表示该数据出现0次,01表示该数据出现1次,10表示该数据出现2次,11表示该数据出现3次及以上。

除了11这种情况之外,其他所有情况都要统计。

题目一变形

给定100亿个整数,我们只有512MB内存,设计算法找到只出现一次的整数?

题目分析:

在题目二中,我们讨论过,100亿个整数映射到位图中大约需要511.367MB的内存空间;这道题和题目一高度相似,题目一我们是利用两个位图解决的,并且最少需要两个位图,使用了大概1G左右的内存空间;相比于题目一,这道题又添加了限制条件512MB内存,也就是说数据量没减少,但我们只能使用一半的内存。

那我们能不能 不使用两个位图呢?不行,这一点在题目一中已经分析过了。那怎么办呢?别忘了,处理海量数据,除了节约的思想,我们还有分批的思想,题目又没说要一次将数据全部加载到内存中,既然空间少了一半,那我们就多加载一次,并且每次只加载一半的数据。

那我们该如何分批处理呢?别忘了,数据是有大小的,我们可以先处理数据范围前一半的数据,再处理后一半的数据,代价就是要多遍历几次文件。

我们假设数据范围是 0 ~ 2^32-1,第一次加载时,将 0 ~ 2^31-1范围的数据通过直接映射的方式映射到位图中,根据我们定义的规则判断该范围中的哪些数据出现了一次。

第二次加载时,将 2^31 ~ 2^32-1 范围的数据 减去2^31 之后映射到位图中,再根据我们定义的规则判断该范围中的哪些数据出现了一次。

这样一来,我们就利用512MB的空间统计出了100亿个整数中只出现一次的整数了。这个变形题中,我们使用了节约和分批两种思想,读者可以细细体会。

3.利用布隆过滤器解决

题目一

题目一:给两个文件,分别有100亿个字符串,我们只有1G内存,如何找到两个文件交集?给出近似算法即可。

题目分析:

一个文件中有100亿个字符串,假设一个字符串平均占用20字节的空间,就需要2000亿个字节,也就是200GB;我们可以采用节约的思想解决该问题,因为映射的数据是字符串类型的,并且题目要求给出近似算法即可,也就是说允许存在误判,那么我们可以使用布隆过滤器来解决这个问题。

先读取一个文件中的内容映射到布隆过滤器中,再读取另一个文件中的内容映射到布隆过滤器中,如果该数据映射的所有bit位都为1,则判断存在交集。

4.哈希切割解决

题目一

题目一:给两个文件,分别有100亿个字符串,我们只有1G内存,如何找到两个文件交集?给出精确算法。

题目分析:

这个题目和上面那个题目是一样的,但是要求我们给出精确算法,因此,我们不能再使用布隆过滤器了。前面我们分析过,假设一个字符串平均占用20字节,一个文件就需要整整200GB的空间,而且有两个文件,就需要400GB的空间;全部同时加载到内存中肯定不行,我们可以利用分批的思想,将这两个大文件分割成具有编号的、一个个的小文件。

那根据什么来分呢?我们可以利用字符串哈希算法,将字符串映射成一个个的整数,该整数就是该字符串所在小文件的编号。这样一来我们就将大文件中的字符串映射到了不同的小文件中,这就是哈希切割的思想

注意:映射两个大文件中的字符串的时候,我们需要使用同一个字符串哈希算法,这样才能确保两个大文件中的相同字符串 能够进入各自相同编号的小文件中。

当我们将字符串映射到小文件中之后,因为我们划分成了1000份小文件,平均每一个小文件就是0.1GB,是可以加载到内存中的。因此,我们可以直接读取到内存中处理;因为是找交集,我们只需要知道一个数据是否出现过即可,因此,我们可以使用STL中的set依次处理相同编号的小文件即可。

一个可能出现的问题 —— 子文件过大

因为相同的字符串和产生哈希冲突的字符串都是进入相同编号的小文件中,小文件过大有以下两种情况

情况一:重复的字符串过多,导致小文件过大。这种情况是不影响处理的,因为我们使用的是set,具有去重的功能。

情况二:冲突的字符串太多,导致小文件过大。这种情况下读取到内存中,会导致set抛异常,一旦set抛异常,说明小文件中冲突的字符串太多,需要换一个哈希函数继续切分。

题目二

题目二:给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?与上题条件相同,如何找到top K的IP?

第一问

题目分析:与上题类似,都是数据量上百亿的大文件,因此,我们直接使用哈希切割。依次读取每个ip,i = hashfunc(ip)%1000,i是几,该ip就进入第几个小文件中。相同的ip计算出的i肯定相同,可以进入相同的小文件中。

此时,我们可以使用STL中的map依次处理每一个小文件来统计次数;如果map抛异常,说明冲突的数据量过多,当前小文件过大,我们需要换哈希函数,进行二次切分。

第二问

题目分析:

和第一问一样,我们可以使用哈希切分将大文件分割成一个个的小文件,保证相同的ip进入同一个编号的小文件;此时,我们可以使用堆这种数据结构来处理每个小文件,对应STL中的priority_queue。我们可以在堆中存放一个个的pair<string,int>类型的键值对,自定义的比较规则为根据pair<string,int>中的第二个数据来比较。

5.海量数据处理总结

在处理海量数据问题时,我们可以使用两种思想,一种是节约的思想,一种是分批的思想。当然两种思想也可以同时使用。

如何使用节约思想呢?

节约,我们节约的是内存空间,使用占用内存小的数据结构来解决,比如位图、布隆过滤器等……

如何使用分批的思想呢?

分批就是多分几批来处理,如果再对分批进行优化,我们可以使用哈希切割,哈希切割时更高级的分批思想。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2100140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

堆排、快速排序、归并排序等总结

十大经典排序算法大梳理 (动图代码)&#xff08;动态图参考&#xff09; 排序算法平均时间复杂度最差时间复杂度空间复杂度数据对象稳定性冒泡排序O(n2)O(n2)O(1)稳定选择排序O(n2)O(n2)O(1)数组不稳定、链表稳定插入排序O(n2)O(n2)O(1)稳定快速排序O(n*log2n)O(n2)O(log2n)不…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《省间中长期市场连续运营下考虑耦合安全约束的电力交易联合优化出清模型》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

Docker笔记-Docker容器使用

Docker笔记-Docker容器使用 1、Docker 客户端 docker 客户端非常简单&#xff0c;我们可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项。 $ docker可以通过命令 docker command --help 更深入的了解指定的 Docker 命令使用方法。 例如我们要查看 docker sta…

用vs附加运行的软件并打断点

需求&#xff1a;给一个代码文件A的第n行打断点。 前提&#xff1a;目标软件已经build完成。并且生成了对应的pdb文件P。 0 将要打断点的代码&#xff0c;所在生成的pdb文件放到exe相同目录下。 1 运行程序。 2 打开vs&#xff0c;并打开文件A。并在n行打上断点。&#xff…

视觉SLAMch4——李群和李代数

一、李群和李代数在SLAM中的定位&#xff08;如何解决SLAM中的问题&#xff09; 在视觉SLAM中&#xff0c;我们的目标之一是估计传感器&#xff08;通常是摄像头&#xff09;在每一时刻的位置和姿态。为了量化估计的好坏&#xff0c;我们需要定义一个误差函数&#xff0c;该函数…

Apache Arrow简介

是什么&#xff1f; (1) Apache Arrow是内存分析开发平台&#xff0c;是Apache的顶级项目。 (2) Apache Arrow是一个开源的跨平台数据层开发框架&#xff0c;主要提供高效的、硬件加速的、内存中数据计算的能力。Apache Arrow的设计初衷是作为“新一代大数据系统的共享基础”&a…

3.5 算术运算指令

&#x1f393; 微机原理考点专栏&#xff08;通篇免费&#xff09; 欢迎来到我的微机原理专栏&#xff01;我将帮助你在最短时间内掌握微机原理的核心内容&#xff0c;为你的考研或期末考试保驾护航。 为什么选择我的视频&#xff1f; 全程考点讲解&#xff1a;每一节视频都…

11、Django Admin启用对计算字段的过滤

重新定义admin.py中的Hero管理模型如下&#xff1a; admin.register(Hero) class HeroAdmin(admin.ModelAdmin):list_display ("name", "is_immortal", "category", "origin", "is_very_benevolent")list_filter ("…

(第四十天)配置完整的考试系统,完成前端和后端并优化,mysql后端,nginx前端,java连接

回顾 1 、使用 harbor 仓库 python --version yum -y update yum -y install python2-pip pip install --upgrade pip 20 .3 -i ....... pip install docker-compose -i ....... sh docker.sh 解压 harbor vim harbor.yml ./prepare ./installed 使用…

智慧储能柜构造揭秘:安科瑞2000ES解决方案打造智慧储能大脑

随着全球能源结构的转型和可再生能源的快速发展&#xff0c;储能技术成为调节能源供需、提高能源利用效率的关键。储能柜作为储能技术的核心组成部分&#xff0c;其构造和功能显得尤为重要。本文将为您详细解析储能柜的构造&#xff0c;并展示其如何成为高效能源管理的智慧核心…

ArcGIS Pro高级技巧:制作带地类编码文字的用地图例

欢迎关注同名微信公众号&#xff0c;更多文章推送&#xff1a; 01 需求分析 这个方法由群友【Erik】提供。 很有意思&#xff0c;看到最后一定会帮你打开思路。 直接上图比较&#xff0c;这是一般情况下简单的用地图例&#xff0c;只有色块&#xff1a; 下面这个是我们想要…

4、Django Admin对自定义的计算字段进行排序

通常&#xff0c;Django会为模型属性字段&#xff0c;自动添加排序功能。当你添加计算字段时&#xff0c;Django不知道如何执行order_by&#xff0c;因此它不会在该字段上添加排序功能。 如果要在计算字段上添加排序&#xff0c;则必须告诉Django需要排序的内容。你可以通过在…

有了这款AI代码神器Coursor,学习Rust不再是难题!

大家好&#xff0c;我是渔夫。 工欲善其事&#xff0c;必先利其器。AI 是未来十年生产力的核心工具&#xff0c;要让 AI 真正转化为生产力&#xff0c;而不仅仅是围观一时的热潮。 今天来聊聊最近又火爆AI圈的AI代码神器 Cursor&#xff0c;它其实是一款 VS Code 的一个分支&am…

在C#中使用Redis

NoSql NoSql概念 NoSQL&#xff0c;泛指非关系型的数据库。随着互联网web2.0网站的兴起&#xff0c; 历史中—中国的网站----马云--- 中国黄页&#xff0c;只能展示&#xff1b;用户只能看到 传统的关系数据库在处理web2.0网站&#xff08;可以看&#xff0c;也可以做到写&am…

华为云CCE集群创建loadBalancer

目录 一、目的 二、创建应用 三、创建服务 loadBalancer 四、域名解析 五、验证 一、目的 1、为CCE容器应用创建loadBalancer服务&#xff0c;并且绑定https协议的域名 2、公网访问域名: https://test.******.com 3、CCE创建用于公网域名访问的loadBalancer&#xff0c;不…

IAR9.X printf串口重定向方法,或提示Linker Error: “no definition for __write“的解决方案

一、问题现象&#xff1a; 1、Error[Li005]:no definition for"__write" [referenced from flush.o(dl7M_tlf.a)] 2、串口重映射代码没问题&#xff0c;但是串口工具接收不到数据 3、复现环境&#xff1a;IAR9.40.1 二、操作方法: 1、[工程项目]->[Options]…

【负载均衡式在线OJ】Compile_server 模块

文章目录 程序源码compile_server整体思路编译(compile.hpp)运行模块编译运行模块编译运行服务 程序源码 https://gitee.com/not-a-stupid-child/online-judge compile_server 整体思路 这个服务要对oj_server 发送过来的代码进行编译和运行&#xff0c;最后把结果返回给oj…

理想二极管

原理图 mos管选型 参考链接 很实用&#xff01;用MOS管制作一个理想中的二极管_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Xi421r7K8/?spm_id_from333.1007.tianma.2-1-4.click&vd_sourcee821a225c7ba4a7b85e5aa6d013ac92e 特此记录 anlog 2024年9月3日

JS设计模式之“单孑独立” - 单例模式

image.png 引言 在JavaScript开发中&#xff0c;单例模式是一种常见且实用的设计模式一。 单例模式的核心思想是&#xff1a;确保一个类只有一个实例对象&#xff0c;并且该对象可以在应用程序的任何地方被共享和访问。通过使用单例模式&#xff0c;我们可以简化代码、节省资…

SpringCloud开发实战(一):搭建SpringCloud框架

本系列文章主要是记录在工作中用到的微服务的各个组件&#xff0c;以及学习新的微服务组件~如有问题&#xff0c;欢迎大家批评指导。如果本文对你有帮助&#xff0c;还请点个收藏和关注。感谢支持&#xff0c;希望大家写的代码都没有BUG&#xff01;&#xff01; 前言 下面是我…