​

  IDC预测,数据中心、边缘计算和物联网产生的数据将在未来7年内增加5倍,达到175ZB。随着数据的巨大增长,Apache软件基金会的Apache spark已经成为分布式扩展数据处理最流行的框架之一,在本地和云上数百万台服务器上运行。本章介绍了Spark框架,并解释它是如何执行应用程序的。

  Apache Spark是一个用于大规模数据处理的快速通用分析引擎,可以在Hadoop、Apache Mesos、Kubernetes、独立运行或在云中运行。Spark提供了高级操作符,可以使用交互式shell、笔记本或打包应用程序轻松在Scala、Python、R或SQL中构建并行应用程序。

  在Spark核心数据处理引擎的基础上,还有用于SQL和DataFrames、机器学习、GraphX、图计算和流处理的库。这些库可以一起用于来自各种数据源的海量数据集,如HDFS、Alluxio、Apache Cassandra、Apache HBase或Apache Hive。

加速APACHE SPARK 3.X之一:Spark处理简介_应用程序

 Spark如何在集群上执行

  Spark应用程序在集群节点的执行器进程中以并行任务的形式运行,在驱动程序中的SparkSession对象和集群上的资源或集群管理器(无论是单机、Mesos、YARN或Kubernetes)之间协调执行。

加速APACHE SPARK 3.X之一:Spark处理简介_集群管理_02

  Spark也可以在一台机器上运行,称为本地模式。在本地模式下,驱动程序和任务在同一个Java虚拟机的线程中运行。本地模式对于原型、开发、调试和测试都很有用。但是,本地模式并不适用于运行生产应用程序。

从文件中创建DataFrame

  Spark DataFrame是org.apache.Spark.sql.Row对象的分布式数据集,在集群中跨多个节点进行分区,可以并行操作。DataFrame表示一个包含行和列的数据表,类似于R或Python中的DataFrame,但使用了Spark优化。DataFrame由分区组成,每一个分区都是数据节点上缓存中的行范围。

加速APACHE SPARK 3.X之一:Spark处理简介_spark_03

  dataframe可以从数据源构建,如csv、parquet、JSON文件、Hive表或外部数据库。DataFrame可以使用关系转换和Spark SQL查询进行操作。

  Spark shell或Spark notebooks提供了一种简单的交互式使用Spark的方式。您可以使用以下命令在本地模式下启动shell: 



$ /[installation path]/bin/spark-shell --master local[2]


  然后可以将本章其余部分的代码输入shell,以交互方式查看结果。在代码示例中,shell的输出以结果开头。

  为了协调应用程序驱动和群集管理器之间的执行,您需要在程序中创建一个SparkSession对象,如下面的代码示例所示:



val spark = SparkSession.builder.appName("Simple Application").master("local[2]").getOrCreate()


  当一个Spark应用程序启动时,它通过主URL连接到集群管理器。当创建SparkSession对象或提交Spark应用程序时,主URL可以设置为集群管理器或本地[N],以使用N个线程在本地运行。在使用spark-shell或notebook时,SparkSession对象已创建并可用作变量spark。连接后,集群管理器将分配资源并启动为集群中节点配置的执行程序进程。当Spark应用程序执行时,SparkSession将任务发送给执行程序以运行。

加速APACHE SPARK 3.X之一:Spark处理简介_spark_04

   通过SparkSession的读取方法,你可以从一个文件中读取数据到DataFrame中,指定文件类型、文件路径和模式的输入选项。



import org.apache.spark.sql.types._
import org.apache.spark.sql._
import org.apache.spark.sql.functions._
val schema =
StructType(Array(
StructField("vendor_id", DoubleType),
StructField("passenger_count", DoubleType),
StructField("trip_distance", DoubleType),
StructField("pickup_longitude", DoubleType),
StructField("pickup_latitude", DoubleType),
StructField("rate_code", DoubleType),
StructField("store_and_fwd", DoubleType),
StructField("dropoff_longitude", DoubleType),
StructField("dropoff_latitude", DoubleType),
StructField("fare_amount", DoubleType),
StructField("hour", DoubleType),
StructField("year", IntegerType),
StructField("month", IntegerType),
StructField("day", DoubleType),
StructField("day_of_week", DoubleType),
StructField("is_weekend", DoubleType)
))
val file = "/data/taxi_small.csv"
val df = spark.read.option("inferSchema", "false")
.option("header", true).schema(schema).csv(file)
result:
df: org.apache.spark.sql.DataFrame = [vendor_id: double, passenger_count:
double ... 14 more fields]


  take方法返回一个包含该DataFrame对象的数组,我们看到它是org.apache.spark.sql.Row类型的。



df.take(1)
result:
Array[org.apache.spark.sql.Row] = Array([4.52563162E8,5.0,2.72,-
73.948132,40.829826999999995,-6.77418915E8,-1.0,-
73.969648,40.797472000000006,11.5,10.0,2012,11,13.0,6.0,1.0])


DataFrame 转换和操作