簡體   English   中英

來自Apache Spark Streaming中JavaRDD的多個元素的單個輸出請求

[英]A single output request from multiple elements of a JavaRDD in Apache Spark Streaming

摘要

我的問題是有關Apache Spark Streaming如何通過改進並行化或將許多寫入合並為一個較大的寫入來處理需要很長時間的輸出操作。 在這種情況下,寫操作是對Neo4J的密碼請求,但它可以應用於其他數據存儲。


環境

我有一個用Java寫的Apache Spark Streaming應用程序,它可以寫入2個數據存儲:Elasticsearch和Neo4j。 這些是版本:

  • Java 8
  • Apache Spark 2.11
  • Neo4J 3.1.1
  • Neo4J Java Bolt驅動程序1.1.2

當我將Elasticsearch-Hadoop用於Apache Spark庫時,Elasticsearch的輸出非常容易。


我們的流

我們的輸入是從Kafka接收的關於特定主題的流,我通過map函數反序列化流的元素以創建JavaDStream<[OurMessage]> dataStream 然后,我對此消息進行轉換,以創建一個密碼查詢String cypherRequest (使用OurMessage到String的轉換),該查詢發送到一個單例,該單例管理Bolt Driver與Neo4j的連接(我知道我應該使用連接池,但是也許這是另一個連接池)題)。 密碼查詢根據OurMessage的內容生成許多節點和/或邊。

該代碼如下所示。

dataStream.foreachRDD( rdd -> {
    rdd.foreach( cypherQuery -> {
        BoltDriverSingleton.getInstance().update(cypherQuery);
    });
});


優化的可能性

關於如何提高吞吐量,我有兩個想法:

  1. 我不確定Spark Streaming並行化是否下降到RDD元素級別。 意思是,RDD的輸出可以並行化(在stream.foreachRDD()內,但RDD的每個元素可以並行化在rdd.foreach()內),如果后者是這種情況,將減少在我們的`dataStream`上進行`轉換增加了Spark並行輸出此數據的能力(每個JavaRDD都將恰好包含一個密碼查詢)?
  2. 即使使用改進的並行化,如果我可以實現某種能夠將RDD的每個元素創建一個單獨的密碼查詢來添加所有元素的節點/邊緣的Builder,而不是為每個RDD進行一個密碼查詢,我們的性能將進一步提高。 但是,如何在不使用另一個kafka實例的情況下做到這一點呢?

我在想這個嗎? 我已經嘗試了很多研究,以至於我可能太深了。


旁白:如果其中任何一項完全錯誤,我謹此致歉。 您不知道不知道什么,而我剛剛開始使用Apache Spark和帶有lambda的Java 8。 正如Spark用戶現在必須知道的那樣,要么由於Spark模式不同而導致Spark學習曲線陡峭,要么我是個白痴:)。

感謝任何可能提供幫助的人; 這是很長時間以來我的第一個StackOverflow問題,所以請留下反饋,我會響應並根據需要糾正此問題。

我認為我們所需要的只是一個簡單的Map / Reduce。 以下內容將使我們能夠解析RDD中的每條消息,然后將其一次性全部寫入Graph DB。

dataStream.map( message -> {
    return (ParseResult) Neo4JMessageParser.parse(message);
}).foreachRDD( rdd -> {
    List<ParseResult> parseResults = rdd.collect();
    String cypherQuery = Neo4JMessageParser.buildQuery(parseResults);
    Neo4JRepository.update(cypherQuery);
    // commit offsets
});

這樣,我們應該能夠減少與必須為每個傳入消息進行寫操作相關的開銷。

暫無
暫無

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

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