簡體   English   中英

Apache Spark-SQL 與 Sqoop 基准測試,同時將數據從 RDBMS 傳輸到 hdfs

[英]Apache Spark-SQL vs Sqoop benchmarking while transferring data from RDBMS to hdfs

我正在研究一個用例,我必須將數據從 RDBMS 傳輸到 HDFS。 我們已經使用 sqoop 對這個案例進行了基准測試,發現我們能夠在 6-7 分鍾內傳輸大約 20GB 的數據。

當我嘗試使用 Spark SQL 時,性能非常低(1 Gb 的記錄從 netezza 傳輸到 hdfs 需要 4 分鍾)。 我正在嘗試進行一些調整並提高其性能,但不太可能將其調整到 sqoop 級別(1 分鍾內大約 3 Gb 的數據)。

我同意 spark 主要是一個處理引擎的事實,但我的主要問題是 spark 和 sqoop 都在內部使用 JDBC 驅動程序,所以為什么性能差異如此之大(或者我可能遺漏了什么)。 我在這里發布我的代碼。

object helloWorld {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("Netezza_Connection").setMaster("local")
    val sc= new SparkContext(conf)
    val sqlContext = new org.apache.spark.sql.hive.HiveContext(sc)
    sqlContext.read.format("jdbc").option("url","jdbc:netezza://hostname:port/dbname").option("dbtable","POC_TEST").option("user","user").option("password","password").option("driver","org.netezza.Driver").option("numPartitions","14").option("lowerBound","0").option("upperBound","13").option("partitionColumn", "id").option("fetchSize","100000").load().registerTempTable("POC")
    val df2 =sqlContext.sql("select * from POC")
    val partitioner= new org.apache.spark.HashPartitioner(14)
    val rdd=df2.rdd.map(x=>(String.valueOf(x.get(1)),x)).partitionBy(partitioner).values
    rdd.saveAsTextFile("hdfs://Hostname/test")
  }
}

我已經檢查了許多其他帖子,但無法得到關於 sqoop 的內部工作和調整的明確答案,也沒有得到 sqoop 與 spark sql 基准測試。請幫助理解這個問題。

您正在使用錯誤的工具來完成這項工作。

Sqoop 將啟動一系列進程(在數據節點上),每個進程都會連接到您的數據庫(請參閱 num-mapper),並且每個進程都會提取數據集的一部分。 我不認為您可以使用 Spark 實現某種讀取並行性。

使用 Sqoop 獲取數據集,然后使用 Spark 進行處理。

您可以嘗試以下操作:-

  1. 從沒有任何分區的 netezza 讀取數據,並將 fetch_size 增加到一百萬。

     sqlContext.read.format("jdbc").option("url","jdbc:netezza://hostname:port/dbname").option("dbtable","POC_TEST").option("user","user").option("password","password").option("driver","org.netezza.Driver").option("fetchSize","1000000").load().registerTempTable("POC")
  2. 在將數據寫入最終文件之前重新分區數據。

     val df3 = df2.repartition(10) //to reduce the shuffle
  3. ORC 格式比 TEXT 更優化。 將最終輸出寫入 parquet/ORC。

     df3.write.format("ORC").save("hdfs://Hostname/test")

@amitabh 雖然標記為答案,但我不同意。

一旦您在從 jdbc 讀取數據時給出了對數據進行分區的謂詞,spark 將為每個分區運行單獨的任務。 在您的情況下,任務數不應為 14(您可以使用 spark UI 確認這一點)。

我注意到您使用 local 作為 master,它只會為執行程序提供 1 個核心。 因此不會有並行性。 這就是你的情況。

現在要獲得與 sqoop 相同的吞吐量,您需要確保這些任務並行運行。 理論上,這可以通過以下方式完成: 1. 使用 14 個執行器,每個執行器具有 1 個核心 2. 使用 1 個執行器和 14 個核心(頻譜的另一端)

通常,我會為每個執行程序使用 4-5 個內核。 因此,我使用 15/5= 3 個執行程序測試了性能(我添加了 1 到 14 個以考慮為在集群模式下運行的驅動程序使用 1 個內核)。 使用:sparkConf.set 中的 executor.cores、executor.instances 來使用配置。

如果這不會顯着提高性能,那么接下來就是查看執行程序內存。

最后,我將調整應用程序邏輯以查看 mapRDD 大小、分區大小和 shuffle 大小。

我遇到了同樣的問題,因為您使用的代碼段不適用於分區。

sqlContext.read.format("jdbc").option("url","jdbc:netezza://hostname:port/dbname").option("dbtable","POC_TEST").option("user","user").option("password","password").option("driver","org.netezza.Driver").option("numPartitions","14").option("lowerBound","0").option("upperBound","13").option("partitionColumn", "id").option("fetchSize","100000").load().registerTempTable("POC")

您可以通過以下方式檢查在您的火花作業中創建的分區數

df.rdd.partitions.length

您可以使用以下代碼連接數據庫:

sqlContext.read.jdbc(url=db_url,
    table=tableName,
    columnName="ID",
    lowerBound=1L,
    upperBound=100000L,
    numPartitions=numPartitions,
    connectionProperties=connectionProperties) 

要優化您的 Spark 作業,請使用以下參數: 1. 分區數 2. --num-executors 3.--executor-cores 4. --executor-memory 5. --driver-memory 6. fetch-size

2,3,4 和 5 選項取決於您的集群配置,您可以在 spark ui 上監控您的 spark 作業。

以下解決方案幫助了我

var df=spark.read.format("jdbc").option("url","
"url").option("user","user").option("password","password").option("dbTable","dbTable").option("fetchSize","10000").load()
df.registerTempTable("tempTable")
var dfRepart=spark.sql("select * from tempTable distribute by primary_key") //this will repartition the data evenly

dfRepart.write.format("parquet").save("hdfs_location")

Sqoop 和 Spark SQL 都使用 JDBC 連接從 RDBMS 引擎獲取數據,但 Sqoop 在這方面有優勢,因為它專門用於在 RDBMS 和 HDFS 之間遷移數據。

Sqoop 中可用的每個選項都經過微調,以便在進行數據攝取時獲得最佳性能。

您可以從討論控制映射器數量的選項 -m 開始。

這是從 RDBMS 並行獲取數據所需的操作。 我可以在 Spark SQL 中做到嗎? 當然可以,但開發人員需要處理 Sqoop 一直在自動處理的“多線程”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM