Apache NiFi 如何從入門到不放棄?

既然來了,就留下唄。

筆者在之前的文章《物聯網遇到流計算》中介紹過 Apache NiFi,雖比不上 StreamSets 華麗的外表,但是功能卻很強大,在開源方面,NiFi 的企業級功能是接近完整的。

在本篇文章中,筆者會帶大家進入 WiFi,No,是 NiFi 的世界。大家看完後,筆者不相信誰還會有放棄的念頭(此處會不會有掌聲!)。

本篇文章引用了 Manoj 小哥的部分 Slides,再次說明,表示感謝。

熱身

在正式講解 NiFi 之前,跟着筆者先來做做熱身運動。

Data Flow/Data Pipeline/ETL

簡單普及幾個四是四,十是十的概念,走馬觀花即可,不必太在意。

1. Data Flow

Data Flow,數據流,有始有終纔有意義,始於數據的源,終於可供使用和分析的結果數據。一句話,Data Flow 解決的是數據端到端傳輸的問題。

數據流中的數據可以來自很多種類型,比如 CSV、JSON、HTTP、IoT 和音視頻流等等。

2. Data Pipeline

Data Pipeline,數據管道,又是什麼呢?
大家可能對 ETL 非常熟悉了,其實 Data Pipeline 和 ETL 很相似,個人感覺 Data Pipeline 是包含 ETL 的,更加通用的方式,包含全局的系統之間數據的遷移,以及遷移過程中數據的轉換處理。

現在國內外有不少公司在研發 Data Pipeline 產品,提供多渠道數據來源實時攝取、數據清洗、任務流管理、元數據管理、流批一體等功能。

3. ETL

ETL(Extract-Transform-Load),大家照着 Extract-Transform-Load 字面意思理解就可以了,即用來描述將數據從來源端經過抽取(extract)、轉換(transform)、加載(load)至目的端的過程。

爲什麼需要實現一個 Data Flow 框架?

是不是 Azkaba、Airflow、DolphinScheduler 等用多了,就忘記當初信誓旦旦的誓言了,好吧,或許不曾有過。

不管那麼多了,我們反正就需要實現一個 Data Flow 框架,要解決的問題看似很簡單,如下:

對,就這麼簡潔。但是要考慮大數據背景下的 N 個 V 問題:

這裏筆者列了最初的大數據的 4V 特點,即 Volume(數據海量)、Velocity(高速,產生和分析)、Variety(數據多樣性)、Veracity(真實,數據準確性)。

這個框架還要提供如下能力:

筆者的確是沒有時間和能力去實現這個框架,幸好社區好多年前就已經實現 Data Flow 的框架,而且具備企業級的功能,接下來的時間就交給今天的主角 Apache NiFi。

何爲 Apache NiFi

什麼前世今生,筆者就省了,感興趣的讀者去深挖一下,但是不要掉坑裏,請記住,我們是研究技術的,不是講故事的。

官網一句話系列

An easy to use, powerful, and reliable system to process and distribute data.

意思就是,那麼好用的數據處理和分發系統,它能(重讀)不香嘛.

NiFi 構建的目標就是:


特性

Apache NiFi 的一些高級功能和目標包括:

1. Web-based user interface
   Seamless experience between design, control, feedback, and monitoring

2. Highly configurable
   2.1 Loss tolerant vs guaranteed delivery
   2.2 Low latency vs high throughput
   2.3 Dynamic prioritization
   2.4 Flow can be modified at runtime
   2.5 Back pressure

3. Data Provenance
   Track dataflow from beginning to end

4. Designed for extension
   4.1 Build your own processors and more
   4.2 Enables rapid development and effective testing

5. Secure
   5.1 SSL, SSH, HTTPS, encrypted content, etc...
   5.2 Multi-tenant authorization and internal authorization/policy management

1. 基於 Web 的用戶界面
   設計、控制、反饋和監控之間的無縫體驗

2. 高度可配置
   2.1 容錯與可靠投遞
   2.2 低延遲與高吞吐量
   2.3 動態優先級
   2.4 流可以在運行時修改
   2.5 背壓

3. 數據來源
   從頭到尾跟蹤數據流

4. 專爲擴展而設計
   4.1 構建自己的處理器等
   4.2 實現快速開發和有效測試

5. 安全
   5.1 SSL、SSH、HTTPS、加密內容等...
   5.2 多租戶授權和內部授權/策略管理

官網說的很清楚了(筆者提供中英文),也很好理解,不作過多補充,大部分內容在本篇文章都有涉及。

生產環境部署的提示

作爲企業級的成熟產品,身份認證和授權是必須的。

NiFi 提供了完善的身份驗證(Authentication)和授權驗證(Authorization)。由於大部分企業級大數據平臺集成了 LDAP,所以 NiFi 需要和 LDAP 集成,方便用戶登錄和使用,以及管理員的統一管理和操作。

NiFi 要求開啓用戶驗證功能,必須設置 HTTPS 安全連接,因此需要開啓 TLS/SSL,官方提供 nifi-toolkit 工具。

nifi-toolkit 工具

爲了便於 NiFi 的安全設置,官方提供 nifi-toolkit 工具,可以使用其中的 tls-toolkit.sh 命令行自動生成所需的 keystores、truststore 以及相關配置文件。

tls-toolkit.sh 提供了 Standalone 和 Client/Server  兩種方式的操作。如下爲 standalone 生成方式:

tls-toolkit.sh standalone -C 'CN=test, OU=NIFI' -n 'nifi-node1,nifi-node2,nifi-node3,nifiregistry-node' --keyPassword xxxxx --keyStorePassword xxxxx --trustStorePassword xxxxx

生成 NiFi 三個節點(nifi-node1、nifi-node2、nifi-node3)和 NiFi Registry 一個節點(nifiregistry-node)的證書信息:

# tree ca
ca
├── CN=test_OU=NIFI.p12
├── CN=test_OU=NIFI.password
├── nifi-cert.pem
├── nifi-key.key
├── nifi-node1
│   ├── keystore.jks
│   ├── nifi.properties
│   └── truststore.jks
├── nifi-node2
│   ├── keystore.jks
│   ├── nifi.properties
│   └── truststore.jks
├── nifi-node3
│   ├── keystore.jks
│   ├── nifi.properties
│   └── truststore.jks
└── nifiregistry-node
    ├── keystore.jks
    ├── nifi.properties
    └── truststore.jks

另外對於 LDAP 配置來說,如果使用安全的 LDAPS 方式,則 LDAP Authentication Strategy 配置爲 LDAPS,如果只是普通的 LDAP,則 Authentication Strategy 配置爲 SIMPLE。

用戶認證和授權

NiFi 頁面的右上角,提供了 Users 和 Policies 功能,用來對用戶/組以及權限的管理。

身份驗證(Authentication)

在 NiFi 部署配置時,選擇 LDAP 中的一個用戶作爲 Admin 管理員即可。

打開 Users 管理臺,管理員可以添加用戶/組。

授權驗證(Authorization)

打開 Policies 管理臺,可以給上面添加的用戶和組授予權限。NiFi 提供的權限控制非常細粒度,其實除了這裏設置外,在開發數據流時,針對每個 Processor、Processor Group 和 Controller Service 等都可以設置權限。

NiFi 核心概念

NiFi 提供的概念很多,這裏簡單羅列幾個,不會深入說明。在後面的具體實戰環節中,筆者會舉例說明,這樣大家會更容易理解和應用。

FBP

在計算機編程中,基於流的編程(FBP,flow-based programming)是一種編程範例,將應用程序定義爲黑盒子(black box)進程的網絡,這些進程通過消息傳遞在預定義的連接之間交換數據,其中連接是在進程外部指定的。這些黑盒子進程可以無限地重新連接以形成不同的應用程序,而無需在內部進行更改。因此,FBP 是面向組件的。

- 摘自 Wikipedia《Flow-based programming》。

NiFi 的基本設計概念與基於流程的編程(FBP)的主要思想緊密相關。以下是 NiFi 一些主要的概念以及它們是如何映射到 FBP 的:

上面圖表中的概念後面會詳細介紹。

DataFlow Manager

DFM(數據流管理器)是一個 NiFi 用戶具有添加、刪除和修改 NiFi 數據流組件的權限。

Funnel

Funnel(字面意思爲漏斗,功能真的很像漏斗)是一個 NiFi 組件,用於將來自多個連接的數據合併到單個連接中。

Tempalte

通常,一個數據流由許多可重用的子流組成。NiFi 允許 DFMs 選擇數據流的一部分或整個數據流並創建模板,爲該模板設置一個名稱,然後可以像其他組件一樣拖放到畫布上。因此,可以將多個組件組合在一起,形成一個更大的構建塊,從而創建一個數據流。這些模板也可以作爲 XML 導出並導入到另一個 NiFi 實例中,從而允許共享這些構建塊,當然用戶也可以從 NiFi wiki 上下載 Tempalte(https://cwiki.apache.org/confluence/display/NIFI/Example+Dataflow+Templates)。

NiFi 如何工作

接下來,介紹 FBP 圖表中提及的術語。

Processor

Processor 是用於監聽傳入數據的 NiFi 組件、從外部獲取數據、對外發布數據,以及從 FlowFiles 中路由、轉換或提取信息。

從下圖中可以看到 Processor 包含的類型很多,多達 293 個,比如傳統數據庫、大數據組件、日誌文件、消息流、aws 雲服務的產品(DynamoDB、Lambda、S3 等)等:

FlowFile

FlowFile 表示 NiFi 中的單個數據塊。

1. FlowFile 組成

一個 FlowFile 由兩個組件組成:

  • FlowFile Content
    Content 是 FlowFile 真實的數據,比如通過 GetFile、GetHTTP 等方式獲取文件的實際內容。

  • FlowFile Attributes
    FlowFile 的元數據信息,包含 Content 的信息有:
    FlowFile 什麼時候創建、FlowFile 名字、FlowFile 來自哪裏、FlowFile 表示什麼等。

2. 針對 FlowFile 進行的操作

  • Processor 可以添加、更新或刪除 FlowFile attributes

  • 修改 FlowFile content

3. FlowFile 生命週期

Connection

DFM 通過將組件從 NiFi 工具欄(NiFi 左上角)的組件部分拖動到畫布上,然後通過 Connection 將組件連接在一起,從而創建一個自動化的數據流。每個 Connection 都包含一個 FlowFile Queue。

簡單理解就是:

  • Connection 是指 Processor 或 Process Group 之間的連接。

  • 每個 Connection 都包含 FlowFile 的一個 Queue,用於緩存傳輸的流數據,並可設置 Back Pressure。

Process Group

當一個數據流變得複雜時,最好在更高更抽象的層次上對數據流進行設計和管理。NiFi 允許將多個組件(例如 Processors)組合到一個 Process Group 中。NiFi 用戶可以輕鬆地將多個 Process Group 連接在一起形成邏輯數據流,並允許 DFM 進入 Process Group 以查看和操作處理組中的組件。

也就說,針對一個複雜的業務處理數據流,建議最好使用邏輯的 Process Group 來組織這個複雜的 processes,方便維護這些數據流。另外 Process Group 還有 Input/Ouput Port,可以用來在它們之間移動數據。

Controller Service

Controller Service 用來被 processes 使用。比如一個 process 需要寫入或讀取數據庫的數據,需要使用一個 Controller Service 用來建立數據庫的連接信息。

筆者在測試環境中創建了一些 Controller Service,包括 HBase 連接、Kerberos 配置:

截止目前,NiFi 提供了 65+ 種 Controller Service。另外在權限控制方面,可以對每個 Controller Service 進行授權操作。

Processors 包羅萬象

既然要進行數據流開發,那麼用戶就要大概瞭解 NiFi 裏面的 Processors 有哪些類型。下面,筆者和大家一起整理歸納一下。

數據攝取 Processors

數據轉換 Processors

數據流出/發送數據 Processors

路由和中轉 Processors

數據庫訪問 Processors

Attribute 抽取 Processors

系統交互 Processors

切分和聚合 Processors

HTTP 和 UDP Processors

Amazon Web Services Processors

Connection Queue & Back Pressure 實驗

筆者使用 GenerateFlowFile 進行測試,默認 Processors 會在 NiFi 集羣所有節點執行,可以對 Processors 執行節點進行設置(這裏保持默認值):

當筆者在 GenerateFlowFile Processor 上點擊 Start 後,可以清楚地看到 Queued 達到 30000 時就停止。打開 Connection Details 查看,可以看到 Back Pressure Object Threshold 默認爲 10000,Size Threshold 大小爲 1 GB,因爲筆者的 NiFi 集羣有三個節點,就乘以 3 倍即可。

另外 Back Pressure 也可以根據數據量的大小,默認爲 1 GB:

Attributes & Content 實驗

筆者將這個數據流功能描述一下:

  • GenerateFlowFile 在 NiFi Primary 節點運行,每隔 5s 生成一個文件,大小爲 1B

  • ReplaceText 將 GenerateFlowFile 產生的每個 1B 大小的數據流替換爲 A,B,C,D

  • ExtractText 將 ReplaceText 轉換的數據流解析爲 CSV 格式,以逗號分隔

筆者執行該數據流後,每隔 5s 獲取的最後數據流的屬性爲:

爲了便於查看數據流中數據值的變化,可以執行第一個 Processor 生成一條數據後,停止該 Processor 執行,然後依次執行後續的 Processor。

Expression Language 實驗

接着上面的數據流,筆者繼續添加一個 ReplaceText:

  • ReplaceText 將 ExtractText 轉換的 CSV 格式替換爲 JSON 格式
    其中配置 ReplaceText Replacement Value 值爲:

{
    "field1": "${csv.1}",
    "field2": "${csv.2}",
    "field3": "${csv.3}",
    "field4": "${csv.4}"
}

筆者執行該數據流後,每隔 5s 獲取的最後數據流值爲:

{
    "field1": "A",
    "field2": "B",
    "field3": "C",
    "field4": "D"
}

補充實驗

筆者繼續添加更多的 Processor 進行數據流轉換處理:

  • UpdateAttribute 修改 filename 的格式,配置 filename 屬性值爲:

${filename}-${now():toNumber():format("yyyy-MM-dd_HHmmss")}.json

  • PutFile 將 UpdateAttribute 修改後的文件寫入指定的目錄

Process Group 實驗

在 NiFi 中可以創建 Process Group,比如筆者創建名爲 CSV to JSON 的 Process Group:

然後將上面的設計數據流歸類到這個 Process Group 中(深深地按住 Shift,然後溫柔地使用鼠標框選數據流,並拖到 Process Group 中):

上圖中的左下角可以看到對應的 Process Group。

Input Port & Output Port 實驗

下面我們來看一下 Input Port & Output Port。

首先在 Process Group 名爲 CSV to JSON 中繼續創建一個 Process Group,名稱爲 Write JSON to File System,然後將數據流中的一部分拖入到該 Process Group 中,如下:

遷移之前,要將拖動的數據流斷開與其他 Processor 的連接。

遷移完成後,進入 Write JSON to File System 進程組中:

接着將 Write JSON to File System 移動到上一層級,和 CSV to JSON 處理同一級:

到此,我們擁有了兩個 Process Group,接下來筆者需要將它們連接起來,這裏就會涉及到使用 Input Port 和 Output Port。

我們在 CSV to JSON 中添加 Output Port,名稱爲 Output_JSON:

然後將數據流連接到 Output_JSON:

接着繼續在 Write JSON to File System 中添加 Input Port,名稱爲 Input_JSON,並連接到數據流,作爲數據源:

Input Port 和 Output Port 添加完成後,我們將兩個 Process Group 連接起來,注意要選擇好 Input 和 Output Port 的名稱:

然後執行兩個 Process Group(CSV to JSON 和 Write JSON to File System),驗證一下結果:

# pwd
/data2/nifi/output

# ll
total 16
-rw-r--r-- 1 nifi nifi 78 Apr 16 17:29 2e74b68d-ddc2-4ce7-8b8c-3e217ecc45fd-2020-04-16_172929.json
-rw-r--r-- 1 nifi nifi 78 Apr 16 17:29 63909e35-3725-4d8b-b12d-58fa8182be65-2020-04-16_172939.json
-rw-r--r-- 1 nifi nifi 78 Apr 16 17:29 6bc134d6-d3d0-43d8-bfd6-034d071532b6-2020-04-16_172944.json
-rw-r--r-- 1 nifi nifi 78 Apr 16 17:29 9df9052f-c7ea-417c-bd62-5129ed7c0804-2020-04-16_172934.json

# cat 2e74b68d-ddc2-4ce7-8b8c-3e217ecc45fd-2020-04-16_172929.json
{
    "field1": "A",
    "field2": "B",
    "field3": "C",
    "field4": "D"
}

每隔 5s 生成 1 個文件。

Templates 實驗

這些問題可以通過 NiFi Template 來解決。

比如,我們根據 CSV to JSON 這個 Process Group 中的某些數據流創建一個模版:

也可以根據 Process Group 來創建:

當然 NiFi 也提供了很多模版:
https://cwiki.apache.org/confluence/display/NIFI/Example+Dataflow+Templates

比如使用 Retry_Count_Loop.xml,只需要下載
https://cwiki.apache.org/confluence/download/attachments/57904847/Retry_Count_Loop.xml?version=1&modificationDate=1433271239000&api=v2&download=true

並導入 NiFi 中即可:

大家可以在 NiFi 右上角查看 Templates 信息:

版本控制

NiFi 數據流的開發往往會涉及到一個團隊協同開發,這時就需要進行版本控制。爲了解決版本控制的問題,NiFi 使用子項目 NiFi Registry 來實現該功能,這一塊後續單獨講解。

NiFi Registry

根據下面的幾頁 slides,大家能夠對 Registry 有一個初步的瞭解。

Funnel 實驗

Funnel 的功能其實很簡單,如其名字一樣,將來自多個連接的數據流合併到單個連接。

首先看一個問題:

這裏 Output 和 Input Port 脫離 Process Group 後是無法連接,不過我們可以使用 Funnel 功能來解決:

來源的數據流可以有很多個,最後通過 Funnel 匯聚爲一個數據流。

NiFi 監控

NiFi 通過 Bulletin Board 提供了非常完善的監控,這一塊同樣會單獨講解,包括數據流查看和調試等。

決定數據流效率的關鍵因素

NiFi 集羣是可以線性擴展,單個 NiFi 集羣每天可以處理數萬億個事件和 PB 級數據,並具有完整的數據來源和血緣。

總結

在本篇文章中,筆者基本上講解了 NiFi 的所有內容,雖然有的方面只是提及,並未深入說明,但是讀者至少明白該如何去研究和實踐。

關於 NiFi 的更多內容,等着,我還會再回來的。

              你若喜歡,點個在看

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章