nifi.apache.org/docs/nifi-docs/html/nifi-in-depth.html
- FlowFile repo 내의 데이터, Content repo 내의 컨텐츠데이터 둘 다 불변(immutability)임
즉, 내용을 변경할 수 없음.
그럼 내용을 변경하고 싶을 때는 어떻게 해야 하느냐?
원본은 그대로 두되 원본을 복사한 복사본을 기준으로 변경 내용을 적용함
이 내용은 문서의 가장 처음인 Intro 에 나오는 내용
- 아래 나올 내용들을 이해하기 위해 먼저 Write-Ahead Log 를 이해해보자.
WAL의 중심 개념은 변경을 로깅한 후에만, 즉 변경 내용을 설명하는 로그 레코드를 영구적 저장소에 먼저 기록한 후에 데이터 파일(테이블과 인덱스가 있는)의 변경 내용을 작성해야 한다는 것이다. 이 절차를 준수한 경우 충돌 발생 시 로그를 사용하여 데이터베이스를 복구할 수 있으므로 트랜잭션 커밋마다 데이터 페이지를 디스크에 쓸 필요가 없다. (따라서 상대적으로 디스크 쓰기 수도 줄어들게 됨) 데이터 페이지에 적용되지 않은 변경 내용은 로그 레코드에서 실행 취소가 가능하다. (이것은 롤포워드roll-forward 복구이며, REDO라고도 한다.) 참고 postgresql.kr/docs/9.6/wal-intro.html |
- FlowFile repo 는 FlowFile 의 메타데이터에 대한 Write-Ahead Log 를 저장함.
메타데이터란, FlowFile 과 관련된 속성, 실제 File 내용에 대한 포인터, FlowFile 이 속한 Connector(큐) 의 상태 등을 의미함.
때문에 시스템은 데이터를 처리 할 때 노드가 어떤 단계에 있는지 정확히 알 수 있고
노드가 다운되어도 저장되어있는 Write-Ahead Log 를 통해 중단된 지점부터 다시 실행이 가능함.
FlowFile Repo 는 NiFi 의 Write-Ahead Log 역할을 함.
FlowFile 이 NiFi 에 의해 가공될 때 생기는 트랜잭션들이 FlowFile Repo 에 기록되는 것임.
- NiFi 는 각 노드에서 발생한 상황을 해당 FlowFile repo 에 Write-Ahead Log 로 기록하여,
하드웨어 및 시스템 오류로부터 보호함
또한 FlowFile repo 의 스냅샷도 지정된 간격(default 2분)으로 찍음(.partial 파일로 디스크에 저장됨)
만약 File 내용을 수정하는 등의 쓰기 동작 중에 노드가 다운되어도,
Copy on Write 과 Immutability 패러다임 덕분에 File 내용은 손상되지 않음.
NiFi 가 다운되면 마지막으로 알려진 안정 상태로 되돌아간다고 함.
- FlowFile 의 실제 내용(content) 는 disk 에 있음
이 FlowFile 을 가공/처리 한다고 하자.
먼저 가공할 때 생기는 트랜잭션들은 Write-Ahead Log 로 FlowFile repo 에 저장
또한 시스템에서 FlowFile 을 처리하기 위해 FlowFile 참조 객체를 JVM Memory(HashMap) 에 넣음
즉, 처리중인 FlowFile 참조 객체는 JVM memory 에 올라가 있다는 소리(반대로 말하면, 사용중이지 않은 FlowFile 참조 객체는 memory 에 올라와있지 않고 디스크에 있음)
(메모리에서 정보를 잃기 쉬워지기 때문에, Write-Ahead Log 를 통해 FlowFile 참조 객체(FlowFile 의 메타데이터, 포인터, FlowFile 속성.. 등)를 미리 영구저장소에 저장한 후 메모리에 올리는 것임. 만약 NiFi 장애 등에 의해 메모리가 날아가도, Ahead Log 가 영구저장소에 저장되어 있기 때문에 복원이 가능함)
이 메모리 내에 있는 참조 객체는 컨넥터(큐)에 보관되는 객체와 동일함. <-??
FlowFile 에 수정/가공/처리가 일어날 때는 이 참조 객체를 대상으로 함.
다시 말해, 실제 Content 는 디스크에 얌전히 있지만,
그 Content 를 가리키는 FlowFile 참조 객체(메타데이터인 듯?) 가 계속 수정되는 것
그럼 수정이 끝나면 나중에 Content 를 기반으로 업데이트 하겠네?
-> 문서의 마지막 부분을 읽어보면 위의 궁금증에 대한 해답이 나옴.
Content 를 가공하는 Processor 의 경우 위에 설명처럼 FlowFile 참조 객체도 수정되고 Content Repo 내의 있는 컨텐츠 데이터도 수정됨.
Attribute 만을 가공하는 Processor 의 경우 FlowFile 참조 객체만 계속 수정되고 Content Repo 내에 있는 컨텐츠 데이터는 그대로.
Connector(큐) 에 너무 많은 FlowFile 이 쌓이게 되면(구체적으로는 "nifi.queue.swap.threshold" 값 보다 커지게 되면)
Memory(HashMap) 에 있는 참조 객체 중 가장 우선순위가 낮은 참조 객체들을 직렬화 한 다음
디스크 내의 "swap file" 영역으로 따로 빼서 저장시켜둠.
FlowFile repo 는 이렇게 Memory(HashMap) 에서 제거된 swap 파일들을 기억해 둠.
나중에 swap file 을 Memory(HashMap) 으로 되돌린다고 하는데, 언제 되돌리는지는 안 써있네
이렇게 swapping 기술을 사용함으로써 메모리 고갈없이 NiFi 가 잘 실행되도록 한다고 함.
- Content repo 는 FlowFilw 의 실제 데이터를 저장하는 곳임.
수정/가공이 필요할 때는 해당 내용만 JVM 의 메모리에 올려 처리한다고 함.
또한, Content repo 는 수정/가공이 되면 원본은 그대로 두고 복사본을 새로 만들어서
그 복사본에 수정/가공 내용을 적용하는 식으로 처리한다고 함.
(Content repo 의 데이터를 업데이트 할 때는 immutability 와 Copy-on-Write 패러다임을 사용하여 안전성을 최대화한다고 함)
이렇게되면 더 이상 사용되지 않는 데이터가 생길 수 있기 때문에(수정/가공에 의해 계속 복사본이 생기게 되면 게중에 한 번 사용된 후로 영원히 사용되지 않을 데이터가 생길 수 있겠지... 암. 그렇고말고)
그런 데이터를 분석하기 위한 전용 쓰레드가 따로 있다고 함.
그런 데이터가 발견되면 삭제하거나 따로 보관된다고 함.
- Provenance Repo 에는 FlowFile 의 기록이 꾸준히 저장됨.
FlowFile 에 대한 이벤트(FlowFile 생성, 분기, 복제, 수정 등)가 일어날 때마다
새로운 Provenance 이벤트도 일어난다고 함.
이 Provenance 이벤트는 해당 시점을 기억하는 snap shot 임
Provenance 이벤트가 생성되면 모든 FlowFile 의 속성과 FlowFile 의 컨텐츠에 대한
포인터를 복사하고 FlowFile 의 상태와 함께 Provenance repo 내에 저장됨.
모든 FlowFile 속성과 컨텐츠에 대한 포인터가
Provenance Repository에 유지/저장되기 때문에
우리는 언제든지 해당 데이터의 계보, 처리 기록과 데이터를 볼 수 있음
Provenance Repository가 저장하는 것은 컨텐츠가 아니라 컨텐츠의 포인터(FlowFile 이 저장하는 그것)이기 때문에
만약 컨텐츠 자체가 사라진다면, Provenance Repository를 통해 컨텐츠를 보지 못 함.
컨텐츠는 보지 못하지만 해당 컨텐츠에 대한 정보 데이터(날짜, 이름, UUID, 위치 등)은 볼 수 있음
- Provenance repo 와 Content repo 는 정보를 여러 물리적 파티션에 나눠 저장할 수 있음(!!)
그렇다면 NiFI 가 동작하는 서버 내의 디스크에만 한정된 것이 아니라 타 서버의 디스크에도 분산 저장이 가능하다는 말?!
여러 디스크에서 읽기/쓰기 작업이 필요할 때 나눠 저장하면 좋겠다.
저장소 (Content 또는 Provenance)는 여전히 하나의 논리적 저장소이지만
쓰기는 시스템에 의해 자동으로 여러 볼륨 / 파티션에 스트라이프 됨
(즉, 내가 NiFi 를 사용할 때는 하나의 저장소인 것 처럼 사용하지만
실제로 데이터는 여러 디스크에 나눠 저장됨)
디렉토리는 'nifi.properties' 파일에 지정된다고 함.
- FlowFile 을 사용할 때는, FlowFile 의 '데이터(content)' 대신 '속성(attribute)'을 사용하는 것이 좀 더 바람직하다고 함.
예를 들어, 1씩 증가하는 카운터를 만든다고 할 때, FlowFile 내의 데이터를 1씩 증가시키기 보다는,
FlowFile 에 counter 라는 속성을 하나 추가하여 그 속성값을 증가시키는 편이 성능상 좋음.
왜냐하면 메모리에 존재하는 속성값의 입출력이 빠르기 때문에 FlowFile 전체 content 르 지속적으로 처리하는 것보다 성능상 훨씬 낫다고 함.
- life of a flowfile 섹션에서는, WebCrawler.xml 라는 템플릿을 예로 들어 FlowFile 이 구체적으로 어떻게 흘러가는지,
FlowFile 이 흘러가는 동안 내부 repo 는 어떤 것을 저장하고 어떻게 동작하는지 자세히 설명해줌.
'NiFi' 카테고리의 다른 글
[Nifi] listSFTP/fetchSFTP 동작 방식 설명 (0) | 2020.11.03 |
---|---|
[Nifi] Cluster 에서 HA 에 관한 고찰 링크 (0) | 2020.11.03 |
[Nifi] How to achieve better load-balancing using NiFi's Site-To-Site Protocol 링크 (0) | 2020.10.29 |
[Nifi] user guide 공부 필기 (0) | 2020.10.22 |
[Nifi] Kafka 와 연동시 알아낸 점 몇 가지 (0) | 2020.10.20 |