文章目录
前言
本文介绍Spark DataFrame、Spark SQL、Spark Streaming入门使用教程,这些内容将为后面几篇进阶的streaming实时计算的项目提供基本计算指引,本文绝大部分内容来自Spark官网文档(基于PySpark):
Spark DataFrame、Spark SQL、Spark Streaming
1、RDD、Spark DataFrame、Spark SQL、Spark Streaming
RDD:大家最熟悉的数据结构,主要使用transmissions和actions 相关函数式算子完成数据处理和数理统计,例如map、reduceByKey,rdd没有定义 Schema(一般指未定义字段名及其数据类型), 所以一般用列表索引号来指定每一个字段。 例如, 在电影数据的推荐例子中:
move_rdd.map(lambda line:line.split('|')).map(lambda a_list:(alist[0],a_list[1],a_list[2]))
每行有15个字段的数据,因此只能通过索引号获取前3个字段的数据,这要求开发者必须掌握 Map/Reduce 编程模式,不过, RDD 功能也最强, 能完成所有 Spark 数据处理与分析需求。
Spark DataFrame:创建DataFrame时,可以定义 Schema,通过定义每一个字段名与数据类型,以便之后直接用字段名进行数据索引,用法跟Pandas的DataFrame差别不大。Spark DataFrame是一种更高层的API,而且基于PySpark,用起来像Pandas的”手感“,很容易上手。
Spark SQL 底层是封装了DataFrame(DataFrame封装了底层的RDD) ,让使用者直接用sql的方式操作rdd,进一步降低Spark作为分布式计算框架的使用门槛。
Spark Streaming是本博客重点要解析的数据结构,实际项目将使用它实现流式计算,相关定义参考原文:
Spark Streaming is an extension of the core Spark API that enables scalable, high-throughput, fault-tolerant stream processing of live data streams. Data can be ingested from many sources like Kafka, Flume, Kinesis, or TCP sockets, and can be processed using complex algorithms expressed with high-level functions like map, reduce, join and window. Finally, processed data can be pushed out to filesystems, databases, and live dashboards.
Spark Streaming具有扩展性、数据吞吐量高、容错的特点,底层基于core Spark API 实现,用于流数据处理。Spark Streaming注入的实时数据源可来自Kafka、Flume、Kinesis或者TCP流等,park Streaming可借助Map、reduce、join和window等高级函数接口搭建复杂的算法用于数据处理。Spark Streaming实时处理后数据可存储到文件系统、数据库或者实时数据展示仪表。
2、Spark DataFrame
Spark DataFrame API比较多,既然用于数据处理和计算,当然会有预处理接口以及各统计函数、各种方法,详细参考官网:pyspark.sql.DataFrame以及pyspark.sql.functions module模块
目前版本中,创建Spark DataFrame的Context接口可以直接用SparkSession接口,无需像RDD创建上下文时用Spark Context。
SparkSession:pyspark.sql.SparkSession:Main entry point for DataFrame and SQL functionality.
2.1 创建基本的Spark DataFrame
创建 Spark DataFrame有多种方式,先回顾Pandas的DataFrame,Pandas可从各类文件、流以及集合中创建df对象,同样 Spark DataFrame也有类似的逻辑
首先需加载spark的上下文:SparkSession
import pandas as pd
import numpy as np
from pyspark.sql import SparkSession # 用于Spark DataFrame的上下文
from pyspark.sql.types import StringType,StructType,StructField, LongType,DateType # 用于定义df字段类型
from pyspark.sql import Row,Column
#本地spark单机模式
spark=SparkSession.builder.master("local").appName('spark_dataframe').getOrCreate()
print(spark)
输出spark上下文信息:
SparkSession - in-memory
SparkContext
Spark UI
Version v2.4.4
Master
local[*]
AppName
spark_dataframe
from pyspark.sql.types:df目前支持定义的字段类型(参考源码),用于定义schema,类似关系型数据库建表时,定义表的字段类型
__all__ = [
"DataType", "NullType", "StringType", "BinaryType", "BooleanType", "DateType",
"TimestampType", "DecimalType", "DoubleType", "FloatType", "ByteType", "IntegerType",
"LongType", "ShortType", "ArrayType", "MapType", "StructField", "StructType"]
直接用从RDD创建dataframe对象
spark_rdd = spark.sparkContext.parallelize([
(11, "iPhoneX",6000, datetime.date(2017,9,10)),
(12, "iPhone7",4000, datetime.date(2016,9,10)),
(13, "iPhone4",1000, datetime.date(2006,6,8))]
)
# 定义schema,就像数据库建表的定义:数据模型,定义列名,类型和是否为能为空
schema = StructType([StructField("id", IntegerType(), True),
StructField("item", StringType(), True),
StructField("price", LongType(), True),
StructField("pub_date", DateType(), True)])
# 创建Spark DataFrame
spark_df= spark.createDataFrame(spark_rdd, schema)
# 创建一个零时表,用于映射到rdd上
spark_df.registerTempTable("iPhone")
# 使用Sql语句,语法完全跟sql一致
data = spark.sql("select a.item,a.price from iPhone a")
# 查看dataframe的数据
print(data.collect())
# 以表格形式展示数据
data.show()
输出:
[Row(item='iPhoneX', price=6000), Row(item='iPhone7', price=4000), Row(item='iPhone4', price=1000)]
+-------+-----+
| item|price|
+-------+-----+
|iPhoneX| 6000|
|iPhone7| 4000|
|iPhone4| 1000|
+-------+-----+
通过该例子,可了解df基本用法,只要从spark上下文加载完数据并转为dataframe类型后,之后调用df的api跟pandas的api大同小异,而且可将dataframe转为Spark SQL,直接使用sql语句操作数据。
上面的例子用了显示定义schema字段类型,pyspark支持自动推理创建df,也即无需原数据定义为rdd,和自动类型,直接传入Python列表的数据,以及定义字段名称即可:
a_list = [
(11, "iPhoneX",6000, datetime.date(2017,9,10)),
(12, "iPhone7",4000, datetime.date(2016,9,10)),
(13, "iPhone4",1000, datetime.date(2006,6,8))]
# 自动推理创建df,代码内部通过各类if 判断类型实现。
spark_df= spark.createDataFrame(a_list, schema=['id','item','price','pub_date'])
2.2 从各类数据源创建Spark DataFrame
相关接口方法参考官网文档
从csv文件创建Spark DataFrame
file =