1.第三方库不能和spark混在一起,原因有以下:
避免包冲突
避免spark升级时jar包造成困扰
避免很多依赖包都要用setJars
采用配置driver和excuter第三方库路径的方式:
spark.executor.extraClassPath /home/hadoop/SW/extra-libs/*
spark.driver.extraClassPath /home/hadoop/SW/extra-libs/*
2.ETL 抽取大表时性能问题:
Spark读取关系型数据库,官方有API接口,如下:
①、SparkSession.read.jdbc(url, table, properties),默认只有一个分区,当表很大时性能很差并且会oom
②、SparkSession.read.jdbc(url, table, columnName, lowerBound, upperBound, numPartitions, connectionProperties),需要指定分区字段和分区上下限,但对于客户的数据库,我们很多时候是很难掌控的这么详细,谁知道该用哪个字段做分区呢?
③、SparkSession.read.jdbc(url, table, predicates, connectionProperties) ,指定(分页)条件来分区,这个最为通用,对于像mysql非常好处理,因为mysql可以借助limit来实现分页,但oracle就很麻烦,通用的分页rownum需要嵌套才可以用,即便加了嵌套也无法完全用该方法实现,所以采用类似:
val tabSql=s"(SELECT * FROM (SELECT T.*, ROWNUM RN FROM (SELECT * FROM ${inputTableName}) T WHERE ROWNUM <= 20) WHERE RN >= 11)" 的方式来作为一张表,调用第一个api,默认一个分区,最终将所有df 进行合并来达到并行抽取的目标。
参考链接:
网友评论