SparkSQL操作Mysql

SparkSQL 提供了强大的功能来连接和操作 MySQL 数据库,支持读取数据、写入数据以及执行 SQL 查询。下面将详细介绍如何使用 SparkSQL 与 MySQL 进行交互,并提供完整的代码示例。

一、环境准备

  1. 安装 MySQL JDBC 驱动
    下载 mysql-connector-java,并将 JAR 文件添加到 Spark 的 classpath 中。

  2. 启动 SparkSession
    在创建 SparkSession 时,通过 config 参数指定 JDBC 驱动路径:

python

运行

from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("SparkMySQLIntegration") \
    .config("spark.jars", "/path/to/mysql-connector-java-*.jar") \
    .getOrCreate()

二、从 MySQL 读取数据

使用 spark.read.jdbc() 方法读取 MySQL 表数据:

python

运行

# MySQL 连接配置
url = "jdbc:mysql://localhost:3306/mydatabase"  # 数据库连接 URL
properties = {
    "user": "username",
    "password": "password",
    "driver": "com.mysql.cj.jdbc.Driver"  # MySQL 驱动类
}

# 读取整张表
df = spark.read.jdbc(url=url, table="mytable", properties=properties)

# 读取时指定查询条件(推荐:减少数据传输)
query = "(SELECT * FROM mytable WHERE category = 'electronics') AS subquery"
df = spark.read.jdbc(url=url, table=query, properties=properties)

# 查看数据
df.show()
df.printSchema()

三、向 MySQL 写入数据

使用 DataFrame.write.jdbc() 方法将数据写入 MySQL:

python

运行

# 示例 DataFrame
data = [("Alice", 25), ("Bob", 30), ("Charlie", 35)]
columns = ["name", "age"]
df = spark.createDataFrame(data, columns)

# 写入配置
url = "jdbc:mysql://localhost:3306/mydatabase"
properties = {
    "user": "username",
    "password": "password",
    "driver": "com.mysql.cj.jdbc.Driver"
}

# 写入模式:overwrite(覆盖)、append(追加)、ignore(存在则忽略)、error(默认,存在则报错)
df.write.jdbc(
    url=url,
    table="new_table",
    mode="overwrite",
    properties=properties
)

四、优化写入性能

  1. 批量写入
    通过 batchsize 参数控制每次写入的行数:

python

运行

properties = {
    "user": "username",
    "password": "password",
    "driver": "com.mysql.cj.jdbc.Driver",
    "batchsize": 1000  # 每批写入1000行
}

  1. 分区并行写入
    使用 repartition() 增加并行度:

python

运行

df.repartition(10).write.jdbc(
    url=url,
    table="new_table",
    mode="append",
    properties=properties
)

  1. 禁用自动提交
    通过 isolationLevel 参数减少事务开销:

python

运行

properties = {
    "user": "username",
    "password": "password",
    "driver": "com.mysql.cj.jdbc.Driver",
    "isolationLevel": "NONE"  # 禁用自动提交
}

五、执行复杂 SQL 查询

  1. 将 DataFrame 注册为临时表

    python

    运行

    df.createOrReplaceTempView("temp_table")
    result = spark.sql("SELECT name, age FROM temp_table WHERE age > 30")
    result.show()
    
  2. 直接执行原生 SQL

    python

    运行

    # 创建数据库连接
    from pyspark.sql import SQLContext
    sqlContext = SQLContext(spark)
    
    # 执行原生 SQL
    query = "SELECT * FROM mytable WHERE category = 'books'"
    result = sqlContext.read.jdbc(
        url=url,
        table=f"({query}) AS subquery",
        properties=properties
    )
    result.show()
    

六、处理数据类型映射

Spark 与 MySQL 之间的数据类型映射需注意:

Spark 数据类型MySQL 数据类型
StringTypeVARCHAR, TEXT
IntegerTypeINT
LongTypeBIGINT
DoubleTypeDOUBLE
BooleanTypeTINYINT(1)
TimestampTypeDATETIME, TIMESTAMP
DateTypeDATE

七、完整示例:读写 MySQL

python

运行

from pyspark.sql import SparkSession

# 创建 SparkSession
spark = SparkSession.builder \
    .appName("SparkMySQLExample") \
    .config("spark.jars", "/path/to/mysql-connector-java-8.0.26.jar") \
    .getOrCreate()

# 读取 MySQL 数据
url = "jdbc:mysql://localhost:3306/mydatabase"
properties = {
    "user": "root",
    "password": "password",
    "driver": "com.mysql.cj.jdbc.Driver"
}

# 读取表
df = spark.read.jdbc(url=url, table="products", properties=properties)
df.show()

# 数据转换
from pyspark.sql.functions import col
df_filtered = df.filter(col("price") > 100)
df_new = df_filtered.withColumn("discounted_price", col("price") * 0.9)

# 写入新表
df_new.write.jdbc(
    url=url,
    table="discounted_products",
    mode="overwrite",
    properties=properties
)

# 执行 SQL 查询
df_new.createOrReplaceTempView("temp_products")
result = spark.sql("SELECT category, AVG(discounted_price) FROM temp_products GROUP BY category")
result.show()

# 停止 SparkSession
spark.stop()

八、常见问题与解决方案

  1. ClassNotFoundException

    • 检查 JDBC 驱动 JAR 文件路径是否正确。
    • 确保所有 Worker 节点都能访问该 JAR 文件。
  2. 数据倾斜

    • 使用 repartition() 或 coalesce() 调整分区数。
    • 对写入表添加合适的索引。
  3. 写入性能低

    • 增大 batchsize 参数。
    • 禁用自动提交(isolationLevel=NONE)。
  4. 连接超时

    • 增加 connectTimeout 参数:

      python

      运行

      properties = {
          "user": "username",
          "password": "password",
          "driver": "com.mysql.cj.jdbc.Driver",
          "connectTimeout": "300"  # 连接超时时间(秒)
      }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值