Spark如何寫入HBase/Redis/MySQL/Kafka

來源:互聯網
上載者:User

標籤:producer   函數   data   redis   flush   mysq   executor   hba   ...   

一些概念

一個partition 對應一個task,一個task 必定存在於一個Executor,一個Executor 對應一個JVM.

  • Partition 是一個可迭代資料集合
  • Task 本質是作用於Partition的線程
問題

Task 裡如何使用Kafka Producer 將資料發送到Kafka呢。 其他譬如HBase/Redis/MySQL 也是如此。

解決方案

直觀的解決方案自然是能夠在Executor(JVM)裡有個Prodcuer Pool(或者共用單個Producer執行個體),但是我們的代碼都是
先在Driver端執行,然後將一些函數序列化到Executor端執行,這裡就有序列化問題,正常如Pool,Connection都是無法序列化的。

一個簡單的解決辦法是定義個Object 類,

譬如

object SimpleHBaseClient {  private val DEFAULT_ZOOKEEPER_QUORUM = "127.0.0.1:2181"  private lazy val (table, conn) = createConnection  def bulk(items:Iterator) = {      items.foreach(conn.put(_))      conn.flush....  }  ......}

然後保證這個類在map,foreachRDD等函數下使用,譬如:

dstream.foreachRDD{ rdd =>    rdd.foreachPartition{iter=>        SimpleHBaseClient.bulk(iter)      }}

為什麼要保證放到foreachRDD/map 等這些函數裡呢?
Spark的機制是先將使用者的程式作為一個單機運行(運行者是Driver),Driver通過序列化機制,將對應運算元規定的函數發送到Executor進行執行。這裡,foreachRDD/map 等函數都是會發送到Executor執行的,Driver端並不會執行。裡面引用的object 類 會作為一個stub 被序列化過去,object內部屬性的初始化其實是在Executor端完成的,所以可以避過序列化的問題。

Pool也是類似的做法。然而我們並不建議使用pool,因為Spark 本身已經是分布式的,舉個例子可能有100個executor,如果每個executor再搞10個connection
的pool,則會有100*10 個連結,Kafka也受不了。一個Executor 維持一個connection就好。

關於Executor掛掉丟資料的問題,其實就看你什麼時候flush,這是一個效能的權衡。

Spark如何寫入HBase/Redis/MySQL/Kafka

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.