Flume exec source
1. Flume exec source
Flume 의 Source 중 하나이다.
exec source 는 OS Command ‘tail’ 로 데이터를 캡쳐한다.
여기서는 데이터를 캡쳐하는 방법 ‘tail’ 으로 인해 발생할 수 있는 문제를 알아보려 한다.
Apache flume 의 공식 가이드에서도 tail 이라는 명령어 자체가 갖는 특징과, Exec source 의 특징으로
데이터 적재를 보장하지 못 한다고 명시되어 있다. (유실 가능성이 있다.)
2. Environment
Source : EXEC – FILE – AVRO
a1.sources.a1.command = tail -F /log/weblogics/Server1/access.log
Target : AVRO – FILE – HDFS
s1.sinks.HDFS.hdfs.path = hdfs://localhost:8020/user/flume/%Y/%m/%d/%H/
Source 에서 tail 명령으로 데이터를 감지한다.
새로운 row 마다 각기 event 로 생성되며 이는 Target 의 HDFS 에 기록된다.
3. Problems to think
여기서 고민하는 것은 데이터가 누락되는 경우이다.
대용량 데이터의 처리이기에 어느 정도의 오차 (이를 테면 소스 데이터로 인한) 는 감당할 수 있다고 생각하지만
이는 상황마다 감안할 수 있는 그 정도가 다를 수 있다.
어떤 케이스에 누락이 발생할지 파악해 둬서 손해 볼 것은 없다.
A. tail 의 대상이 없어지는 경우 (내용)
B. tail 의 대상이 없어지는 경우 (파일)
C. source agent 가 down 되는 경우
D. target agent 가 down 되는 경우
E. source, target agent 모두 down 되는 경우
4. Test
A. tail 의 대상이 없어지는 경우 (내용)
original_name 이 있으면 original_name.copy 복제본을 만들고,
original_name 의 내용을 비운다. ( cat /dev/null > original_name )
내용을 비우기 이전 / 이후 누락 되는 데이터가 있는지 확인해 보겠다.
echo new line 6 >> test.log; cat /dev/null > test.log; echo new line 7 >> test.log; |
위와 같이 파일의 내용을 비우는 시점을 대상으로 전/후 데이터가 들어온다 했을 때 Target agent 로
데이터가 잘 복제되는지 확인하였다.
3회 시도해 보았고 이상없이 복제 되었다.
위와 같은 패턴으로 100 라인을 만들어 스크립트로 수행해 보았고, 이상없이 전부 복제되는 걸 확인하였다.
원래 파일이 유지되는 상황에서 내용이 지워지고 새로이 생성되는 경우 100 회의 테스트에서 유실되지 않았다.
B. tail 의 대상이 없어지는 경우 (파일)
먼저 exec source 에서 사용한 tail –F 에 대해 이야기를 하자면, -F 옵션은 대상이 존재하지 않아도 retry 한다.
tail –f 의 경우에는 대상 파일이 사라지면, 이후 동명의 파일이 다시 생기고 입력이 있더라도 정지 상태이다.
tail –F 의 경우에는 대상 파일이 사라지면, 대상에 대해 엑세스가 불가능하다는 메시지가 나오며,
파일이 다시 생기는 경우 이를 인지한다.
다시 테스트로 돌아가 다음과 같은 순서로 진행하려 한다.
l Source test.log 를 test.bak 으로 리네임
l Source test.bak 을 test.log 로 리네임 (다른데이타)
위 방법을 사용하는 와중에 다음의 상황을 확인하려 한다.
a. 리네임 후 일정시간 (agent 가 인지할 정도의 – 30초) 이 흐른 후 원복
b. 리네임 후 바로 원복
<리네임 후 일정시간이 흐른 후 소스 파일을 생성하는 경우>
rm -f test.log; sleep 60; echo `date` > test.log;
Source 에서는 다음의 로그가 확인 되었다.
2014-10-10 14:50:34,883 (StderrReader-[tail -F /root/flume1/test.log]) [INFO - org.apache.flume.source.ExecSource$StderrReader.run(ExecSource.java:451)] StderrLogger[106] = 'tail: `/root/flume1/test.log' has become inaccessible
Target 에서는 다음의 로그가 확인 되었다.
2014-10-10 14:51:37,116 (New I/O worker #1) [DEBUG - org.apache.flume.source.AvroSource.appendBatch(AvroSource.java:363)] Avro source c1: Received avro event batch of 1 events.
2014-10-10 14:51:37,952 (Log-BackgroundWorker-fc) [INFO - org.apache.flume.channel.file.EventQueueBackingStoreFile.beginCheckpoint(EventQueueBackingStoreFile.java:214)] Start checkpoint for /var/lib/hadoop-hdfs/.flume/file-channel/checkpoint/checkpoint, elements to sync = 1
그리고 데이터가 정상적으로 복제 된 것을 확인하였다.
<리네임 후 바로 소스 파일을 생성하는 경우>
rm -f test.log; echo `date` > test.log;
Source 에서는 다음의 로그가 확인되었다.
2014-10-10 14:55:12,034 (StderrReader-[tail -F /root/flume1/test.log]) [INFO - org.apache.flume.source.ExecSource$StderrReader.run(ExecSource.java:451)] StderrLogger[107] = 'tail: `/root/flume1/test.log' has become inaccessible:
2014-10-10 14:55:12,043 (StderrReader-[tail -F /root/flume1/test.log]) [INFO - org.apache.flume.source.ExecSource$StderrReader.run(ExecSource.java:451)] StderrLogger[108] = 'tail: `/root/flume1/test.log' has appeared; following end of new file'
Target 에서는 다음의 로그가 확인되었다.
2014-10-10 14:55:12,166 (New I/O worker #1) [DEBUG - org.apache.flume.source.AvroSource.appendBatch(AvroSource.java:363)] Avro source c1: Received avro event batch of 1 events.
2014-10-10 14:55:38,197 (Log-BackgroundWorker-fc) [INFO - org.apache.flume.channel.file.EventQueueBackingStoreFile.beginCheckpoint(EventQueueBackingStoreFile.java:214)] Start checkpoint for /var/lib/hadoop-hdfs/.flume/file-channel/checkpoint/checkpoint, elements to sync = 1
누락되는 데이터 없이 정상 복제 되었다.
리네임 (혹은 삭제) 의 속도를 떠나 tail –F 옵션을 사용한 경우 파일이 바뀜을 확인 (엑세스 불가 메시지) 되었고,
Target 측에서는 새로운 내용에 대한 event 를 정상 수신 하였다. ( Received avro event … )
C. source agent 가 down 되는 경우
echo `date` > test.log;
위의 명령어를 Source agent 를 kill 하고 진행하였다.
다음의 내용을 확인해 보려 한다.
a. agent shutdown 상태에서 구 파일에 내용이 더 쓰여지고 파일이 초기화 된 이후 다시 쓰여지는 경우
b. agent shutdown 상태에서 구 파일을 삭제하고 새로운 파일을 만드는 경우
<agent shutdown 상태에서 구 파일에 내용이 더 쓰여지고 파일이 초기화 된 이후 다시 쓰여지는 경우>
date >> test.log; date >> test.log; cat /dev/null > test.log >> date >> test.log; date >> test.log; date >> test.log;
초기화 이후의 데이터가 정상적으로 복제되었다.
다시 말하면 초기화 이전의 데이터는 잃어버렸다.
<agent shutdown 상태에서 구 파일을 삭제하고 새로운 파일을 만드는 경우>
date >> test.log; date >> test.log; rm –f test.log >> date >> test.log; date >> test.log; date >> test.log;
앞서 살펴 본 케이스와 마찬가지로 새로운 변경분에 대해서는 복제가 되었지만,
파일 삭제 전에 일어난 변경에 대해서는 잃어버렸다.
결론을 이야기 하면 Source agent shutdown 상태에서 파일의 삭제 (rm, mv), 변경 ( /dev/null ) 시점을 기준으로
그 이전의 변경 분은 유실된다.
D. target agent 가 down 되는 경우
Target 의 agent 를 shutdown 하고 Source 에 다음과 같이 변경을 가했다.
date >> test.log; date >> test.log; date >> test.log;
Target 이 down 되어 있어도, Source 에 일어난 변경분이 전달 됨을 확인하였다.
3건의 데이터는 각기 event 로 생성이 되며 이는 다음 로그를 통해 변경 분 (3 lines) 을 확인할 수 있다.
2014-10-10 15:32:56,098 (New I/O worker #1) [DEBUG - org.apache.flume.source.AvroSource.appendBatch(AvroSource.java:363)] Avro source c1: Received avro event batch of 3 events.
결론으로 target down 여부는 source agent 가 정상 동작하고 있음을 전제로 데이터 유실과 관계가 없었다.
E. source, target agent 모두 down 되는 경우
앞서 케이스를 살펴 본 결과 Target 은 말 그대로 Source 가 넘겨주는 데이터를 받을
뿐이다.
Target agent 입장에서는 Source 의 생사는 중요하지 않다.
결과적으로 Source Agent 가 데이터를 적재하냐 못 하냐가 중요하다.
데이터가 누락되는 경우는 Source shutdown 중 감시 대상 파일이 초기화 되거나 삭제 (변경) 되는 경우 그 전의 변경 분을 잃는다는 것이다.
a. source agent shutdown
b. target agent shutdown
c.
source
file 에 다음을 수행
date >> test.log; date >> test.log; date >> test.log;
d. target agent startup
e. source agent startup
확인 결과 Source agent 때 케이스와 마찬가지로 파일 삭제 / 초기화 이후 변경 분에 대해서는 정상 복제되었다.
5. Conclusion
Source exec 방식을 사용할 때 변경 내역을 잃을 수 있는 케이스는 다음과 같다.
n Source Agent shutdown 상태에서 파일이 초기화 (null) 되기 전까지의 변경분은 잃어버린다.
n Source Agent shutdown 상태에서 파일이 삭제 되기 전까지의 변경분은 잃어버린다.
위 외에는 변경 분을 일반적으로 잃어버리지 않는다고 봐도 된다.
다만 Apache Flume 공식 문서에서도 이야기 하는 데이터 유실의 케이스에 대해서는 일어날 수 있다.
문서에서 언급한 유실 경우는 Source Agent 가 데이터 적재하는 경우 Channel 에 문제가 있는 경우나,
네트워크 자체의 문제 등으로 발생할 수 있다.
때문에 위의 상황에 대해서도 감당할 수 없는 경우엔 Spooling Directory source 를 사용하라고 한다.