Spark SQL百万级数据批量读写入MySQL

本文介绍了如何使用Spark SQL通过JDBC方式读取和批量写入MySQL数据。强调了在处理大规模数据时,需要指定分区以防止OOM,并提供了代码示例展示如何进行重分区和使用foreachPartition进行安全的批量写入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spark SQL读取MySQL的方式

Spark SQL还包括一个可以使用JDBC从其他数据库读取数据的数据源。与使用JdbcRDD相比,应优先使用此功能。这是因为结果作为DataFrame返回,它们可以在Spark SQL中轻松处理或与其他数据源连接。JDBC数据源也更易于使用Java或Python,因为它不需要用户提供ClassTag。

可以使用Data Sources API将远程数据库中的表加载为DataFrame或Spark SQL临时视图。用户可以在数据源选项中指定JDBC连接属性。 user和password通常作为用于登录数据源的连接属性。除连接属性外,Spark还支持以下不区分大小写的选项:

属性名称 解释
url 要连接的JDBC URL
dbtable 读取或写入的JDBC表
query 指定查询语句
driver 用于连接到该URL的JDBC驱动类名
partitionColumn, lowerBound, upperBound 如果指定了这些选项,则必须全部指定。另外, numPartitions必须指定
numPartitions 表读写中可用于并行处理的最大分区数。这也确定了并发JDBC连接的最大数量。如果要写入的分区数超过此限制,我们可以通过coalesce(numPartitions)在写入之前进行调用将其降低到此限制
queryTimeout 默认为0,查询超时时间
fetchsize JDBC的获取大小,它确定每次要获取多少行。这可以帮助提高JDBC驱动程序的性能
batchsize 默认为1000,JDBC批处理大小,这可以帮助提高JDBC驱动程序的性能。
isolationLevel 事务隔离级别,适用于当前连接。它可以是一个NONEREAD_COMMITTEDREAD_UNCOMMITTEDREPEATABLE_READ,或SERIALIZABLE,对应于由JDBC的连接对象定义,缺省值为标准事务隔离级别READ_UNCOMMITTED。此选项仅适用于写作。
sessionInitStatement 在向远程数据库打开每个数据库会话之后,在开始读取数据之前,此选项将执行自定义SQL语句,使用它来实现会话初始化代码。
truncate 这是与JDBC writer相关的选项。当SaveMode.Overwrite启用时,就会清空目标表的内容,而不是删除和重建其现有的表。默认为false
pushDownPredicate 用于启用或禁用谓词下推到JDBC数据源的选项。默认值为true,在这种情况下,Spark将尽可能将过滤器下推到JDBC数据源。

源码

  • SparkSession
/**
   * Returns a [[DataFrameReader]] that can be used to read non-streaming data in as a
   * `DataFrame`.
   * {
   {
   {
   *   sparkSession.read.parquet("/path/to/file.parquet")
   *   sparkSession.read.schema(schema).json("/path/to/file.json")
   * }}}
   *
   * @since 2.0.0
   */
  def read: DataFrameReader = new DataFrameReader(self)
  • DataFrameReader
  // ...省略代码...
  /**
   *所有的数据由RDD的一个分区处理,如果你这个表很大,很可能会出现OOM
   *可以使用DataFrameDF.rdd.partitions.size方法查看
   */
  def jdbc(url: String, table: String, properties: Properties): DataFrame = {
   
    assertNoSpecifiedSchema("jdbc")
    this.extraOptions ++= properties.asScala
    this.extraOptions += (JDBCOptions.JDBC_URL -> url, JDBCOptions.JDBC_TABLE_NAME -> table)
    format("jdbc").load()
  }
/**
   * @param url 数据库url
   * @param table 表名
   * @param columnName 分区字段名
   * @param lowerBound  `columnName`的最小值,用于分区步长
   * @param upperBound  `columnName`的最大值,用于分区步长.
   * @param numPartitions 分区数量 
   * @param connectionProperties 其他参数
   * @since 1.4.0
   */
  def jdbc(
      url: String,
      table: String,
      columnName: String,
      lowerBound: Long,
      upperBound: Long,
      numPartitions: Int,
      connectionProperties: Properties): DataFrame =
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值