我的逻辑如下。
使用createDirectStream在Kafka中按日志类型获取主题。
重新分区后,将通过各种处理处理日志。
使用combineByKey为每种日志类型创建一个字符串(使用StringBuilder)。
最后,按日志类型保存到HDFS。
有很多操作可以添加字符串,因此GC经常发生。
在这种情况下如何设置GC更好?
//////////////////////
有各种逻辑,但我认为在执行combineByKey时存在问题。
rdd.combineByKey[StringBuilder](
(s: String) => new StringBuilder(s),
(sb: StringBuilder, s: String) => sb.append(s),
(sb1: StringBuilder, sb2: StringBuilder) => sb1.append(sb2)
).mapValues(_.toString)
答案 0 :(得分:0)
使用combineByKey
表达式可以做的最大影响的最简单的事情是调整您创建的StringBuilder
的大小,以便在将字符串值合并到其中时不必扩展其后备字符数组;调整大小会放大分配率并通过从旧的后备阵列复制到新的后备阵列来浪费内存带宽。作为猜测,我会说选择结果数据集记录的字符串长度的第90个百分点。
要看第二件事(在收集关于中间值的一些统计数据之后),你的组合函数会选择StringBuilder
实例,当你调用{{1}时,该实例有空间适合另一个实例}。
照顾好的一件事就是使用Java 8;当字符串和字符串缓冲区工作繁重时,它有一些优化可以产生重大影响。
最后但并非最不重要的是,个人资料可以查看您实际花费周期的位置。这个工作量(不包括你正在做的任何其他自定义处理)不需要向老一代推广很多对象(如果有的话),所以你应该确保年轻一代有足够的规模并且是并行收集的。 / p>