Spark白话

举报
黄生 发表于 2023/09/26 00:56:50 2023/09/26
【摘要】 谷歌这个名字就是“大规模"的同义词。Google正是改写自数学术语googol,意思是1后面带100个0。不论是关系数据库这种传统的存储系统,还是传统的命令式编程,都没有能力满足谷歌构建和搜索全网索引文档的超大规模需求。这种需求最终孕育出了谷歌文件系统(GFS)、MapReduce(MR)编程框架,以及Bigtable数据存储。GFS使用大量的标准硬件服务器来搭建集群,提供容错的分布式文件系...

谷歌这个名字就是“大规模"的同义词。Google正是改写自数学术语googol,意思是1后面带100个0。不论是关系数据库这种传统的存储系统,还是传统的命令式编程,都没有能力满足谷歌构建和搜索全网索引文档的超大规模需求。
这种需求最终孕育出了谷歌文件系统(GFS)、MapReduce(MR)编程框架,以及Bigtable数据存储。GFS使用大量的标准硬件服务器来搭建集群,提供容错的分布式文件系统,而Bigtable则基于GFS提供可伸缩的结构化数据存储。基于函数式编程,MR则为分布在GFS和Bigtable上的大规模数据处理引人了一种新的并行编程范式。

从本质上说,MR应用程序与MR系统交互,将用于计算的代码逻辑(映射函数和归约函数)发送到存储数据的地方来执行,从而实现在本机或集群同一机架内处理数据,而不是让应用程序远程拉取数据。集群中的工作节点对中间计算结果做归约和聚合操作,并通过归约函数生成最终的输出结果,然后将结果写入分布式存储,以便其他程序读取。

这种方式显著减少了网络开销,将绝大部分输人输出(I/O)操作限定在本地磁盘,从而避免跨网络读写。

关于GFS、MR和Bigtable的论文在开源社区激起了千层浪,尤其是雅虎,毕竟雅虎的搜索引擎也面临类似的挑战。谷歌的GFS论文所描述的计算挑战及解决方案为Hadoop文件系统和MR分布式计算框架提供了雏形。

然而,基于HDFS的MR框架也存在不容忽视的缺点。
第一,管理集群很难,操作也比较烦琐。
第二,Hadoop的通用批处理MR API非常啰嗦,需要大段的样板代码配置,而且容错性很差。
第三,对于需要多组映射和归约的复杂数据作业来说,各组MapReduce间的计算结果要写入硬盘供后续阶段的操作使用。这种重复的磁盘输入输出行为带来的代价是,大型的MR作业可能要执行几小时甚至几天才能结束。

image.png

最后,虽然Hadoop MR对于大规模的通用批处理作业来说还可以,但结合机器学习、流处理,或者交互式SQL查询等其他工作场景的话,难免力不从心。于是工程师开发了一些定制化的系统,例如Apache Hive、Apache Storm、Apache Impala、Apache Giraph、Apache Drill、Apache Mahout等等。这些项目都有自己的API和集群配置选项,因而进一步增加了Hadoop集群的运维复杂度,也使得Hadoop开发的学习曲线更加陡峭。

一批来自美国加州大学伯克利分校、具有Hadoop MapReduce经验的研究人员推出了spark项目。2009年,Spark项目在RAD实验室诞生。中心思想是,借鉴Hadoop MR的思想并增强系统,加上高容错性和高并发,支持将迭代式或交互式映射和归约计算的中间结果存储在内存中,并向用户提供支持多种语言、简单、易组合的API作为编程模型,一站式支持各种使用场景。

Spark为中间计算结果提供了基于内存的存储,这让它比Hadoop MR快了很多。它整合了各种上层库,比如用于机器学习的库MLlib、提供交互式查询功能的SparkSQL、支持操作实时数据的流处理库Structured Streaming,以及图计算库GraphX。这些库都提供了易用的API。

Spark提供了一种称作RDD(resilient distributed dataset,弹性分布式数据集)的简单逻辑数据结构,它是Spark最基本的抽象。其他高级的结构化数据抽象(比如DataFrame和Dataset)都是基于RDD构建的,RDD彰显着Spark的简单性。Spark提供的RDD操作分为转化操作和行动操作,这种简单的编程模型使你能够轻松地使用熟悉的编程语言来构建大数据应用。

Spark的重心在于快速的分布式计算引擎,而不是存储。和Apache Hadoop同时包含计算和存储不同,Spark解耦了计算和存储。
这意味着你可以用Spark读取存储在各种数据源中的数据,并在内存中进行处理。你还可以扩展Spark的DataFrameReader和DataFreameWriter,以便将其他数据源(如Apache Kafka、Kinesis、Azure存储、亚马逊S3)的数据读取为DataFrame的逻辑数据抽象,以进行操作。

image.png

组件和API栈
image.png

在数据能讲故事之前,数据科学家必须先清洗数据、探索数据,以发现潜在的模式,然后构建出模型,从而对结果进行预测或建议。其中一些任务需要具有统计学、数学、计算机科学和编程方面的知识背景。
大多数数据科学家能熟练运用SQL这样的分析工具,擅长使用NumPy和Pandas这样的库,熟悉R和Python这些编程语言。但他们还需要了解如何处理或转化数据,以及如何使用现成的分类算法、回归算法、聚类算法来构建模型。这些任务经常是迭代的、交互式的、临时性的,又或是实验性的(用于证明假想)。
spark能支持这些不同类型的工具。spark的MLlib提供了一些常见的机器学习算法,以使用高层的评估器、转化器、数据特征提取器来构建模型流水线。spark SQL和spark shell则有助于对数据进行临时的交互式探索。
Spark让数据科学家能够处理大规模数据集,并让其模型训练和评估能够扩展到更大的数据规模上。

存储解决方案应该能够支持各种各样的业务场景:
像传统商业智能分析这样的SQL作业;
批式作业,如处理原始非结构化数据的传统ETL作业;
像实时监控和告警这样的流式作业;
像推荐和客户流失预测这样的机器学习和人工智能作业。

数据库的设计理念是将结构化数据存储为表,使用SQL查询语句来读取。
数据必须遵从严格的表结构,数据库管理系统重度依赖这个表结构对数据存储和处理协同优化。
也就是说,硬盘上的文件的数据排布和索引与数据库高度优化的查询处理引擎在数据库内部紧密耦合,为存储的数据提供非常快速的计算速度,并对所有读写操作提供强事务的ACID保证。

数据库的SQL作业可以大致分为
联机事务处理(OLTP)作业,银行账户交易等OLTP作业一般要求高并发、低延迟,使用简单的查询语句,每次读取或更新少数几条记录。
联机分析处理(OLAP)作业,周期性报表等OLAP作业一般是比较复杂的查询(涉及聚合和表连接),需要对很多数据进行高吞吐的扫描。

Spark查询引擎,主要针对OLAP场景设计。

数据分析领域的二个趋势
数据量不断增长
随着大数据的出现,业界出现了通过衡量和收集一切数据(页面浏览量、点击量等)来理解趋势和用户行为的浪潮。
分析类型不断丰富
随着数据集的增长,从数据中挖掘更深层次信息的需求出现了。这带来了机器学习和深度学习等复杂分析的爆炸式增长。

数据库已经不能充分适应上述新趋势了。
扩展数据库的代价特别大
虽然数据库能在单机上高效处理数据,但是数据量增长的速度远超单机性能极限的增长速度。改进处理引擎的唯一办法就是扩展,也就是使用多台机器并行处理数据。但是,大多数数据库系统设计时并没有考虑通过扩展来执行分布式处理任务,尤其是那些开源的数据库系统。少数的工业级数据库解决方案可以勉强满足处理要求,但获取和维护的代价特别高。

数据库不能很好地支持非SQL查询
数据库以复杂的(通常是专有的)格式存储数据,这种格式一般只针对数据库的SQL处理引擎读取数据而高度优化。这意味着像机器学习系统和深度学习系统这样的其他处理工具不能高效访问数据(只能低效地从数据库读取所有数据)。数据库系统也不能通过轻松扩展来执行机器学习这种不基于SQL的分析。

数据库的这些不足之处促使业界发展出了一种完全不同的数据存储方式,那就是数据湖

数据湖是在廉价硬件上运行的分布式存储解决方案。
与数据库架构不同,数据湖架构将分布式存储系统与分布式计算系统进行解耦。数据使用开放的格式存储为文件,这样任何处理引擎都可以使用标准API直接读写数据文件。
21世纪10年代后期,Hadoop文件系统(HDFS)促使这种开放格式的设计思想流行起来。
各个公司可以分别依据下列部件来构建自己的数据湖。
存储系统。既可以选择在集群的机器上运行HDFS,也可以使用云上的对象存储系统(如AWS S3、Azure Data Lake Storage,或Google Cloud storage)。
文件格式。数据以文件形式存储,可以使用结构化格式(如parquet、ORC等)、半结构化格式(如JSON),有时甚至可以使用非结构化格式(如文本格式、图像、音频、视频等)。
处理引擎。既可以选择批处理引擎(如Spark、Presto、hive等),也可以使用流处理引擎(如Spark、Flink等),还可以使用机器学习库(如Spark MLlib、scikit-learn、R等)。

可以根据作业场景选择最合适的存储系统、开放的数据格式,以及处理引擎,这种灵活性是数据湖相对数据库而言最大的优势。总体来说,在性能特性相当的情况下,数据湖方案一般比数据库方案便宜得多。这个关键优势使得大数据生态系统爆炸式成长。

数据湖的缺点,最糟糕的是没有事务保证。
原子性与隔离性。写数据时,处理引擎会以分布式写多个文件。如果操作失败,没有回滚机制来撤回已经写入的文件,因此可能会留下损坏的数据。(如果并发的作业同时修改数据,且上层没有相应机制提供文件隔离,那么问题会更槽糕。)
一致性。写失败时没有原子性保证,这进一步导致了读取时可能查到不一致的数据。事实上,即使数据能成功写入,也很难确保数据质量。举例来说,数据湖的一个常见问题是,不小心写入格式和表结构与已有数据不一致的数据。

开发人员也有一些解决办法,比如

根据列的值,数据湖中的大量数据文件通常“分区”到多个子目录(例如,一个Parquet格式的Hive表按日期进行分区)。要想实现对已有数据的原子性修改,经常需要完全重写多个子目录(先写入临时目录,然后替换目录),哪怕只是更新或删除少数几条记录。

数据更新作业的调度(如每日ETL作业)和数据查询作业(如每日报表作业)通常要错开,以避免因同时访问数据而导致的不一致问题。

湖仓一体(lakehouse)是针对OLAP场景且兼具数据湖和数据库优点的新范式。
新的系统设计让湖仓一体成为可能,从而直接以低成本提供类似数据库的数据管理特性,同时具有数据湖的可伸缩存储的特性。
支持事务
表结构强化与治理。湖仓一体系统禁止表结构不对的数据插人表内,必要时也可以显式调整表结构来适应不断变化的数据。这种系统可以推理数据完整性,需要有可靠的治理和审计机制。
支持开放格式的各种数据类型。为了使各种工具可以直接且高效地访问数据,必须提供具备标准化读写接口的开放格式来存储数据。

支持各种作业类型
湖仓一体系统支持对其中的数据执行各种类型的作业,因为有各种使用开放接口读取数据的工具提供支持,数据不需要导来导去。从传统的SQL查询和流式分析到机器学习,湖仓一体系统避免了数据孤岛(也就是将不同类别的数据放在不同系统中),允许开发人员更轻松地构建各种复杂的数据解决方案。

支持插入更新和删除。变更数据捕获(change data capture,CDC)和慢变更维度(slowly changing dimension,SCD)等复杂使用场景要求表中的数据能持续更新。通过事务保证,湖仓一体系统允许数据并发删除和更新。
数据治理。湖仓一体系统提供用于推理数据完整性和审计所有数据变更的工具,可以用于合规。

一些开源系统开源用来构建湖仓一体架构,如Hudi, Iceberg, Delta Lake。

Apache Iceberg最初由Netflix构建,是海量数据集的另一个开放存储格式。但与专注更新键值数据的Hudi有所不同,Iceberg更关注单表扩展到PB级的通用数据存储,并且具有更新表结构的特性。
通过对表结构中列、字段以及嵌套结构的添加、删除、更新、改名、重排来修改表结构。
隐藏分区机制,在内部为表中的行创建分区值。
修改分区结构,随着数据量或查询模式改变,自动执行元数据操作以更新表的布局。
时间旅行,允许用户通过ID或时间戳查询表的某个快照的数据。
通过回滚到以前的版本来修正错误。
确保多个并发写之间的可串行化级别的隔离。

Dalta Lake由Spark的初创者构建,所以与Spark的集成度最高。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。