nifi.apache.org/docs/nifi-docs/html/nifi-in-depth.html

 

Apache NiFi In Depth

Utilizing the copy-on-write, pass-by-reference, and immutability concepts in conjunction with the three repositories, NiFi is a fast, efficient, and robust enterprise dataflow platform. This document has covered specific implementations of pluggable interf

nifi.apache.org

 

 

 

- 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 패러다임을 사용하여 안전성을 최대화한다고 함)

이렇게되면 더 이상 사용되지 않는 데이터가 생길 수 있기 때문에(수정/가공에 의해 계속 복사본이 생기게 되면 게중에 한 번 사용된 후로 영원히 사용되지 않을 데이터가 생길 수 있겠지... 암. 그렇고말고)

그런 데이터를 분석하기 위한 전용 쓰레드가 따로 있다고 함.

그런 데이터가 발견되면 삭제하거나 따로 보관된다고 함.

("nifi.content.repository.archive.max.retention.period", "nifi.content.repository.archive.max.usage.percentage" 옵션 참고)

 

 

- 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 는 어떤 것을 저장하고 어떻게 동작하는지 자세히 설명해줌.

 

 

 

 

 

+ Recent posts