在Spark的执行过程中,涉及到一些关键角色和概念,如Client、Job、Master、Worker、Driver、Stage、Task以及Executor。
Spark应用程序从Client提交到Master,由Master将作业划分为不同的Stage并分配给Worker节点上的Executor执行。每个Executor并行执行多个Task,最终完成Spark应用程序的计算任务。
常见的Spark部署模式:
Local 模式:在Local模式下,Spark运行在单个机器上,通常用于开发和测试目的。在这种模式下,Spark只使用单个线程进行计算,并且不涉及分布式计算和集群。这是最简单的部署模式,适用于在本地机器上快速验证Spark应用程序。
Standalone 模式:Standalone模式是Spark自带的独立部署模式,它是一种简单的分布式模式,支持在独立的集群上运行Spark应用程序。在这种模式下,Spark Master和Worker都运行在同一个集群上,Spark应用程序通过连接到Spark Master进行任务的提交和分配。
YARN 模式:
YARN(Yet Another Resource Negotiator)是Hadoop的资源管理器,Spark可以在YARN上运行,利用Hadoop集群的资源进行计算。在YARN模式下,Spark作为YARN的客户端,通过YARN资源管理器向集群请求资源,并在集群上运行Spark应用程序。
Mesos 模式:Mesos是一个通用的集群管理器,Spark可以在Mesos上运行,充分利用集群资源进行计算。在Mesos模式下,Spark作为Mesos的框架,通过Mesos Master向集群请求资源,并在Mesos Slave上运行Spark应用程序。
Kubernetes 模式:Kubernetes是一个容器编排平台,Spark可以在Kubernetes上运行,利用容器化的方式进行资源管理和任务调度。在Kubernetes模式下,Spark应用程序作为Kubernetes的Pod运行,并通过Kubernetes调度器管理资源。
不同的部署模式适用于不同的场景和需求。Local模式适用于开发和测试,Standalone模式适用于简单的分布式部署,YARN和Mesos模式适用于与Hadoop或Mesos集成的部署,而Kubernetes模式适用于容器化的部署。
SparkContext是PySpark的核心组件之一,它是与Spark集群通信的主要入口点。在Spark中,SparkContext实例化之后,可以使用它来创建RDD和广播变量,还可以配置Spark应用程序的行为。
Spark Session是一个代表Spark应用程序与Spark集群交互的入口点。它是Spark 2.0及以上版本中引入的概念,取代了之前版本中的SparkContext和SQLContext,并将它们的功能整合在一个统一的接口中。
Spark Session提供了许多功能,使得在Spark应用程序中更加方便地使用Spark的各项功能,包括:
在Python中,创建Spark Session非常简单,只需要使用SparkSession.builder创建一个Spark Session实例,并通过getOrCreate()方法获取Spark Session。例如:
from pyspark.sql import SparkSession
# 创建Spark Session
spark = SparkSession.builder \
.appName("MySparkApp") \
.config("spark.some.config.option", "config-value") \
.getOrCreate()
# 使用Spark Session创建DataFrame或执行SQL查询等操作
在Spark应用程序中,通常只需要一个Spark Session实例,它会自动根据需要懒惰地初始化SparkContext和SQLContext,并自动对其进行管理。
RDD(弹性分布式数据集)是Spark的核心数据抽象,是一个分布式的、不可变的数据集合。它是Spark中最基本的数据单元,表示分布在集群中多个节点上的数据项的集合。RDD是可并行计算的,可以在集群的多个节点上同时进行计算。
在RDD(弹性分布式数据集)中,有两种主要类型的操作:转换操作(Transformations)和行动操作(Actions)。这些操作是用来处理和计算分布在Spark集群中的数据。
Broadcast变量允许在集群的所有节点上缓存一个只读变量,这样每个节点都可以有效地共享同一个变量,从而减少数据的传输开销。Accumulator用于在集群的所有节点上聚合数据,例如用于累加计数。例如
broadcast_var = sc.broadcast([1, 2, 3, 4, 5])
accumulator = sc.accumulator(0) # 初始化一个累加器
# 在RDD上累加值
rdd.foreach(lambda x: accumulator.add(x))
SparkConf是Spark的配置类,用于设置和配置Spark应用程序的参数。它允许您在创建SparkContext或SparkSession之前,指定Spark应用程序的各种配置选项。
SparkFiles是一个工具类,用于在Spark集群的所有节点上分发文件和访问这些文件。通常,当您需要在Spark任务中使用文件时,可以使用SparkFiles将文件分发到集群的所有节点,然后在任务中使用分发的文件路径。
SparkFiles提供了两个主要功能:
以下是示例
from pyspark import SparkFiles
# 将文件分发到集群的所有节点
sc.addFile("file.txt")
# 在任务中使用分发的文件
def process_file(file_path):
with open(file_path, "r") as file:
data = file.read()
# 在此处处理文件内容
return data
# 获取分发文件的本地路径
file_path = SparkFiles.get("file.txt")
# 在任务中使用文件
result = sc.parallelize([file_path]).map(process_file).collect()
Storage Level(存储级别)是用于控制RDD(弹性分布式数据集)持久化的选项。RDD的持久化是将RDD的数据存储在内存或磁盘上,以便可以在后续的计算中重复使用,避免重复计算。存储级别可以控制RDD的数据在内存和磁盘之间的存储和处理方式,以平衡性能和资源使用。
在PySpark中,有多种存储级别可供选择,每种存储级别都有不同的特性和适用场景。以下是一些常见的存储级别:
# 在创建RDD时,可以使用persist()或cache()方法来指定存储级别
data = [1, 2, 3, 4, 5]
rdd = sc.parallelize(data)
# 使用MEMORY_AND_DISK_SER存储级别持久化RDD
rdd.persist(StorageLevel.MEMORY_AND_DISK_SER)
Spark SQL是Apache Spark的结构化数据处理组件,它提供了在Spark中使用SQL语言进行数据查询和处理的功能。Spark SQL允许您在Spark应用程序中使用标准的SQL语法,来处理结构化数据,包括表格数据、CSV文件、Parquet文件、JSON数据等。它为开发人员提供了一种更简单、更直观的方式来处理结构化数据,而无需编写复杂的Spark代码。
spark sql读取数据的方法
from pyspark.sql import SparkSession
# 创建SparkSession
spark = SparkSession.builder \
.appName("ReadTextFileExample") \
.getOrCreate()
# 从文本文件读取数据并创建DataFrame
text_df = spark.read.text("data.txt")
# 从CSV文件读取数据并创建DataFrame
csv_df = spark.read.csv("data.csv", header=True, inferSchema=True)
# 从Parquet文件读取数据并创建DataFrame
parquet_df = spark.read.parquet("data.parquet")
# 从JSON数据读取数据并创建DataFrame
json_df = spark.read.json("data.json")
# 从JDBC数据库读取数据并创建DataFrame,定义数据库连接属性
url = "jdbc:mysql://localhost:3306/your_database_name"
properties = {
"user": "your_username",
"password": "your_password",
"driver": "com.mysql.jdbc.Driver"
}
jdbc_df = spark.read.jdbc(url, table="your_table_name", properties=properties)
# 从Hive表读取数据并创建DataFrame
spark = SparkSession.builder \
.appName("ReadHiveTableExample") \
.enableHiveSupport() \
.getOrCreate()
hive_df = spark.table("your_hive_table_name")
# 读取hive数据库
spark.sql("CREATE TABLE IF NOT EXISTS src (key INT, value STRING) USING hive")
spark.sql("LOAD DATA LOCAL INPATH 'data/kv1.txt' INTO TABLE src")
df = spark.sql("SELECT key, value FROM src WHERE key < 10 ORDER BY key")
# 5.2 读取mysql数据库
url = "jdbc:mysql://localhost:3306/test"
df = spark.read.format("jdbc") \
.option("url", url) \
.option("dbtable", "runoob_tbl") \
.option("user", "root") \
.option("password", "8888") \
.load()\
在PySpark中,您可以使用DataFrame API或RDD API将数据保存或写入不同的数据源。Spark支持将数据写入到各种格式的文件(如CSV、Parquet、JSON等),以及数据库(如Hive、MySQL等)。以下是保存数据的一些常见方法:
from pyspark.sql import SparkSession
spark = SparkSession.builder \
.appName("SaveDataFrameToCSV") \
.getOrCreate()
df = spark.read.csv("data.csv", header=True, inferSchema=True)
# 保存为CSV文件
df.write.csv("output.csv", header=True)
# 保存为Parquet文件
df.write.parquet("output.parquet")
# 保存为JSON文件
df.write.json("output.json")
# 保存到Hive表
df.write.saveAsTable("hive_table_name")
DataFrame是一个类似于SQL表的分布式数据集,是Spark中最常用的数据结构之一。DataFrame提供了更高级的API和更多的优化,用于处理和分析结构化数据。它是由行和列组成的分布式数据集合,类似于pandas里的dataframe。创建DataFrame的常见方式有:
# 从本地集合创建DataFrame
data = [("Alice", 34), ("Bob", 45), ("Cathy", 29)]
columns = ["Name", "Age"]
df = spark.createDataFrame(data, columns)
# 从RDD创建
rdd = sc.parallelize([("Sam", 28, 88), ("Flora", 28, 90), ("Run", 1, 60)])
df = rdd.toDF(["name", "age", "score"])
# 从文件创建DataFrame
df = spark.read.csv("data.csv", header=True, inferSchema=True)
可以使用Spark SQL来执行SQL查询和操作DataFrame。通过SparkSession可以将DataFrame注册为临时表或全局表,然后可以使用SQL语句查询这些表。
from pyspark.sql import SparkSession
spark = SparkSession.builder \
.appName("MyApp") \
.master("local") \
.getOrCreate()
data = [("Alice", 34), ("Bob", 45), ("Cathy", 29)]
columns = ["Name", "Age"]
df = spark.createDataFrame(data, columns)
# 通过SparkSession可以将DataFrame注册为临时表
df.createOrReplaceTempView("people")
result = spark.sql("SELECT * FROM people WHERE Age > 30")
在PySpark中,SQL函数(SQL Functions)是一组用于数据处理和转换的内置函数,它们可以在SQL查询或DataFrame API中使用。PySpark提供了许多常见的SQL函数,用于字符串处理、数值计算、日期时间操作等,以及自定义函数的创建和使用。
以下是一些常用的PySpark SQL函数示例:
字符串处理函数:
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, concat_ws, upper
# 创建SparkSession
spark = SparkSession.builder \
.appName("SQLFunctionsExample") \
.getOrCreate()
# 创建DataFrame
data = [("John", "Doe"), ("Alice", "Smith"), ("Mike", "Brown")]
df = spark.createDataFrame(data, ["first_name", "last_name"])
# 使用concat_ws函数连接两列,以空格分隔
df.withColumn("full_name", concat_ws(" ", col("first_name"), col("last_name"))).show()
# 使用upper函数将文本转换为大写
df.withColumn("upper_first_name", upper(col("first_name"))).show()
数值计算函数:
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, round, sqrt
# 创建SparkSession
spark = SparkSession.builder \
.appName("SQLFunctionsExample") \
.getOrCreate()
# 创建DataFrame
data = [(1, 2), (3, 4), (5, 6)]
df = spark.createDataFrame(data, ["col1", "col2"])
# 使用round函数对列进行四舍五入
df.withColumn("rounded_col1", round(col("col1"), 2)).show()
# 使用sqrt函数计算平方根
df.withColumn("sqrt_col2", sqrt(col("col2"))).show()
日期时间函数:
from pyspark.sql import SparkSession
from pyspark.sql.functions import col, current_date, date_format
# 创建SparkSession
spark = SparkSession.builder \
.appName("SQLFunctionsExample") \
.getOrCreate()
# 创建DataFrame
data = [(1, "2023-07-25"), (2, "2023-07-26"), (3, "2023-07-27")]
df = spark.createDataFrame(data, ["id", "date_str"])
# 使用current_date函数获取当前日期
df.withColumn("current_date", current_date()).show()
# 使用date_format函数格式化日期
df.withColumn("formatted_date", date_format(col("date_str"), "yyyy-MM-dd")).show()
PySpark Streaming是Apache Spark中的实时数据流处理组件,它允许您对实时数据流进行高效处理,并将数据流切分为小批次进行分布式处理。PySpark Streaming使用微批处理的方式,将连续的实时数据划分为小批次,然后在Spark集群上并行处理这些小批次,从而实现实时的数据处理和分析。
使用PySpark Streaming的一般步骤如下:
MLlib(Machine Learning Library)是Spark中用于机器学习的库,提供了各种常见的机器学习算法和工具,如分类、回归、聚类、特征提取等。
MLlib的功能可以分为以下几个方面: