flume學習(十一):如何使用Spooling Directory Source

問題導讀


1.如何理解將FTP上的信令數據匯聚到HDFS上去存儲?

2.使用Spooling Directory Source的時候同時讀寫一個文件會怎樣?








最近在弄一個信令數據匯聚的事情,主要目的是把FTP上的信令數據匯聚到HDFS上去存儲。 邏輯是這樣的:把FTP服務器上的文件下載到一臺主機上,然後SCP到另外一臺主機上的Spooling Directory Source所監控的目錄下面去,sink是hdfs(這裏解釋一下,由於網絡環境的因素,另一臺不能訪問到內網的FTP服務器,所以只能這樣中轉一下)。


嗯,想法不錯,邏輯上看上去也應該沒啥問題,於是就開始吭哧吭哧寫腳本了。FTP上每個信令數據的每個文件的大小差不多都有300M左右。SCP到遠端服務器也沒出現問題,可就是agent老是會掛掉,報這個異常:

  1. 2014-11-26 12:30:16,942 ERROR org.apache.flume.source.SpoolDirectorySource: FATAL: Spool Directory source source1: { spoolDir: /var/log/apache/flumeSpool }: Uncaught exception in SpoolDirectorySource thread. Restart or reconfigure Flume to continue processing.
  2. java.nio.charset.MalformedInputException: Input length = 1
  3.         at java.nio.charset.CoderResult.throwException(CoderResult.java:277)
  4.         at org.apache.flume.serialization.ResettableFileInputStream.readChar(ResettableFileInputStream.java:195)
  5.         at org.apache.flume.serialization.LineDeserializer.readLine(LineDeserializer.java:134)
  6.         at org.apache.flume.serialization.LineDeserializer.readEvent(LineDeserializer.java:72)
  7.         at org.apache.flume.serialization.LineDeserializer.readEvents(LineDeserializer.java:91)
  8.         at org.apache.flume.client.avro.ReliableSpoolingFileEventReader.readEvents(ReliableSpoolingFileEventReader.java:241)
  9.         at org.apache.flume.source.SpoolDirectorySource$SpoolDirectoryRunnable.run(SpoolDirectorySource.java:224)
  10.         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
  11.         at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304)
  12.         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178)
  13.         at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
  14.         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
  15.         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
  16.         at java.lang.Thread.run(Thread.java:745)
複製代碼

然後讓我重啓agent纔會把Spooling Directory Source所監控的目錄下面的文件抽取到HDFS上去,感覺很莫名,網上搜索了一下這個錯誤的原因,很多都是說可能傳輸的文件字符集的原因,不以爲然,因爲我反覆測試了一下,如果是字符集的原因,那麼爲什麼我重啓一下agent又可以成功的抽取數據了。



於是我想了想是不是由於同時讀寫導致的問題,因爲我SCP文件過去,文件較大,需要一定的時間,而flume監測到有文件馬上就開始逐行讀取文件轉化成EVENT發送到HDFS上去,這中間肯定存在同時讀寫一個文件了,然後就產生的這個異常問題?


目前僅僅是猜測,於是我修改了Spooling Directory Source的配置,加了這麼一個配置:

tier1.sources.source1.ignorePattern = ^(.)*\\.tmp$


就是忽略監控目錄下面的.tmp文件。然後我修改了scp的邏輯,拷貝到另一臺主機上時,先命名爲:原文件名.tmp(由於是.tmp文件,agent不會採集此類文件),等SCP執行成功之後,在mv這個.tmp文件,去掉.tmp後綴,這樣agent又會抽取這個文件的數據了,通過這麼一處理,就巧妙的避免了同時讀寫一個文件的問題。


腳本調整好之後,重新運行腳本,驚喜的發現成功了,這次agent沒有掛掉,大功告成了。


總結:使用Spooling Directory Source的時候,一定要避免同時讀寫一個文件的情況。採用上面提到的方法就可以巧妙的避開這個問題。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章