目录
1.系统架构
2.环境搭建
2.1本地环境下kafka批量导入数据
2.2 kafka-manager的安装与配置
3.1 Spark Streaming 性能调优(一): 解决并行度
3.2 Spark Streaming 性能调优(二): 解决task倾斜
根据前面几篇文章,运行该日志分析系统的环境与数据都已经准备好了,接下来就该进行调试与排查性能瓶颈了。
问题分析
首先, 根据前面的一篇文章:2.1 本地环境下kafka批量导入数据, 我分别模拟了数据在kafka的各个分区中分布均匀与分布不均匀两种情况.下面来看看运行结果对比:
测试环境: 本地, 开启4个线程
数据分布不均下task的执行情况
从上图可以看出, 在数据分布不均匀的情况下, 出现了部分task有数据,部分task却没有数据的情况, 导致机器的cpu资源没有得到充分利用.
task数据不均的原因
由于我这个日志分析系统是使用direct模式从kafka拉取数据的, 在direct模式下, 通过KafkaUtils.createDirectStream(...)获取的DStream中的rdd的分区数是与kafka相对应的topic的分区数是一样的,且分区中的数据分布情况也是一样的.
这就导致了spark streaming获取的rdd的分区中只有一个是有数据的, 而task与分区也是一一对应关系, 所以就造成了只有一个task在处理数据.
数据分布均匀下task执行情况
从上图可以看出, 数据均匀分布的话, 各个task处理的数据量都比较均匀, cpu资源的利用也提升了不少.
解决问题
问题逐渐清晰了, 其实就是线上从kafka获取数据时, kafka中的分区数据分布不均, 导致部分task处理的数据量特别少, 集群cpu资源得不到充分利用.
而解决办法就是, 利用DStream.reparation(partitionNum), 对DStream进行重新分区, 请注意, reparation()函数会对数据做shuffle, 这就相当于将数据分配到了其他机器上.这样就能提高并行度, 提高集群cpu资源利用率.