在前面,我有稍微帶到 Apache NiFi 的性質與特點,但除了了解這些之外,我們也要清楚知道這個服務本身的架構,以及它牽扯到有哪些 Component,就趁這時候先來好好地知道一下,這樣往後在實作時也比較清楚我們運用到哪些。
一開始,我會先大概講一下在 Apache NiFi 中最重要的幾個 component,我會先有簡單的描述來讓大家可以容易理解,而往後也會一ㄧ套用到實際的操作來做一個呼應,這裡我先帶出一張自己設計的圖,接著搭配下面的 component 來介紹,圖如下:
何謂 FlowFile?我們可以想像是資料中或是File中的一筆Record,甚至是一包資料同時含有很多筆 record,今天假設有一張 Table且其中有100筆資料時,當 NiFi 從中讀取時,這100筆 Record 就會在 NiFi 產生100筆 FlowFile,而FlowFile會帶有自己的 attribute 和 content,這兩個有什麼差異呢?attribute
:可以想像成是 metadata,以 Key-Value 的方式來對 FlowFile 的描述,包含size, path, permission等content
:真實data的內容,可能是 csv, json 等格式。
可以想像成是一個邏輯處理的 Unit,在 NiFi 中它提供了許多內建的 Processor,可參考官方連結,這可使我們透過設定的方式來產生
、處理
、轉換
、輸出
FlowFile 等相關操作。
因此,我們可以從上圖的橘線
,可看到在一個 Pipeline當中,FlowFiles 會經過中間多個 Processor的處理,而第一個 Processor 會被用來產生FlowFiles(ex. 讀取DB或 files); 而最後一個通常會是一個落地輸出的 Processor(ex. 寫入DB 或 files)
P.S 額外補充一下,如果讀者們有熟悉 Apache Airflow 的話,Processor 的概念就是類似於 Airflow 的 operator。
在 NiFi 建立 Data Pipeline 的時候,其實就是透過一連串 Processor 來建置,而Processor 彼此之間會建立一個關係,就稱作為 Connection,可從圖中看到 Processor之間一定會有個 Connection的存在。
在 Connection 當中,我們可以透過設定來描述該 Connection的定義,以上圖中的綠框
與紅框
分別代表著最常見的 Success 和 Failed,若今天有 FlowFiles 是走 Success 的 Connection(上圖中的橘線),也就代表上一個 Processor 是處理成功的。因此,我們可自身建立多種 Connection來決定每一條下游路徑的狀態與意義為何。
此外,在 Connection中我們還可以設定 Queue 的狀態,像是 FIFO 或是 New First等,來緩解當 Connection 中因有太多 Flowfiles 時所導致效能的問題。
Processor Group 通常被用來作為 Processor 的 Module,為 Processors 的集合。最常發生在什麼樣的情境呢?會有3種情境需要Processor Group:
『Module』
的意思。『分專案或部門』
為使用,若今天有一個 Team,同時有10個專案需要建立 Data Pipeline,理所當然每一個專案的流程都會不一樣,這時候就可以透過 Processor Group 來做專案的劃分; 或是有不同 Team 要採用時,也可以利用這個方式來劃分不同 Team。User 權限的最小單位
,我們可以針對特定 Processor Group 來決定哪些 User 擁有 Write 或 read 的權限其中情境1,我們可以看到上圖的橘框
,它被整合在 Pipeline 的其中一環,但其實我們將其放大來看,他就是由一連串的 Processor 組合而成,所以未來若有其他 Pipeline 需要類似的情境時,他僅可拉這個 Processor Group,就不需要再重頭拉一次原先 Processor Group 內部的流程。
P.S 額外補充,若對應到 Airflow,其實就是類似於 Subdag 或是 Airflow2.0 的 TaskGroup.
用來將多個 source connection 的 組合成單一個 connection,這對於可讀性可以提供相當大的幫助,如同上圖的紫框
,我們可以想像假設有 n 個 Processor 同時要連到同一個 Processor,如果不透過 Funnel 的話,在下游的那一個 Processor 身上會有很多條線,這對於使用者在檢視或是Debug是不理想的。
接下來的 Component 介紹,就沒有呈現在上圖,但也是有一定的重要性。
Controller Service 可以想像成他是一個與第三方對接的 connection
,注意不是前面所提到的 connection,而是真的透過網路服務建立的 connection。
當我們選擇 NiFi 作為我們 Data Pipeline 的工具時,照理來說就會在服務上建立許多的 Pipeline,甚至有些當中的 Processor 會共同存取同一個 DB 或是 cloud 的服務,如果每一個 Processor 都對其建立太多 connection 的話可能會造成 DB 或 cloud 的問題。
所以此時就可以統一透過 Controller Service 來做一個管理,他可以事先建立好一個與第三方服務的 connection,而當有 Processor 需要做使用的就可以直接套用對應的 Controller Service,一方面不用再重新設定,另一方面可以對目標存取控制好連線數以節省開銷。
Reporting Task 是 NiFi 在做 Monitoring 很重要的角色,他可以將一些** Metrics、Memory & Disk Utilization、以及一些 Monitoring 的資訊發送到出來**,常見應用是發送到 Prometheus, DataDog、Cloudwatch 等第三方服務來做視覺化呈現。
Templates 通常用於轉換環境做使用
,假設我有一個既有的 NiFi 在 A 機器上,但這時候我需要轉換環境到 B 機器上,此時使用者可以把在 A 機器上所有的 Pipeline 輸出成 Templates(為 XML 檔),接著再匯入到 B 機器上的 NiFi,就可以在新的環境中繼續使用相同的 Pipeline了
這當中的轉換是以 Processor Group 作為單位,其中也會把這個底下的所需要用到的參數和設定一起匯出成 templates,所以在環境轉換時就會是無痛轉移。簡單的呈現如下圖:
Apache NiFi是透過 Java 來做開發,所以根據官方文件所提供的架構圖,我們可以看見 NiFi 的 Core Component 都位於 JVM 上 :
讓我們來從下往上一一介紹
Repository 就是一個存放的地方,在 NiFi 的運作原理會經過壓縮與 WAL 方式寫入在所屬的 instance 上。
因此 FlowFile Repository 就是將 FlowFile 經過我們於 NiFi 所設計的 Data Pipeline 過程中,將其狀態做一個保存。舉例來說,Pipeline 有 3個 Processor,FlowFile 在每經過一個 Processor 都會將他的狀態和 metadata 儲存於 FlowFile Repository。
Content 就是指的是 FlowFile 真實的資料內容,Nifi 會將這樣的內容透過壓縮與加密,再接著存放到自身的 FileSystem,也就是Content Repository。
Provenance Repository是用來存放所有 Flowfile 的追蹤事件,也就是記錄著 FlowFile 從哪裡留到目前的 Processor,以及後續以哪一個 Processor 作為下一步流向的標的。主要就是用來追蹤 FlowFiles 在每個 Processor 的狀態,包含時間、資料變化等
Flow Controller 你可以想像著他整個 NiFi 的操作核心,所有 Pipeline 的觸發與排程,以及對於給 Processor 的相關資源,都是由它來做一個分派與調度。
Apache NiFi 有自己的 API 可做使用,所以除了可以在 Web UI 操作之外,我們也可透過呼叫 API 的方式來做設定與執行,但其實 Web UI 也就是基於 Web Server 來根據使用者在 UI 的操作來執行對應的 API。所以這就是一個控制 NiFi API 的地方。
Apache NiFi 除了可以建立成 Single Node 之外,也可以建立成 clustering 的架構,根據官方提供的圖參考如下:
但是要注意一點的地方是,NiFi 的 Clustering 與一般我們所想到的像是 EMR, hadoop 的那種 Clustering 不太一樣。通常最常見的 Clustering,會有一個 Master(或稱 Leader),去搭配其他的 Worker(或稱Follower)。但在 NiFi 的設計中,它是採用『Zero-Master』
的 Clustering,也就是每一個在 Clustering 的 Node 都會負責到 Data 的處理,差別在於Data 會被切分到各個 Node 中。
正因為沒有一個主要的 Master Node,所以使用者可以從各個 Node 去操作 UI,而 NiFi 就會來同步到其他 Node 中。舉例來說,使用者在 A Node 加入一個 Processor,而使用者也可以在同一個 Clustering 中的 B Node 看到剛剛所加入的 Processor。
除了Nifi本身之外,還會一個 Apache Zookeeper 的服務,主要是用來執行故障的處理,而它會選擇一個 Node 作為 Coordinator,其他 Node 要向 Coordinator 發送 Heartbeats 和回報狀態來確保彼此之間的連線(預設為5秒發送一次)。所以當有一個 Node 沒有在時間內回報任何資訊時,Coordinator 就會斷開該 Node,直到恢復連線為止。
這邊來額外提一下在 NiFi Clustering 中的會用到的名詞:
其實 Nifi Clustering 的設定相對比較複雜,還有一些操作上的細節,所以在這次的系列文當中還是以 Single Node 的模式來去做一個主軸。明天我也會提供 Clustering 的 docker-compose.yml 的參考範例,有興趣的讀者到時候可以再 build 起來玩玩看。
Day2 就大概到這邊,讓各位了解主要的架構與 Component,明天會帶各位介紹另一位 NiFi 的關鍵角色 - NiFi Registry,他可幫我們對 Data Pipeline 來做版控喔,敬請期待。