spark通过jdbc读取Oracle,当数据量很大的时候会出现两个问题:
- 读取数据异常缓慢,甚至卡死
- 大表中进行操作也会出现OOM的问题
调优
常规的读取数据库的方式如下
ods_bdz = spark.read.format(“jdbc”)
.option(“url”, “jdbc:oracle:thin:@”+dbstring)
.option(“dbtable”, “ODS_BDZ”)
.option(“user”, dbuser)
.option(“password”, dbpasswd)
.load()
常规jdbc读取表的时候只有一个分区在执行,也就是只有一个excutor在工作,没有把spark并行操作的特性发挥出来
通过查阅sparksql官方文档,查阅到如下的jdbc操作数据库的连接属性
属性名 | 含义 |
---|---|
url | 需要连接的JDBC URL |
dbtable | 需要读取的JDBC表。注意,任何可以填在SQL的where子句中的东西,都可以填在这里。(既可以填完整的表名,也可填括号括起来的子查询语句) |
driver | JDBC driver的类名。这个类必须在master和worker节点上都可用,这样各个节点才能将driver注册到JDBC的子系统中。 |
partitionColumn, lowerBound, upperBound, numPartitions | 这几个选项,如果指定其中一个,则必须全部指定。他们描述了多个worker如何并行的读入数据,并将表分区。partitionColumn必须是所查询的表中的一个数值字段。注意,lowerBound和upperBound只是用于决定分区跨度的,而不是过滤表中的行。因此,表中所有的行都会被分区然后返回。 |
fetchSize | JDBC fetch size,决定每次获取多少行数据。在JDBC驱动上设成较小的值有利于性能优化(如,Oracle上设为10) |
所以我们可以采取上表中所示的分区读表的方式来优化这个问题
- 当有数值字段的时候
这种情况是最好进行处理的,直接按数值字段分区处理即可。在此需要增加四个属性:numPartitions,partitionColumn,lowerBound,upperBound。
读数代码如下:
ods_bdz = spark.read.format(“jdbc”)
.option(“url”, “jdbc:oracle:thin:@”+dbstring)
.option(“dbtable”, “ods_bdz”)
.option(“user”, dbuser)
.option(“password”, dbpasswd)
.option(“numPartitions”, 20)
.option(“partitionColumn”, “part_num”)
.option(“lowerBound”, 1)
.option(“upperBound”, 20)
.load()
因为分区数是20,所以在oracle数据里面就会生成20条SQL,每条sql又一个excutor取读取。从未实现了分区读取的优化目的:
Select * from ods_bdz where part_num<2;
Select * from ods_bdz where part_num<3 and part_num>=2;
Select * from ods_bdz where part_num<4 and part_num>=3;
……
Select * from ods_bdz where part_num>=20;文章来源:https://www.toymoban.com/news/detail-413010.html
- 没有数值字段的时候,采用ROWID自定义分区键
ods_bdz = spark.read.format(“jdbc”)
.option(“url”, “jdbc:oracle:thin:@”+dbstring)
.option(“dbtable”, “(SELECT MOD(ASCII(SUBSTR(ROWID,-1)),20) RN,A.* FROM tab A)”)
.option(“user”, dbuser)
.option(“password”, dbpasswd)
.option(“numPartitions”, 20)
.option(“partitionColumn”, “RN”)
.option(“lowerBound”, 0)
.option(“upperBound”, 20)
.load()
采用ROWID的最后一位的ASCII码对20进行取模,得到的模是0-19之间的,这样就可以将这个值作为分区键,每条数据记录将会划分到固定的分区。文章来源地址https://www.toymoban.com/news/detail-413010.html
到了这里,关于Spark通过jdbc性能调优--采用分区的方式从oracle读数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!