Hive向SparkSQL迁移总结

Hive & SparkSQL使用不同点

  1. hive中对空格、制表符、大小写的不明感,spark-sql中敏感(通过压缩sql,去掉敏感符号;字段大小写要匹配)
  2. 在shell中提交hive -e 和spark-sql -e,spark-sql需要用""显式的把字符串引起来
  3. spark-sql -e 执行时转义符号需要修改为[],而不可以使用//

SparkSQL优化(Spark2.x)

现在网上的一些调优方式很大一部分在spark2.x已经自动调优

  1. spark-sql命令只有本地driver client模式没有custer模式 

参数调优

  1. 增大executor-memory内存,个数不要太多 (如果资源充足,增大内存能减少很多的异常)
  2. 控制executor-cores个数 (最好不要超过4个)
  3. spark.sql.shuffle.partitions=7000 (增大数shuffe时的并行度,依据依赖stage前后数量来设定)
  4. spark.yarn.executor.memoryOverhead 值为executorMemory * 0.07, with minimum of 384 (通常不够用,暂设为1024,需要再增加
  5. spark.sql.windowExec.buffer.spill.threshold=3000000 (默认值为4096,调优窗口函数中用到)
  6. mapred.output.compress=true mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec (输出文件压缩为gzip,减少45%的存储空间)
  7. spark.speculation=true (开启spark的推测机制,开启推测机制后如果某一台机器的几个task特别慢,推测机制会将任务分配到其他机器执行,最后Spark会选取最快的作为最终结果)
  8. spark.reducer.maxReqsInFlight=512,spark.reducer.maxSizeInFlight=96m (优化shuffle read time时间)
  9. --conf spark.dynamicAllocation.enabled=true --conf spark.shuffle.service.enabled=true --conf spark.dynamicAllocation.executorIdleTimeout=60s --conf spark.dynamicAllocation.schedulerBacklogTimeout=10s --conf spark.dynamicAllocation.minExecutors=2 --conf spark.dynamicAllocation.maxExecutors=300 (设置动态资源分配,如果设置了`--num-executors`(或`spark.executor.instances`)并且大于此值,它将用作执行程序的初始数。)
  10. spark.network.timeout=18000,默认为 120(120s),配置所有网络传输的延时,如果没有主动设置以下参数,默认覆盖其属性 spark.core.connection.ack.wait.timeout、spark.akka.timeout、spark.storage.blockManagerSlaveTimeoutMs、spark.shuffle.io.connectionTimeout、spark.rpc.askTimeout or spark.rpc.lookupTimeout

程序健壮性

  • --conf spark.sql.shuffle.partitions=10000 --conf spark.sql.adaptive.enabled=true --conf spark.sql.adaptive.shuffle.targetPostShuffleInputSize=512000000 (尽可能多设置shuffle并行度,开起Adaptive Execution,设置合并度小文件阀值,实现自我调节)

实际操作的中的问题

执行速度问题 

  • 处理的文件数据量较大,存在shuffle。由于部分节点存在网络问题,导致计算时间严重倾斜(在yarn下线了有问题的机器)

小文件问题

失败的尝试(参数调整)

  • --conf spark.default.parallelism=1000(无效,只适用于spak core,且文件可split)
  • --conf spark.sql.adaptive.enabled=true --conf spark.sql.adaptive.shuffle.targetPostShuffleInputSize=128000000 (无效,这个配置是应用于读取小文件处理)
  • --conf spark.sql.shuffle.partitions=1000 (无效,未发生shuffle;希望通过group by * 强制shuffle,但是字段中有Map类型…)
  • set hive.merge.mapfiles=true;set mapred.max.split.size=256000000;set mapred.min.split.size.per.node=192000000;set mapred.min.split.size.per.rack=192000000;set hive.input.format="org.apache.hadoop.hive.ql.io.CombineHiveInputFormat";(无效,原因未排查,可能也是未shuffle)

失败的尝试(直接编写为spark core)

  • repartition(有效,但10000->1000的shuffle时间已经超过了计算花费的时间,需要设置非常大的memoryOverhead)
  • coalesce (无效,原因没有产生shuffle)

文件问题

  • 文件为列式存储结构 parquet,利用spark2.x sql查询时抛异常 CorruptStatistics: Ignoring statistics because created_by could not be parsed (see PARQUET-251): parquet-mr (更改的配置文件$SPARK_HOME / conf / log4j.properties,log4j.logger.org.apache.parquet=ERROR)

参数问题

  • 如果参数属性不是spark特有的属性,通过 --conf 配置无效,需要在hive中配置如:set hive.exec.compress.output=true;

序列化问题 

  • 设置 spark.serializer = org.apache.spark.serializer.KryoSerializer 对优化spark sql 没有效果(spark sql 数据集与RDD类似,但是,它们不使用Java序列化或Kryo,而是使用专用的编码器来序列化对象以便通过网络进行处理或传输。虽然编码器和标准序列化都负责将对象转换为字节,但编码器是动态生成的代码,并使用一种格式,允许Spark执行许多操作,如过滤,排序和散列,而无需将字节反序列化为对象) 

导出查询结果 

使用hive -e 或 spark-sql -e 在后面的SQL语句中如果有特殊符号需要转义,请使用 " [] "。不要使用 " \\ " 查询会出现问题,但在CLI中使用没有问题
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值