2011-06-28 78 views
1

我有一個分析日誌文件並將彙總輸出寫入S3的Pig任務。我不想將輸出寫入S3,而是想將其轉換爲JSON有效負載並將其發佈到URL。將Hadoop Pig作爲JSON數據輸出到URL中?

一些注意事項:

  • 此作業在Amazon Elastic MapReduce的運行。
  • I 可以使用STREAM通過外部命令傳輸數據,並從那裏加載數據。但是因爲Pig從不向外部命令發送EOF,這意味着我需要在每行到達時對其進行POST,並且我無法批量處理它們。顯然,這會傷害表現。

解決此問題的最佳方法是什麼? PiggyBank或​​其他庫中是否有可用的內容?或者我應該寫一個新的存儲適配器?感謝您的建議!

+0

事實證明,豬_does_發送EOFs。請參閱下面的接受答案。 – emk

回答

0

事實證明,Pig 確實正確地將EOF發送到外部命令,因此您可以選擇通過外部腳本來傳輸所有內容。如果它不是工作,那麼你可能有一個難以調試的配置問題。

以下是如何開始。定義一個外部命令,如下所示,使用任何你需要解釋和腳本:

DEFINE UPLOAD_RESULTS `env GEM_PATH=/usr/lib/ruby/gems/1.9.0 ruby1.9 /home/hadoop/upload_results.rb`; 

流過你的腳本結果:

/* Write our results to our Ruby script for uploading. We add 
    a trailing bogus DUMP to make sure something actually gets run. */ 
empty = STREAM results THROUGH UPLOAD_RESULTS; 
DUMP empty; 

從Ruby中,你可以批量輸入記錄到的1024塊:

STDIN.each_line.each_slice(1024) do |chunk| 
    # 'chunk' is an array of 1024 lines, each consisting of tab-separated 
    # fields followed by a newline. 
end 

如果無法正常工作,仔細檢查以下內容:

  1. 您的腳本是否從命令行工作?
  2. 從Pig運行時,腳本是否具有所有必需的環境變量?
  3. 您的EC2引導程序操作是否正常工作?

其中一些很難驗證,但是如果它們中的任何一個都失敗了,那麼很容易就會浪費很多時間進行調試。

但是,請注意,您應該強烈考慮mat kelcey推薦的替代方法。

4

而不是流,你可以寫一個UDF(UDF以來的提供完成()回調)[1]

另一種方法可以做POST作爲第二傳過來的數據。

  1. 現有豬的步驟,只是寫出到一個單一的關係作爲JSON字符串中使用NLineInputFormat做郵政批次的

  • 一個簡單的數據流作業,我總是青睞的做法這種風格,因爲它分離關注點並使豬代碼清潔。

    它還允許您(在我的腦海中)在您的工作的POST部分更簡單的調整選項。在這種情況下,根據您接收的Web服務的冪等性,關閉推測執行(可能)很重要。要注意的是你的集羣中運行大量併發作業完全可以殺死一個服務器太:d

    例如,對於在20批次發佈...

     
    $ hadoop jar ~/contrib/streaming/hadoop-streaming.jar \ 
        -D mapred.line.input.format.linespermap=20 \ 
        -D mapred.reduce.tasks.speculative.execution=false \ 
        -input json_data_to_be_posted -output output \ 
        -mapper your_posting_script_here.sh \ 
        -numReduceTasks 0 \ 
        -inputformat org.apache.hadoop.mapred.lib.NLineInputFormat 
    
    

    [1] http://pig.apache.org/docs/r0.7.0/api/org/apache/pig/EvalFunc.html#finish%28%29

  • 1

    也許你應該處理Pig之外的數據發佈。我發現,包裝我的豬通常比做一個職位(沒有雙關語意圖)處理步驟的UDF更容易。如果您不希望它觸及S3,則可以使用dump而不是store並處理要發佈的標準。否則,將它存儲在S3中,然後用hadoop fs -cat outputpath/part*將其取出,然後用curl或其他東西發送出去。