Spark SQL支持数据源使用JDBC从其他数据库读取数据。 与使用JdbcRDD相比,应优先使用此功能。 这是因为结果以DataFrame的形式返回,并且可以轻松地在Spark SQL中进行处理或与其他数据源合并。 JDBC数据源也更易于从Java或Python使用,因为它不需要用户提供ClassTag。 (请注意,这与Spark SQL JDBC服务器不同,后者允许其他应用程序使用Spark SQL运行查询)。

首先,您需要在spark类路径上包含特定数据库的JDBC驱动程序。

例如,要从Spark Shell连接到postgres,您可以运行以下命令:

bin/spark-shell --driver-class-path postgresql-9.4.1207.jar --jars postgresql-9.4.1207.jar
  • Spark读取关系型数据库,官方有API接口,如下:

    ①、SparkSession.read.jdbc(url, table, properties)

    ②、SparkSession.read.jdbc(url, table, columnName, lowerBound, upperBound, numPartitions, connectionProperties)

    ③、SparkSession.read.jdbc(url, table, predicates, connectionProperties)
  1. 单partition方式:使用如下函数
def jdbc(url: String, table: String, properties: Properties): DataFrame

例子:

val url = "jdbc:mysql://mysqlHost:3306/database"
val tableName = "table" // 设置连接用户&密码
val prop = new java.util.Properties
prop.setProperty("user","username")
prop.setProperty("password","pwd") // 取得该表数据
val jdbcDF = spark.read.jdbc(url,tableName,prop) // 一些操作
jdbcDF.write.mode..

查看并发度

jdbcDF.rdd.partitions.size # 结果返回 1

该操作的并发度为1,你所有的数据都会在一个partition中进行操作,意味着无论你给的资源有多少,只有一个task会执行任务,执行效率可想而之,并且在稍微大点的表中进行操作分分钟就会OOM

更直观的说法是,达到千万级别的表就不要使用该操作,count操作就要等一万年,亲测4个小时 !

  1. 根据Long类型字段分区

    调用函数为
 def jdbc(
url: String,
table: String,
columnName: String, # 根据该字段分区,需要为整形,比如id等
lowerBound: Long, # 分区的下界
upperBound: Long, # 分区的上界
numPartitions: Int, # 分区的个数
connectionProperties: Properties): DataFrame

例子:

val url = "jdbc:mysql://mysqlHost:3306/database"
val tableName = "table" val columnName = "colName"
val lowerBound = 1,
val upperBound = 10000000,
val numPartitions = 10, // 设置连接用户&密码
val prop = new java.util.Properties
prop.setProperty("user","username")
prop.setProperty("password","pwd") // 取得该表数据
val jdbcDF = spark.read.jdbc(url,tableName,columnName,lowerBound,upperBound,numPartitions,prop) // 一些操作
....

查看并发度

jdbcDF.rdd.partitions.size # 结果返回 10
该操作将字段 colName 中1-10000000条数据分到10个partition中,使用很方便,缺点也很明显,只能使用整形数据字段作为分区关键字。
  1. 根据任意类型字段分区

    调用函数为
jdbc(
url: String,
table: String,
predicates: Array[String],
connectionProperties: Properties): DataFrame

例子:

val url = "jdbc:mysql://localhost:3306/db"
val tableName = "tablename" // 设置连接用户&密码
val prop = new java.util.Properties
prop.setProperty("user","mysql")
prop.setProperty("password","123456") val predicates =
Array(
"2018-10-01" -> "2018-11-01",
"2018-11-02" -> "2018-12-01",
"2018-12-02" -> "2019-01-01",
"2019-02-02" -> "2019-03-01",
"2019-03-02" -> "2019-04-01",
"2019-04-02" -> "2019-05-01",
"2019-05-02" -> "2019-06-01",
"2019-06-02" -> "2019-07-01",
"2019-07-02" -> "2019-08-01",
"2019-08-02" -> "2019-09-01",
"2019-09-02" -> "2019-10-01",
"2019-10-02" -> "2019-11-01"
).map {
case (start, end) =>
s"cast(txntime as date) >= date '$start' " + s"AND cast(txntime as date) <= date '$end'"
} // 取得该表数据
val jdbcDF = spark.read.jdbc(url, tableName, predicates, prop)
// 写入到hive表
jdbcDF.write.partitionBy().mode("overwrite").format("orc")
.saveAsTable("db.tableName")

一千万级别数据实测2.4min左右导入完成。

  1. limit分页分区

    依旧采用上述函数,但是partitions做了修改,例子:

val url = "jdbc:mysql://localhost:3306/db"
val tableName = "tablename" // 设置连接用户&密码
val prop = new java.util.Properties
prop.setProperty("user","mysql")
prop.setProperty("password","123456") def getPartition(count:Int) = {
val step = count / 10
Range(0, count, step).map(x =>{
(x, step)
}).toArray
}
val partitions = getPartition(10000000)
.map {
case (start,end) => s"1=1 limit ${start},${end}"
} // 取得该表数据
val jdbcDF = spark.read.jdbc(url, tableName, partitions, prop)
// 写入到hive表
jdbcDF.write.partitionBy().mode("overwrite").format("orc")
.saveAsTable("db.tableName")

实际测试效果和上面的差不多,区别是这里不需要字段有特殊的要求,对行数做处理就行啦。

Spark使用jdbc时的并行度的更多相关文章

  1. spark之JDBC开发(实战)

    一.概述 Spark Core.Spark-SQL与Spark-Streaming都是相同的,编写好之后打成jar包使用spark-submit命令提交到集群运行应用$SPARK_HOME/bin#. ...

  2. spark之JDBC开发(连接数据库测试)

    spark之JDBC开发(连接数据库测试) 以下操作属于本地模式操作: 1.在Eclipse4.5中建立工程RDDToJDBC,并创建一个文件夹lib用于放置第三方驱动包 [hadoop@CloudD ...

  3. 使用Spring Boot操作Hive JDBC时,启动时报出错误:NoSuchMethodError: org.eclipse.jetty.servlet.ServletMapping.setDef

    使用Spring Boot操作Hive JDBC时,启动时报出错误:NoSuchMethodError: org.eclipse.jetty.servlet.ServletMapping.setDef ...

  4. spark通过JDBC读取外部数据库,过滤数据

    官网链接: http://spark.apache.org/docs/latest/sql-programming-guide.html#jdbc-to-other-databases http:// ...

  5. streaming优化:spark.default.parallelism调整处理并行度

    官方是这么说的: Cluster resources can be under-utilized if the number of parallel tasks used in any stage o ...

  6. spark 操作Hive时遇到的问题

    To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).17/10/14 ...

  7. Spark读写HBase时出现的问题--RpcRetryingCaller: Call exception

    问题描述 Exception in thread "main" org.apache.hadoop.hbase.client.RetriesExhaustedException: ...

  8. Spark实际项目中调节并行度

    实际项目中调节并行度 实际项目中调节并行度 并行度概述 spark架构一览 如果不调节并行度,导致并行度过低,会怎么样? 设置spark作业并行度 小结 并行度概述 其实就是指的是,Spark作业中, ...

  9. Spark执行失败时的一个错误分析

    错误分析 堆栈信息中有一个错误信息:Job aborted due to stage failure: Task 1 in stage 2.0 failed 4 times, most recent ...

随机推荐

  1. python 读取 execl 文件 之 xlrd 模块

    1. 安装 xlrd模块 pip install xlrd 2. 读取文件内容 #!/usr/bin/env python3 import xlrd name = r"E:\excel\yo ...

  2. LeetCode--链表2-双指针问题

    LeetCode--链表2-双指针问题 思考问题: 判断一个链表是否有环 列举几种情况: graph LR A-->B B-->C C-->D D-->E E-->C g ...

  3. 01 Taro_Mall 开源多端小程序框架设计

    项目介绍 Taro_Mall是一款多端开源在线商城应用程序,后台是基于litemall基础上进行开发,前端采用Taro框架编写,现已全部完成小程序和h5移动端,后续会对APP,淘宝,头条,百度小程序进 ...

  4. CSS+JS相应式导航菜单

    响应式导航菜单 响应式导航菜单就是当网页在其他不同视口的样式,不同的设备需要不同的样式 需要掌握的知识 - 掌握媒体查询,如果你不是很懂那就看我写的CSS响应式布局 掌握CSS重的display:no ...

  5. 基于springboot多模块项目使用maven命令打成war包放到服务器上运行的问题

    首先,大家看到这个问题,可能并不陌生,而且脑子里第一映像就是使用mava中的clear package 或者 clear install进行打包,然后在项目中的target文件夹下面找到xxx.war ...

  6. 趣谈编程史第3期-大器晚成的新晋流量Python发展史

    写在前面 这篇博文主要介绍javaScript的发展史,根据作者在B站发布的同名视频的文案整理修改而成,对视频感兴趣的博友可访问https://www.bilibili.com/video/av860 ...

  7. axios下载文件乱码问题 无法解压 文件损坏

    /* 下载附件 */ downloadFile(fileName) { // window.open(url); var that = this; var url = "PO2116&quo ...

  8. Druid未授权(弱口令)的一些利用方式

    Druid简介 1.Druid是阿里巴巴数据库事业部出品,为监控而生的数据库连接池. 2.Druid提供的监控功能,监控SQL的执行时间.监控Web URI的请求.Session监控. Druid可能 ...

  9. MyISAM 和 InnoDB

    1.MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持.MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级 ...

  10. 《前端之路》- TypeScript(二) 函数篇

    目录 一.定义函数方法 二.定义函数传参 三.可选传参 四.默认传参 五.传递剩余参数 六.函数重载 七.箭头函数 八.总结 一.定义函数方法 在 es5 中定时函数的方法有 命名函数和函数表达式(匿 ...