我正在研究一个研究项目,我在Google Cloud Platform上安装了完整的数据分析管道。我们使用Spark上的HyperLogLog实时估算每个URL的唯一访问者。我使用Dataproc来设置Spark Cluster。此工作的一个目标是根据群集大小测量体系结构的吞吐量。 Spark集群有三个节点(最小配置)
使用Java编写的自己的数据生成器模拟数据流,其中我使用了kafka生成器API。该体系结构如下所示:
数据生成器 - >卡夫卡 - > Spark Streaming - > Elasticsearch。
问题是:随着我在数据生成器上每秒增加生成事件的数量并超过~1000个事件/秒,我的Spark作业中的输入速率突然崩溃并开始变化很多。
正如您在Spark Web UI的屏幕截图中看到的那样,处理时间和调度延迟保持不变,而输入速率则下降。
我使用完整的简单Spark作业对其进行了测试,该作业只进行了简单的映射,以排除缓慢的Elasticsearch写入或作业本身问题等原因。卡夫卡似乎也正确接收和发送所有事件。
此外,我尝试了Spark配置参数:
spark.streaming.kafka.maxRatePerPartition
和spark.streaming.receiver.maxRate
结果相同。
有没有人有一些想法在这里出了什么问题?它似乎取决于Spark Job或Dataproc ......但我不确定。所有CPU和内存利用似乎都没问题。
编辑:目前我在该主题上有两个kafka分区(放在一台机器上)。但我认为Kafka甚至应该只有一个分区执行超过1500个事件/秒。问题还在于我实验开始时的一个分区。我使用没有接收器的直接方法,因此Spark从主题中简单地读取了两个工作节点。
编辑2:我发现导致这种糟糕吞吐量的原因。我忘记在我的架构中提到一个组件。我使用一个中央Flume代理通过netcat从log4j记录我的模拟器实例中的所有事件。这种水槽剂是性能问题的原因!我通过disruptor更改了log4j配置以使用异步记录器(https://logging.apache.org/log4j/2.x/manual/async.html)。我将Flume代理扩展到更多CPU内核和RAM,并将通道更改为文件通道。但它仍然表现不佳。没有效果......任何其他想法如何调整Flume性能?
答案 0 :(得分:0)
很难说信息量很少。我怀疑是内存问题 - 在某些时候,服务器甚至可能开始交换。因此,请检查所有服务器上的JVM内存利用率和交换活动。 Elasticsearch应该能够处理~15,000记录/秒而几乎没有调整。检查服务器上的空闲和已提交的RAM。
答案 1 :(得分:0)
正如我之前提到的,CPU和RAM的使用率非常好。我发现了一个"魔法极限",它似乎正好是每秒1500个事件。当我超过此限制时,输入速率立即开始摆动。
奇怪的是,处理时间和调度延迟保持不变。所以可以排除背压效应,对吧?
我唯一可以猜到的是GCP / Dataproc的技术限制......我没有在Google文档中找到任何提示。
其他一些想法?