[英]Write to elasticsearch from spark is very slow
我正在處理文本文件並從Spark應用程序將轉換后的行寫入到彈性搜索中,如下所示
input.write.format("org.elasticsearch.spark.sql")
.mode(SaveMode.Append)
.option("es.resource", "{date}/" + dir).save()
這運行非常慢,大約需要8分鍾才能寫入287.9 MB / 1513789記錄。
鑒於網絡延遲始終存在,我如何調整spark和elasticsearch設置以使其更快。
我在本地模式下使用Spark,並且具有16個內核和64GB RAM。 我的Elasticsearch集群有一個主節點和3個數據節點,每個節點有16個核心,每個核心64GB。
我正在閱讀以下文本文件
val readOptions: Map[String, String] = Map("ignoreLeadingWhiteSpace" -> "true",
"ignoreTrailingWhiteSpace" -> "true",
"inferSchema" -> "false",
"header" -> "false",
"delimiter" -> "\t",
"comment" -> "#",
"mode" -> "PERMISSIVE")
....
val input = sqlContext.read.options(readOptions).csv(inputFile.getAbsolutePath)
首先,讓我們從應用程序中發生的事情開始。 Apache Spark正在讀取1個(不是很大)壓縮的csv
文件。 因此,第一個spark將花費時間解壓縮數據並對其進行掃描,然后再將其寫入elasticsearch
。
這將創建一個分區的Dataset
/ DataFrame
(由df.rdd.getNumPartitions
提到的df.rdd.getNumPartitions
的結果確認)。
一種簡單的解決方案是在將數據寫入elasticsearch
之前對讀取的數據進行repartition
並對其進行緩存。 現在,我不確定您的數據是什么樣的,因此從您的角度確定分區數是基准。
val input = sqlContext.read.options(readOptions)
.csv(inputFile.getAbsolutePath)
.repartition(100) // 100 is just an example
.cache
我不確定您的應用程序能帶來多少好處,因為我相信可能還會存在其他瓶頸(網絡IO,ES的磁盤類型)。
PS:我應該先將csv轉換為Parquet文件,然后再在其上構建ETL。 在這里可以真正獲得性能。 (個人意見和基准)
另一種可能的優化方法是調整es.batch.size.entries
-spark連接器的es.batch.size.entries
設置。 默認值為1000
。
設置此參數時需要小心,因為您可能會使elasticsearch重載。 我強烈建議您在此處查看可用的配置。
我希望這有幫助 !
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.