1. 程式人生 > >flume異常崩潰 File has been modified since being read

flume異常崩潰 File has been modified since being read

conf dep info rep 問題 pooled string ext.get 發現

日誌采集異常,生產報錯誤日誌:

(org.apache.flume.source.SpoolDirectorySource$SpoolDirectoryRunnable.run:280) - FATA
L: Spool Directory source spool_source: { spoolDir: /apps/logs/libra }: Uncaught exception in SpoolDirectorySource thread. Restart or
reconfigure Flume to continue processing.
java.lang.IllegalStateException: File has been modified since being read: /apps/logs/libra/financial-webapp/spool/libra.2018-03-09_09-
10-16.tmp

看提示應該是flume讀文件時,該文件正被其他進程修改。

查閱資料有人因為大日誌文件導致該問題(http://www.bubuko.com/infodetail-508764.html),仔細分析flume的源碼,發現應該不是這個原因。

因為我們的文件很小。

後來發現是因為兩個系統用了用一個日誌目錄,日誌文件的格式均為年月日時分秒,如果同一秒兩個系統都寫文件,一個系統寫完,flume去獲取發現已經寫完,這時候另一個系統又去寫,這時flume會和寫進程沖突。

解決辦法就是兩個系統分寫兩個目錄,或者文件名區分開同一秒的兩個文件。

另外針對大文件,flume的解決方案可以設置一個文件完成後綴:

SPOOLED_FILE_SUFFIX

以下摘自flume 1.7源碼,可以看到,當後綴匹配是才會取。大文件可以在寫完時修改後綴,可以避免大文件問題。
public FileVisitResult visitFile(Path candidate, BasicFileAttributes attrs)
throws IOException {
String fileName = candidate.getFileName().toString();
if (!fileName.endsWith(completedSuffix) &&
!fileName.startsWith(".") &&
includePattern.matcher(fileName).matches() &&
!ignorePattern.matcher(fileName).matches()) {
candidateFiles.add(candidate.toFile());
}
其中
completedSuffix = context.getString(SPOOLED_FILE_SUFFIX,
DEFAULT_SPOOLED_FILE_SUFFIX);

flume異常崩潰 File has been modified since being read