spark-streaming数据量从1%提升到全量实战

2022-06-13 11:47:49

架构

这里写图片描述

背景

由于接入我们调用链计算平台的模块超过12个,kafka的topic超过24个,当初考虑到spark处理速度,以及抽样的可行性(google dapper论文论证过),我们只抽样1%处理。但是最近接入WF日志,要求全量处理,所以我们不得不提升spark任务的处理速度来满足这些要求。

spark参数优化

我们任务执行间隔是1分钟。优化前,我们的spark任务处理时间是处理2w条traceid需要50s左右,没有提升数据量的控件,所以必须提升任务执行速度。进行了如下操作:

提高executor-cores大小

提高并发是提高执行速度最有效的方法,但是由于我们原来使用的是Redis单机版,我将exector-cores参数设置为2时,就报链接拒绝错误,查询了下是redis单机版并发数多的时候就会出现这个问题。后来调整为redis集群,解决了这个问题,现在exector-cores设置为4

调整executor-memory

原先该参数executor-memory设置为4G,发现我们的任务并不需要,后来改为1G也能满足抽样1%的需求,我们的集群能力总内存是800G,而且还有其他任务在跑,所以如不需求那么多内存,可以调整该参数。这个参数的设置需要通过任务执行的情况来定,如果发现任务GC耗时比较大,或者出现OOM,那么请适当增大这个参数,因为我们要增加到全量,所以我暂时调整到6G,看实际运行情况后我再调整。

num-executors设置

num-executors从原先的30提升到目前的56(为了方便能被8个slave整除,所以设置了56个)

首次处理减压策略

因为首次启动JOB的时候,由于冷启动会造成内存使用太大,为了防止这种情况出现,限制首次处理的数据量

spark.streaming.backpressure.enabled=true
spark.streaming.backpressure.initialRate=200

2.x消息队列bug规避

Spark-streaming stage夯住原因分析

PHP端限制处理

由于单docker(4核16G)机器cpu的限制,目前一台docker只能在一分钟内处理2w条traceid,而且目前的ES系统也达不到每分钟存储200w条的数据量,所以我在php端做了限制,从sortedset中取所有的id,但是只保存2w条到queue中,其他全部删除。

后续等我们的智能计算系统上线后,我们会改变这个策略。核心代码:

这里写图片描述

Action

我们分3阶段提升,分别为1%提升到10%,10%提升到50%,50%提升到全量,每个阶段进行优化,逐步达到要求。

1%的处理速度

上面优化完成后,我们的处理速度由原先的高分期50s提升到15s左右,非高峰期20s提升到10s左右,效率提升50%+。

从1%提升到10%

高峰期

外卖业务高峰期从11点开始,我们观察了这个阶段的处理速度

这里写图片描述

这里写图片描述

平均处理时间:30s左右。

非高峰期

2点左右基本处于非高峰期

JOB处理速度

这里写图片描述

stage处理速度(分2个stage)

这里写图片描述
平均处理时间:15s左右。

状况描述

存储到Hbase和存储到Redis的耗时占比2:1,但是Hbase包括数据的计算,聚合的过程,所以还算正常。Redis只有存储的过程就消耗了约1/3的时间,但没达到瓶颈,暂时先不优化

从10%提升到50%

高峰

这里写图片描述

这里写图片描述

平均处理时间1min

非高峰期

这里写图片描述

这里写图片描述

平均处理耗时:50s

状况描述

非高峰期耗时已经达到45s左右,向Redis存储数据耗时偏大,已经接近1:1Hbase耗时了。看来不得不优化redis的写QPS了。
优化从两方面入手:

  • Jedis采用Pipeline添加数据
  • 提升RedisCluster的QPS

采用pipeline

因为JedisCluster官方没有提供Pipeline方法,所以找了一个个人开发的JedisClusterPipeline,使用了下效果很明显
Redis存储耗时非高峰期降低到1s左右,效果明显。非高峰期耗时如下

这里写图片描述

提升redis的qps

这里写图片描述

使用benchmark测了一下我们的qps,达到11w,按理说80w(高峰期)也用不到20多s,后来问了一下专业的OP,得到的回答是Sortedset是有序序列,存储速度会慢不少,而且不能通过提升节点来提升QPS。所以放弃了。

50%提升到全量

非高峰期

这里写图片描述

这里写图片描述

平均处理速度:30s。数据量是10G左右。traceid为55w左右。

下午时段

这里写图片描述

这里写图片描述

平均处理速度>1min,数据量在20G左右,traceid在100w左右

高峰期

这里写图片描述

这里写图片描述

已经gameover了,数据量约30G,traceid约170w。

状态分析

这个阶段redis的耗时已经不是问题了,问题已经在20G的处理量所耗用的时间太大,接近间隔时间1min了。所以又需要调优spark参数了。

调试了一整天后发现参数调优已经无法满足了,因为只有8台机器,12cpu,无论是24(num-executors)*4(executor-cores)还是8*12,或者120(num-executors)*1(executor-cores)都达到了机器计算瓶颈,无法再添加了,而且耗时还是超过了1min,所以参数已经解决不了。只能从下面3方面解决

  • 提升hbase的qps,目前一次性存储170wtraceid,30G的数据,耗时还是挺大,大约15s左右
  • 提升spark on yarn集群的机器,增加CPU数量增加计算能力
  • 代码层面优化,看看是否有优化的地方

由于前两个需要第三方解决,先从代码层面优化。

  • 作者:Q博士
  • 原文链接:https://doctorq.blog.csdn.net/article/details/68064460
    更新时间:2022-06-13 11:47:49