Spark调优

数据倾斜的原理:

在进行shuffle的时候必须将各个节点上相同的key拉取到某个节点上的一个task来进行处理,
比如按照key进行聚合或join等操作,如果某个key对应的数据量特别大的话,就会发生数据
倾斜
  1. 解决方案一:使用Hive ETL预处理数据。将数据倾斜提前到上游的Hive ETL Spark作业时,执行速度都会很快
  2. 解决方案二:过滤少数导致倾斜的key。如果我们判断那少数几个数据量特别多的key,对作业的执行和计算结果不是特别重要的话,就直接过滤掉那少数几个key
  3. 解决方案三:提高shuffle操作的并行度。给shuffle算子传入一个参数,比如reduceByKey(1000)
  4. 解决方案四:两阶段聚合(局部聚合+全局聚合)。通过随机增加前缀的方式变成多个不同的key再聚合,然后去掉前缀再聚合
  5. 解决方案五:将reduce join转为map
    join。如果一个RDD是比较小的,则可以采用广播小RDD全量数据+map算子来实现与join同样的效果,也就是map join,此时就不会发生shuffle操作,也就不会发生数据倾斜
  6. 解决方案六:采样倾斜key并分拆join操作。思路:找出数据倾斜key,根据key拆分两个RDD,形成四个RDD,将会产生数据倾斜的RDD的key增加随机N以内前缀,对应join的rdd数据膨胀N倍;将他们进行join然后用union连接就是 最终的结果
  7. 解决方案七:使用随机前缀和扩容RDD进行join,跟方案六一样,只是这儿不拆分数据,不全部rdd进行增加随机前缀,扩容N倍

开发调优:

  • 原则一:避免重复创建RDD
  • 原则二:尽可能复用同一个RDD
  • 原则三:对多次使用的RDD进行持久persist(StorageLevel.MEMTORY_AND_DISK_SER)
  • 原则四:避免使用shuffle类算子 Broadcast+map的join操作,不会出现shuffle,前提是RDD数据量较小的时候
  • 原则五:使用map-side预聚合的shuffle操作,reduceByKey aggregateByKey代替groupByKey算子
  • 原则六:使用Kryo优化序列化性能 设置序列化
    conf.set(“spark.serializer”,“org.apache.spark.serializer.KryoSerializer”)
    注册需要序列化的自定义类型
    conf.registerKryoClasses(Array(classOf[MyClass1],classOf[MyClass2]))
  • 原则七:多使用高性能的算子
    reduceByKey aggregateByKey代替groupByKey算子
    mapPartitions代替map算子
    foreachPartitions代替foreach算子
    filter之后数据量就减少 coalesce 手动减少分区
  • 原则八:kafka直连模式,增大topic分区数,提高spark并发

kafka直连模式,与receiver模式区别

kafka的 receiver模式必须启动两个线程local[2],receiver对象启动的时候一直会在kafka中topic中的leader上面消费数据,
可以设置多个线程同时消费,在流式计算中如果 数据处理的时间大于数据摄入的时间间隔,会出现 数据丢失
或者一个批次的数据量占用内存大于给定executor的内存时,数据会丢失,streaming程序会出现各种问题。
当重启streaming程序的时候,很容易出现数据丢失,因为streaming挂掉的时候,处理的一部分数据的offset值并没有写进zk
为了避免这种情况,可以启动WAL(spark1.2)持久化日志到HDFS,但是非常消耗性能,有些记录在某些失败情况下可能会被消耗两次,
offset值在未写入到zk的时候streaming程序挂了,挂掉之前的数据 可能会被重复消费

kafka直连模式,增大topic分区数,提高spark并发
kafka Direct(spark1.3)模式这种模式下没有receiver

  • 1、并行更加简单,并发度与kafka的分区数一一对应
  • 2、高效,没有多次拷贝,效率更高,把kafka当做数据存储的一方
  • 3、只消费一次,offset值内存中存储,如果设置了checkpoint会在checkpoint中也保存一份,如果在保存偏移量的时候宕机,会产生重复消费。

直连模式 通过定期读取kafka中的topic+partirion的偏移量范围来获取数据
一个kafka的分区对应Dstream中RDD的一个分区,这个一一对应关注在RDD产生shuffle之后是不会保留的
这种方式需要我们自己管理偏移量offset值

参数调优:

  • num-executors 本次作业总的executors的数据,建议50-100合适
  • executor-memory 每个executor的使用内存,建议4g-8g
  • executor-cores 每个executor的使用核数,建议2-4个
  • driver-memory 在需要 collect 的时候需要将RDD的数据全部拉取到driver,此时如果Driver内存过小会出现 OOM情况,建议1g
  • spark.default.parallelism 表示每个stage的task数量,默认太小,建议设置为 500-1000
  • spark.storage.memoryFraction 表示在executor中持久化的比例默认0.6,如果需要大量数据持久化可以设置高一点,避免出现频繁GC
  • spark.shuffle.memoryFraction 表示在executor中shuffle内存占比默认0.2,如果需要大量数据shuffle可以设置高一点,避免频繁出现GC
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值