Spark 介绍
行业广泛使用Hadoop来分析他们的数据集。原因是Hadoop框架基于一个简单的编程模型(MapReduce),它支持可扩展,灵活,容错和成本有效的计算解决方案。这里,主要关注的是在处理大型数据集时在查询之间的等待时间和运行程序的等待时间方面保持速度。
Spark由Apache Software Foundation引入,用于加速Hadoop计算软件过程。
对于一个普遍的信念,Spark不是Hadoop的修改版本,并不是真的依赖于Hadoop,因为它有自己的集群管理。 Hadoop只是实现Spark的方法之一。
Spark以两种方式使用Hadoop - 一个是存储,另一个是处理。由于Spark具有自己的集群管理计算,因此它仅使用Hadoop进行存储。
Apache Spark简介
Apache Spark是一种快速的集群计算技术,专为快速计算而设计。它基于Hadoop MapReduce,它扩展了MapReduce模型,以有效地将其用于更多类型的计算,包括交互式查询和流处理。 Spark的主要特性是它的内存中集群计算,提高了应用程序的处理速度。
Spark旨在涵盖各种工作负载,如批处理应用程序,迭代算法,交互式查询和流式处理。除了在相应系统中支持所有这些工作负载之外,它还减少了维护单独工具的管理负担。
Apache Spark的演变
Spark是Hadoop在2009年在加州大学伯克利分校的Matei Zaharia的AMPLab开发的子项目之一。它是在2010年根据BSD许可开放。它在2013年捐赠给Apache软件基金会,现在Apache Spark已经成为2014年2月的顶级Apache项目。
Apache Spark的特性
Apache Spark具有以下功能。
速度
Spark有助于在Hadoop集群中运行应用程序,在内存中速度提高100倍,在磁盘上运行时提高10倍。这可以通过减少对磁盘的读/写操作的数量来实现。它将中间处理数据存储在存储器中。
支持多种语言
Spark在Java,Scala或Python中提供了内置的API。因此,您可以使用不同的语言编写应用程序。 Spark提供了80个高级操作符进行交互式查询。
高级分析
Spark不仅支持“Map”和“reduce”。它还支持SQL查询,流数据,机器学习(ML)和图算法。
Spark基于Hadoop
下图显示了如何使用Hadoop组件构建Spark的三种方式。
Spark部署有三种方式,如下所述。
Standalone- Spark独立部署意味着Spark占据HDFS(Hadoop分布式文件系统)顶部的位置,并明确为HDFS分配空间。 这里,Spark和MapReduce将并行运行以覆盖集群上的所有spark作业。
Hadoop Yarn- Hadoop Yarn部署意味着,spark只需运行在Yarn上,无需任何预安装或根访问。 它有助于将Spark集成到Hadoop生态系统或Hadoop堆栈中。 它允许其他组件在堆栈顶部运行。
Spark in MapReduce (SIMR) - MapReduce中的Spark用于在独立部署之外启动spark job。 使用SIMR,用户可以启动Spark并使用其shell而无需任何管理访问。
Spark的组件
下图说明了Spark的不同组件。
Apache Spark Core
Spark Core是spark平台的基础通用执行引擎,所有其他功能都是基于。它在外部存储系统中提供内存计算和引用数据集。
Spark SQL
Spark SQL是Spark Core之上的一个组件,它引入了一个称为SchemaRDD的新数据抽象,它为结构化和半结构化数据提供支持。
Spark Streaming
Spark Streaming利用Spark Core的快速调度功能来执行流式分析。它以小批量获取数据,并对这些小批量的数据执行RDD(弹性分布式数据集)转换。
MLlib (Machine Learning Library)
MLlib是Spark之上的分布式机器学习框架,因为基于分布式内存的Spark架构。根据基准,它是由MLlib开发人员针对交替最小二乘法(ALS)实现完成的。 Spark MLlib是基于Hadoop磁盘的Apache Mahout版本的9倍(在Mahout获得了Spark接口之前)。
GraphX
GraphX是Spark上的一个分布式图形处理框架。它提供了一个用于表达图形计算的API,可以通过使用Pregel抽象API为用户定义的图形建模。它还为此抽象提供了一个优化的运行时。
Spark RDD
弹性分布式数据集
弹性分布式数据集(RDD)是Spark的基本数据结构。它是一个不可变的分布式对象集合。 RDD中的每个数据集划分为逻辑分区,可以在集群的不同节点上计算。 RDD可以包含任何类型的Python,Java或Scala对象,包括用户定义的类。
形式上,RDD是只读的,分区的记录集合。 RDD可以通过对稳定存储器或其他RDD上的数据的确定性操作来创建。 RDD是可以并行操作的元件的容错集合。
有两种方法来创建RDD - 并行化驱动程序中的现有集合,或引用外部存储系统中的数据集,例如共享文件系统,HDFS,HBase或提供Hadoop输入格式的任何数据源。
Spark使用RDD的概念来实现更快和更高效的MapReduce操作。让我们首先讨论MapReduce操作是如何发生的,以及为什么它们不那么高效。
MapReduce中的数据共享缓慢
MapReduce被广泛应用于在集群上使用并行的分布式算法来处理和生成大型数据集。它允许用户使用一组高级操作符来编写并行计算,而不必担心工作分布和容错。
不幸的是,在大多数当前框架中,在计算之间重复使用数据(例如:两个MapReduce作业之间)的唯一方法是将其写入外部稳定存储系统(例如:HDFS)。虽然这个框架提供了访问集群的计算资源的许多抽象,用户仍然想要更多。
迭代和交互应用程序都需要跨并行作业更快的数据共享。由于复制,序列化和磁盘IO,MapReduce中的数据共享速度很慢。关于存储系统,大多数Hadoop应用程序,他们花费90%以上的时间做HDFS读写操作。
MapReduce迭代运算
在多阶段应用程序中跨多个计算重用中间结果。下图说明了当前框架如何工作,同时对MapReduce执行迭代操作。这会由于数据复制,磁盘I / O和序列化而招致大量开销,这使得系统变慢。
MapReduce上的交互操作
用户对同一数据子集运行即席查询。 每个查询将对稳定存储执行磁盘I / O,这可以支配应用程序执行时间。
下图说明了当在MapReduce上执行交互式查询时当前框架如何工作。
使用Spark RDD进行数据共享
由于复制,序列化和磁盘IO,MapReduce中的数据共享速度很慢。大多数Hadoop应用程序,他们花费90%以上的时间做HDFS读写操作。
认识到这个问题,研究人员开发了一个名为Apache Spark的专门框架。 spark的关键思想是弹性分布式数据集(RDD);它支持内存中处理计算。这意味着,它将存储器的状态存储为作业中的对象,并且对象可以在这些作业之间共享。内存中的数据共享比网络和磁盘快10到100倍。
让我们现在尝试找出Spark RDD中如何进行迭代和交互操作。
Spark RDD的迭代操作
下图给出了Spark RDD的迭代操作。它将中间结果存储在分布式存储器中,而不是稳定存储(磁盘),并使系统更快。
注意 - 如果分布式内存(RAM)不足以存储中间结果(JOB的状态),则它将这些结果存储在磁盘上
在星火RDD交互式操作
此图显示星火RDD交互式操作。如果不同的查询在同一组数据的反复运行,该特定数据可被保存在内存中获得更好的执行时间。
默认情况下,每次对其执行操作时,都可以重新计算每个已转换的RDD。 但是,您还可以在内存中保留RDD,在这种情况下,Spark将保持集群上的元素更快的访问,下次查询它。 还支持在磁盘上持久存储RDD,或者跨多个节点进行复制。
Spark SQL简介
Spark为结构化数据处理引入了一个称为Spark SQL的编程模块。它提供了一个称为DataFrame的编程抽象,并且可以充当分布式SQL查询引擎。
Spark SQL的特性
以下是Spark SQL的功能
集成
无缝地将SQL查询与Spark程序混合。 Spark SQL允许您将结构化数据作为Spark中的分布式数据集(RDD)进行查询,在Python,Scala和Java中集成了API。这种紧密的集成使得可以轻松地运行SQL查询以及复杂的分析算法。
统一数据访问
加载和查询来自各种来源的数据。 Schema-RDDs提供了一个有效处理结构化数据的单一接口,包括Apache Hive表,镶木地板文件和JSON文件。
Hive兼容性
在现有仓库上运行未修改的Hive查询。 Spark SQL重用了Hive前端和MetaStore,为您提供与现有Hive数据,查询和UDF的完全兼容性。只需将其与Hive一起安装即可。
标准连接
通过JDBC或ODBC连接。 Spark SQL包括具有行业标准JDBC和ODBC连接的服务器模式。
可扩展性
对于交互式查询和长查询使用相同的引擎。 Spark SQL利用RDD模型来支持中查询容错,使其能够扩展到大型作业。不要担心为历史数据使用不同的引擎。
Spark SQL架构
下图说明了Spark SQL的体系结构
此架构包含三个层,即Language API,Schema RDD和数据源。
语言API
Spark与不同的语言和Spark SQL兼容。 它也是由这些语言支持的API(python,scala,java,HiveQL)。
模式RDD
Spark Core是使用称为RDD的特殊数据结构设计的。 通常,Spark SQL适用于模式,表和记录。 因此,我们可以使用Schema RDD作为临时表。 我们可以将此Schema RDD称为数据帧。
数据源
通常spark-core的数据源是文本文件,Avro文件等。但是,Spark SQL的数据源不同。 这些是Parquet文件,JSON文档,HIVE表和Cassandra数据库。
Spark SQL 数据帧
DataFrame是一个分布式数据集合,它被组织成命名列。从概念上讲,它相当于具有良好优化技术的关系表。
DataFrame可以从不同来源的数组构造,例如Hive表,结构化数据文件,外部数据库或现有RDD。这个API是为现代大数据和数据科学应用程序设计的,从Python的R ProgrammingandPandas中的DataFrame中获得灵感。
DataFrame的特性
下面是一些DataFrame的一些特征:
能够将单个节点集群上的大小为Kilobytes到Petabytes的数据处理为大型集群。
支持不同的数据格式(Avro,csv,弹性搜索和Cassandra)和存储系统(HDFS,HIVE表,mysql等)。
通过Spark SQL Catalyst优化器(树变换框架)的最先进的优化和代码生成。
可以通过Spark-Core轻松地与所有大数据工具和框架集成。
提供用于Python,Java,Scala和R编程的API。
SQLContext
SQLContext是一个类,用于初始化Spark SQL的功能。初始化SQLContext类对象需要SparkContext类对象(sc)。
以下命令用于通过spark-shell初始化SparkContext。
$ spark-shell
默认情况下,SparkContext对象在spark-shell启动时用namesc初始化。
使用以下命令创建SQLContext。
scala> val sqlcontext = new org.apache.spark.sql.SQLContext(sc)
例
让我们考虑一个名为employeesee.json的JSON文件中的员工记录示例。 使用以下命令创建DataFrame(df)并读取名为employee.json的JSON文档,并具有以下内容。
employee.json-将此文件放在currentscala>指针所在的目录中。
{
{"id" : "1201", "name" : "satish", "age" : "25"}
{"id" : "1202", "name" : "krishna", "age" : "28"}
{"id" : "1203", "name" : "amith", "age" : "39"}
{"id" : "1204", "name" : "javed", "age" : "23"}
{"id" : "1205", "name" : "prudvi", "age" : "23"}
}
DataFrame操作
DataFrame为结构化数据操作提供了一个领域特定的语言。 这里,我们包括使用DataFrames的结构化数据处理的一些基本示例。
按照以下步骤执行DataFrame操作
阅读JSON文档
首先,我们要读取JSON文档。 基于此,生成名为(dfs)的DataFrame。
使用以下命令读取JSON文档namedemployee.json。 数据显示为带有字段id,name和age的表。
scala> val dfs = sqlContext.read.json("employee.json")
输出:字段名称从employee.json自动获取。
dfs: org.apache.spark.sql.DataFrame = [age: string, id: string, name: string]
显示数据
如果你想看到的数据框的数据,然后使用以下命令。
scala> dfs.show()
输出:您可以以表格格式查看员工数据。
<console>:22, took 0.052610 s
+----+------+--------+
|age | id | name |
+----+------+--------+
| 25 | 1201 | satish |
| 28 | 1202 | krishna|
| 39 | 1203 | amith |
| 23 | 1204 | javed |
| 23 | 1205 | prudvi |
+----+------+--------+
使用方法printSchema
如果要查看DataFrame的Structure(Schema),请使用以下命令。
scala> dfs.printSchema()
输出:
root
|-- age: string (nullable = true)
|-- id: string (nullable = true)
|-- name: string (nullable = true)
使用选择方法
使用以下命令从DataFrame的三个列中获取fetchname-column。
scala> dfs.select("name").show()
输出:您可以查看名称列的值。
<console>:22, took 0.044023 s
+--------+
| name |
+--------+
| satish |
| krishna|
| amith |
| javed |
| prudvi |
+--------+
使用年龄过滤器
使用以下命令查找年龄大于23(age> 23)的雇员。
scala> dfs.filter(dfs("age") > 23).show()
输出
<console>:22, took 0.078670 s
+----+------+--------+
|age | id | name |
+----+------+--------+
| 25 | 1201 | satish |
| 28 | 1202 | krishna|
| 39 | 1203 | amith |
+----+------+--------+
使用groupBy方法
使用以下命令计算同一年龄的员工人数。
scala> dfs.groupBy("age").count().show()
输出:这两个雇员有23岁。
<console>:22, took 5.196091 s
+----+-----+
|age |count|
+----+-----+
| 23 | 2 |
| 25 | 1 |
| 28 | 1 |
| 39 | 1 |
+----+-----+
运行SQL查询
SQLContext使应用程序能够在运行SQL函数时以编程方式运行SQL查询,并将结果作为DataFrame返回。
通常,在后台,SparkSQL支持两种不同的方法将现有的RDD转换为DataFrames
编号 | 方法和说明 |
---|---|
1 | 使用反射来推断模式 此方法使用反射来生成包含特定类型的对象的RDD的模式。
|
2 | 以编程方式指定模式 第二种创建DataFrame的方法是通过编程接口,它允许您构造一个模式,然后将其应用到现有的RDD。
|
Spark SQL 数据源
DataFrame接口允许不同的DataSource在Spark SQL上工作。 它是一个临时表,可以作为正常的RDD操作。 将DataFrame注册为表允许您对其数据运行SQL查询。
在本章中,我们将描述使用不同Spark DataSource加载和保存数据的一般方法。 此后,我们将详细讨论可用于内置数据源的特定选项。
SparkSQL中提供了不同类型的数据源,下面列出了其中的一些数据源:
编号 | 数据源 |
---|---|
1 | JSON数据集 Spark SQL可以自动捕获JSON数据集的模式,并将其作为DataFrame加载。
|
2 | 蜂巢表 Hive与Spark库捆绑为HiveContext,它继承自SQLContext。
|
3 | Parquet文件 Parquet是一种柱状格式,由许多数据处理系统支持。 |