Apache NiFi深度擴展

介紹

該高級文檔旨在深入瞭解NiFi的實施和設計決策。它假設讀者已經閱讀了足夠的其他文檔來了解NiFi的基礎知識。

FlowFiles是NiFi的核心,也是基於流程的設計。FlowFile是一種數據記錄,由指向其內容(有效負載)的指針和支持內容的屬性組成,該指針與一個或多個起源事件相關聯。屬性是用作FlowFile元數據的鍵/值對,例如FlowFile文件名。內容是文件的實際數據或有效負載。原產地是FlowFile發生的事情的記錄。這些部分中的每一個都有自己的存儲庫(repo)用於存儲。

存儲庫的一個關鍵方面是不可變性。內容存儲庫中的內容和FlowFile存儲庫中的數據是不可變的。當FlowFile的屬性發生更改時,屬性的新副本將在內存中創建,然後保留在磁盤上。當爲給定的FlowFile更改內容時,將讀取其原始內容,通過轉換進行流式處理,並將其寫入新流。然後FlowFile的內容指針更新到磁盤上的新位置。因此,FlowFile內容存儲的默認方法可以說是不可變版本的內容存儲。這樣做的好處很多,包括:大幅減少典型的複雜處理圖所需的存儲空間,自然重放功能,利用操作系統緩存,降低隨機讀/寫性能,很容易推理。以前的修訂版根據“nifi.properties”文件中設置的歸檔屬性進行保存,並在中進行了概述NiFi系統管理員指南

庫(Repositories)

NiFi使用了三個存儲庫。每個都存在於OS / Host的文件系統中,並提供特定的功能。爲了完全理解FlowFiles以及底層系統如何使用它們,瞭解這些存儲庫非常重要。所有三個存儲庫都是NiFi用於保存數據的本地存儲上的目錄。

  •  FlowFile Repository  包含流中所有當前FlowFiles的元數據。

  •  Content Repository保存當前和過去的FlowFiles的內容。

  • Provenance Repository 保存FlowFiles的歷史記錄。

FlowFile存儲庫

系統主動處理的FlowFiles保存在JVM內存中的哈希映射中(更多關於Deeper View中的內容:內存和磁盤上的FlowFiles))。這使得處理它們非常有效,但是由於諸多原因(例如斷電,內核緊張,系統升級和維護週期),需要輔助機制來提供跨流程重啓的數據持久性。FlowFile存儲庫是系統中當前存在的每個FlowFiles的元數據的“預寫日誌(Write-Ahead Log)”(或數據記錄)。此FlowFile元數據包括與FlowFile關聯的所有屬性,指向FlowFile的實際內容的指針(存在於內容回購中)和FlowFile的狀態,例如FlowFile所屬的Connection / Queue。 Ahead Log爲NiFi提供了處理重啓和意外系統故障所需的彈性。

FlowFile存儲庫充當NiFi的預寫日誌,因此當FlowFiles流經系統時,每個更改都會在作爲事務工作單元發生之前記錄在FlowFile存儲庫中。這允許系統在處理一段數據時準確地知道節點處於什麼步驟。如果節點在處理數據時出現故障,則可以輕鬆地從重新啓動時停止的位置恢復(更深入地介紹事務中系統故障的影響)。日誌中FlowFiles的格式是沿途發生的一系列增量(或更改)。NiFi通過恢復FlowFile的“快照”(在Repository指向檢查時創建)然後重放每個增量來恢復FlowFile。

系統會定期自動拍攝快照,從而爲每個FlowFile創建一個新快照。系統通過序列化哈希映射中的每個FlowFile並使用文件名“.partial”將其寫入磁盤來計算新的基本檢查點。隨着檢查點的進行,新的FlowFile基線被寫入“.partial”文件。檢查點完成後,將刪除舊的“快照”文件,並將“.partial”文件重命名爲“snapshot”。

系統檢查點之間的時間段可在“nifi.properties”文件中進行配置(在“ NiFi系統管理員指南”中有說明)。默認值爲兩分鐘。

系統失敗對交易的影響(Effect of System Failure on Transactions)

NiFi通過在各自的FlowFile Repo中記錄當時每個節點上發生的事情來防止硬件和系統故障。如上所述,FlowFile Repo是NiFi的預寫日誌。當節點重新聯機時,它首先檢查“快照”和“.partial”文件,以恢復其狀態。節點接受“快照”並刪除“.partial”(如果存在),或者如果“快照”文件不存在,則將“.partial”文件重命名爲“snapshot”。

如果節點在內容發生故障時處於寫入內容的中間,那麼由於Copy On Write(下面提到)和Immutability(上面提到的)範例,沒有任何內容被破壞。由於FlowFile事務從不修改原始內容(由內容指針指向),因此原始內容是安全的。當NiFi發生故障時,對更改的寫入聲明將成爲孤立狀態,然後通過後臺垃圾收集進行清理。這提供了對最後已知穩定狀態的“回滾”。

然後,Node從FlowFile恢復其狀態。有關該過程的更深入,逐步說明,請參閱 NiFi的預寫日誌實施

就交易工作單元而言,這種設置允許NiFi在逆境中具有很強的彈性,確保即使NiFi突然被殺死,它也可以在沒有任何數據丟失的情況下進行回收。

更深入的視野:內存和磁盤上的FlowFiles ( Deeper View: FlowFiles in Memory and on Disk )

術語“FlowFile”有點用詞不當。這將導致人們相信每個FlowFile對應於磁盤上的文件,但事實並非如此。FlowFile屬性存在兩個主要位置,上面說明的預寫日誌和工作內存中的哈希映射。此哈希映射引用了Flow中正在使用的所有FlowFiles。此映射引用的對象與處理器使用並保存在連接隊列中的對象相同。由於FlowFile對象保存在內存中,因此處理器獲取FlowFile所需要做的就是讓ProcessSession從隊列中獲取它。

當FlowFile發生更改時,delta會寫入Write-Ahead Log,並相應地修改內存中的對象。這允許系統快速使用FlowFiles,同時還可以跟蹤發生的事件以及提交會話時將發生的情況。這提供了非常堅固耐用的系統。

還有“交換”FlowFiles的概念。當連接隊列中的FlowFiles數超過“nifi.queue.swap.threshold”屬性中設置的值時,會發生這種情況。連接隊列中具有最低優先級的FlowFile被序列化並以10,000個批次的“交換文件”寫入磁盤。然後從上面提到的哈希映射中刪除這些FlowFiles,連接隊列負責確定何時將文件交換回內存。當FlowFiles被換出時,會通知FlowFile repo並保留交換文件的列表。系統檢查點時,快照包含換出文件的部分。重新交換交換文件時,FlowFiles會重新添加到哈希映射中。這種交換技術,

內容存儲庫(Content Repository)

內容存儲庫只是本地存儲中的一個位置,其中存在所有FlowFiles的內容,它通常是三個存儲庫中最大的。如介紹部分所述,此存儲庫利用不變性和寫時複製範例來最大化速度和線程安全性。影響內容回購的核心設計決策是將FlowFile的內容保存在磁盤上,並在需要時將其讀入JVM內存。這使得NiFi可以處理微小且大型的對象,而無需生產者和消費者處理器將完整的對象保存在內存中。因此,在不損害內存的情況下,分割,聚合和轉換非常大的對象等操作非常容易。

以同樣的方式,JVM Heap具有垃圾收集過程以在需要空間時回收無法到達的對象時,NiFi中存在專用線程來分析未使用內容的內容存儲庫(更多信息在“更深層視圖:刪除檢查點後”) “ 部分)。在將FlowFile的內容標識爲不再使用後,它將被刪除或存檔。如果在'nifi.properties'中啓用了歸檔,那麼FlowFile的內容將存在於內容回購中,直到它老化(在一定時間後刪除)或由於內容回購佔用太多空間而被刪除。存檔和/或刪除的條件在'nifi.properties'文件中配置(“nifi.content.repository.archive.max.retention.period”,“nifi.content.repository.archive.max.usage.percentage”NiFi系統管理員指南。有關刪除內容的更多信息,請參閱“數據出口”部分。

更深入的視野:內容聲明(Deeper View: Content Claim)

通常,在談論FlowFile時,對其內容的引用可以簡稱爲內容的“指針”。但是,FlowFile內容參考的底層實現具有多層複雜性。內容存儲庫由磁盤上的文件集合組成。這些文件被分箱到容器和部分中。Section是Container的子目錄。可以將Container視爲內容存儲庫的“根目錄”。但是,內容存儲庫可以由許多容器組成。這樣做是爲了讓NiFi能夠並行利用多個物理分區。“NiFi能夠並行讀取和寫入所有這些磁盤,以實現數百兆字節甚至千兆字節的數據速率。單個節點上的第二個磁盤吞吐量。

爲了跟蹤FlowFile的內容,FlowFile有一個“Content Claim”對象。此內容聲明引用了資源聲明,其中包含內容,文件內容的偏移量以及內容的長度。要訪問內容,內容存儲庫使用Resource Claim的屬性向下鑽取到磁盤上的特定文件,然後在從文件傳輸內容之前尋找資源聲明指定的偏移量。

完成了這一抽象層(資源聲明),因此磁盤上沒有每個FlowFile內容的文件。不變性的概念是實現這一目標的關鍵。由於內容在寫入後永遠不會更改(“寫入時複製”用於進行更改),因此如果FlowFile的內容發生更改,則不會出現內存碎片或移動數據。通過利用磁盤上的單個文件來保存許多FlowFiles的內容,NiFi能夠提供更好的吞吐量,通常接近磁盤提供的最大數據速率。

起源庫(Provenance Repository)

Provenance Repository是存儲每個FlowFile的歷史記錄的地方。該歷史記錄用於提供每條數據的數據沿襲(也稱爲監管鏈)。每次爲FlowFile發生事件(FlowFile被創建,分叉,克隆,修改等)時,都會創建一個新的來源事件。此來源事件是FlowFile的快照,因爲它看起來很適合當時存在的流程。創建起源事件時,它會複製所有FlowFile的屬性和指向FlowFile內容的指針,並將FlowFile的狀態(例如與其他起源事件的關係)聚合到Provenance Repo中的一個位置。除了數據過期之外,此快照不會更改。

由於所有FlowFile屬性和指向內容的指針都保存在Provenance Repository中,因此Dataflow Manager不僅能夠查看該數據的譜系或處理歷史記錄,而且還能夠以後查看數據本身甚至可以從流程中的任何一點重放數據。這種情況的一個常見用例是特定的下游系統聲稱沒有收到數據。數據沿襲可以準確顯示數據何時傳送到下游系統,數據的樣子,文件名以及數據發送到的URL - 或者可以確認數據確實從未發送過。在任何一種情況下,只需單擊按鈕(或通過訪問適當的HTTP API端點)即可重播Send事件,以便僅將數據重新發送到該特定下游系統。或者,

但請記住,由於Provenance不會複製內容回購中的內容,只是將FlowFile的指針複製到內容,因此可以在刪除引用它的出處事件之前刪除內容。這意味着用戶將無法再查看內容或稍後重播FlowFile。但是,用戶仍然可以查看FlowFile的血統並瞭解數據發生了什麼。例如,即使數據本身不可訪問,用戶仍然能夠看到數據的唯一標識符,文件名(如果適用),接收時間,接收地點,操作方式,發送的地方,等等。此外,由於FlowFile的屬性可用,

  由於起源事件是FlowFile的快照,因爲它存在於當前流中,因此對流的更改可能會影響以後重放起源事件的能力。例如,如果從流中刪除了連接,則無法從流中的該點重放數據,因爲現在無法將數據排入隊列以進行處理。

有關Provenance Repository背後的設計決策,請查看Persistent Provenance Repository Design

更深入的視野:原型日誌文件(Deeper View: Provenance Log Files)

每個來源事件都有兩個映射,一個用於事件之前的屬性,另一個用於更新的屬性值。通常,來源事件不會存儲在發出事件時存在的屬性的更新值,而是存儲會話提交時的屬性值。事件被緩存並保存,直到提交會話爲止,一旦提交了會話,就會在提交會話時使用與FlowFile關聯的屬性發出事件。此規則的例外是“SEND”事件,在這種情況下,事件包含發出事件時存在的屬性。這樣做是因爲如果還發送了屬性本身,則準確地說明確切地發送了哪些信息非常重要。

隨着NiFi的運行,有一個由16個出處日誌文件組成的滾動組。當發現起源事件時,它們被寫入16個文件中的一個(有多個文件來增加吞吐量)。定期滾動日誌文件(默認時間範圍是每30秒)。這意味着新創建的出處事件開始寫入一組16個日誌文件,並處理原始文件以進行長期存儲。首先,將翻轉的日誌合併到一個文件中。然後可選地壓縮文件(由“nifi.provenance.repository.compress.on.rollover”屬性確定)。最後,事件使用Lucene編制索引並可用於查詢。

一個單獨的線程處理原始日誌的刪除。管理員可以設置控制刪除源項日誌的兩個條件是它可以佔用的最大磁盤空間量以及日誌的最大保留持續時間。線程按上次修改日期對repo進行排序,並在超出其中一個條件時刪除最舊的文件。

Provenance Repo是一個Lucene索引,分爲多個分片。這是出於多種原因。首先,Lucene使用32位整數作爲文檔標識符,因此Lucene支持的沒有分片的最大文檔數量是有限的。其次,如果我們知道每個分片的時間範圍,就可以輕鬆搜索多個線程。此外,這種分片還允許更有效的刪除。在從磁盤中刪除整個分片之前,NiFi會一直等到分片中的所有事件都被安排刪除。這使得我們在刪除時不必更新Lucene索引。

通用存儲庫說明

多個物理存儲點

對於Provenance和Content repos,可以選擇跨多個物理分區對信息進行條帶化。如果管理員想要跨多個磁盤聯合讀寫,那麼管理員就會這樣做。repo(Content或Provenance)仍然是一個邏輯存儲,但是系統會自動在多個卷/分區上劃分寫入。這些目錄在'nifi.properties'文件中指定。

最佳實踐

最好的做法是儘可能少地分析FlowFile的內容,而是將內容中的關鍵信息提取到FlowFile的屬性中; 然後從FlowFile屬性讀取/寫入信息。其中一個例子是ExtractText處理器,它從FlowFile內容中提取文本並將其作爲屬性放置,以便其他處理器可以使用它。這提供了比連續處理FlowFile的整個內容更好的性能,因爲屬性保存在內存中,並且根據存儲在每個內容庫中的數據量,更新FlowFile存儲庫比更新內容存儲庫快得多。

FlowFile的生命

爲了更好地理解repos如何相互影響,NiFi的基本功能以及FlowFile的生命週期; 下一節將包括實際流程中不同點的FlowFile示例。該流程是一個名爲“WebCrawler.xml”的模板,可在此處獲取:https//cwiki.apache.org/confluence/display/NIFI/Example+Dataflow+Templates

在較高級別,此模板可以訪問GetHTTP處理器中配置的種子URL,然後使用RouteText處理器分析響應,以查找關鍵字的實例(在本例中爲“nifi”),以及要觸發的潛在URL。然後,InvokeHTTP使用原始種子網頁中找到的URL執行HTTP Get請求。響應根據狀態代碼屬性進行路由,並且只有200-202個狀態代碼被路由回原始的RouteText處理器進行分析。

該流還會檢測重複的URL並阻止再次處理它們,在找到關鍵字時向用戶發送電子郵件,記錄所有成功的HTTP請求,並捆綁成功的請求以在磁盤上壓縮和存檔。

  要使用此流程,您需要配置幾個選項。首先,必須使用默認屬性添加DistributedMapCacheServer控制器服務。在撰寫本文時,無法將控制器服務顯式添加到模板中,因爲沒有處理器引用該服務,因此不包括該服務。另外,要獲取電子郵件,必須使用您的電子郵件憑據配置PutEmail處理器。最後,要使用HTTPS,必須使用正確的密鑰和信任存儲配置StandardSSLContextService。請記住,必須使用適當的證書頒發機構配置信任庫才能使用網站。下面的命令是使用“keytool”命令將默認Java 1.8.0_60 CA添加到名爲myTrustStore的信任庫的示例:keytool -importkeystore -srckeystore /Library/Java/JavaVirtualMachines/jdk1.8.0_60。

Web爬蟲模板

 

 

 

 

  由於Web爬行的隨機性,在InvokeHttp處理器上出現諸如“連接超時”之類的消息的公告並不罕見。

數據入口

當生產者處理器調用“ProcessSession.create()”,然後調用ProvenanceReporter時,在系統中創建FlowFile。“ProcessSession.create()”調用創建一個空的FlowFile,其中包含一些核心屬性(標準進程會話的文件名,路徑和uuid),但沒有父項的任何內容或沿襲(create方法被重載以允許父FlowFiles的參數)。然後,生產者處理器將內容和屬性添加到FlowFile。

ProvenanceReporter用於爲FlowFile發出Provenance事件。如果文件由NiFi從外部實體未接收的數據創建,則應發出“CREATE”事件。如果數據是根據從外部源接收的數據創建的,則應發出“RECEIVE”事件。Provenance事件分別使用“ProvenanceReporter.create()”和“ProvenanceReporter.receive()”進行。

在我們的WebCrawler流程中,GetHTTP處理器使用“ProcessSession.create()”創建初始FlowFile,並使用“ProvenanceReporter.receive()”記錄數據的接收。此方法調用還提供從中接收數據的URL,傳輸數據所花費的時間以及添加到FlowFile的任何FlowFile屬性。例如,HTTP標頭可以添加爲FlowFile屬性。

通過參考傳遞

基於流的編程的一個重要方面是黑盒之間資源受限關係的概念。在NiFi中,這些分別是隊列和處理器。只需將引用傳遞給FlowFile(類似於EIP中的“Claim Check”模式),FlowFiles就可以通過隊列從一個處理器路由到另一個處理器。

在WebCrawler流程中,InvokeHTTP處理器通過HTTP GET請求到達URL,並根據HTTP服務器的響應向FlowFile添加狀態代碼屬性。更新FlowFile的文件名後(在InvokeHttp之後的UpdateAttribute處理器中)有一個RouteOnAttribute處理器,它將具有成功狀態代碼屬性的FlowFiles路由到兩個不同的處理器。RouteOnAttribute處理器“刪除”那些不匹配的(“數據出口”部分),因爲它被配置爲自動終止任何與任何路由規則不匹配的數據。進入RouteOnAttribute處理器有一個FlowFile(F1),它包含狀態代碼屬性並指向內容(C1)。有一個起源事件指向C1幷包含F1的快照但省略以更好地關注路由。此信息分別位於FlowFile,Content和Provenance Repos中。

在RouteOnAttribute處理器檢查FlowFile的狀態代碼屬性後,它確定應將其路由到兩個不同的位置。首先發生的事情是處理器克隆FlowFile來創建F2。這會複製所有屬性和指向內容的指針。由於它僅僅是路由和分析屬性,因此內容不會改變。然後將FlowFiles添加到相應的連接隊列以等待下一個處理器檢索它們以進行處理。

ProvenanceReporter記錄發生的更改,包括CLONE和兩個ROUTE事件。每個事件都有一個指向相關內容的指針,並以快照的形式包含相應FlowFiles的副本。

擴展路由用例

除了基於屬性路由FlowFiles之外,一些處理器還基於內容進行路由。雖然效率不高,但有時需要將FlowFile的內容拆分爲多個FlowFiles。

一個例子是SplitText處理器。此處理器分析查找結束行字符的內容,並創建包含可配置行數的新FlowFiles。Web Crawler流程使用它將潛在的URL拆分爲單行以進行URL提取,並充當InvokeHttp的請求。SplitText處理器的一個好處是,由於處理器正在拆分連續的塊(沒有FlowFile內容是不相交或重疊的),處理器可以在不復制任何內容的情況下進行此路由。它所做的只是創建新的FlowFiles,每個FlowFiles都有一個指向原始FlowFile內容的一部分的指針。這可以通過NiFi API內置的內容劃分和拆分工具實現。雖然在可行的情況下以這種方式分割並不總是可行的,但性能益處是相當大的。

RouteText是一個處理器,它顯示了爲什麼某些樣式的路由可能需要複製內容。該處理器分析每一行並根據可配置屬性將其路由到一個或多個關係。當多個行被路由到相同的關係時(對於相同的輸入FlowFile),這些行被合併到一個FlowFile中。由於行可能是不相交的(第1行和第100行路由到相同的關係)並且一個指針無法準確描述FlowFile的內容,因此處理器必須將內容複製到新位置。例如,在Web Crawler流程中,RouteText處理器將包含“nifi”的所有行路由到“NiFi”關係。因此,當有一個輸入FlowFile在網頁上多次出現“nifi”時,

漏斗

漏斗是一個組件,它從一個或多個連接獲取輸入並將它們路由到一個或多個目標。用戶指南中描述了其典型用例。無論用例如何,如果漏斗下游只有一個處理器,那麼漏斗就不會發現物源事件,它在原型圖中看起來是不可見的。如果有多個下游處理器(如WebCrawler中的處理器),則會發生克隆事件。參考下圖,您可以看到從原始FlowFile(F1)克隆了一個新的FlowFile(F2),就像上面的Routing一樣,新的FlowFile只有一個指向相同內容的指針(內容不會被複制) )。

從開發人員的角度來看,您可以將漏斗視爲一個非常簡單的處理器。當它被安排運行時,它只是對輸出連接執行“ProcessSession.get()”然後“ProcessSession.transfer()”。如果有多個輸出連接(如下例所示),則運行“ProcessSession.clone()”。最後調用“ProcessSession.commit()”,完成交易。

寫入時複製

在前面的示例中,只有路由但沒有更改FlowFile的內容。下一個示例重點介紹模板的CompressContent處理器,該處理器壓縮包含排隊等待分析的網頁的合併FlowFiles包。

在此示例中,FlowFile F1的內容C1正在CompressContent處理器中進行壓縮。由於C1是不可變的,我們想要一個完全可重複播放的起源歷史,我們不能只覆蓋C1。爲了“修改”C1,我們執行“寫入時複製”,我們通過在將內容複製到內容存儲庫中的新位置時修改內容來實現。執行此操作時,FlowFile引用F1將更新爲指向新的壓縮內容C2,並創建引用新FlowFile F1.1的新Provenance事件P2。因爲FlowFile repo是不可變的,所以不是修改舊F1,而是創建新的delta(F1.1)。以前的來源事件仍然具有指向Content C1的指針幷包含舊屬性,但它們不是FlowFile的最新版本。

  爲了專注於Copy on Write事件,省略了導致此點的FlowFile(F1)起源事件。

寫用例的擴展複製

Copy on Write的一個獨特案例是MergeContent處理器。幾乎每個處理器一次只能作用於一個FlowFile。MergeContent處理器的獨特之處在於它接收多個FlowFiles並將它們合併爲一個。目前,MergeContent有多種不同的合併策略,但所有這些都需要將輸入FlowFiles的內容複製到新的合併位置。在MergeContent完成之後,它會發出類型爲“JOIN”的起源事件,該事件確定給定的父項連接在一起以創建新的子FlowFile。

更新屬性

使用FlowFile的屬性是NiFi的核心方面。假設每次處理器在其上執行時,屬性足夠小以完全讀入本地存儲器。因此,它們易於使用非常重要。由於屬性是路由和處理FlowFile的核心方式,因此只需更改FlowFile屬性的處理器就很常見。一個這樣的例子是UpdateAttribute處理器。所有UpdateAttribute處理器都會根據處理器的屬性更改傳入的FlowFile屬性。

看一下圖表,在處理器之前有FlowFile(F1),它有屬性和指向內容的指針(C1)。處理器通過創建仍具有指向內容(C1)的指針的新增量(F1.1)來更新FlowFile的屬性。發生這種情況時會發出“ATTRIBUTES_MODIFIED”來源事件。

在此示例中,先前的處理器(InvokeHTTP)從URL獲取信息並創建新的響應FlowFile,其文件名屬性與請求FlowFile相同。這無助於描述響應FlowFile,因此UpdateAttribute處理器將filename屬性修改爲更相關的內容(URL和事務ID)。

  爲了集中於ATTRIBUTES_MODIFIED事件,省略了導致此點的FlowFile(F1)起源事件。

典型用例說明

除了通過UpdateAttribute添加任意屬性之外,從FlowFile的內容中提取信息到屬性中是一個非常常見的用例。Web Crawler流程中的一個這樣的示例是ExtractText處理器。當它嵌入FlowFile的內容時,我們不能使用URL,因此我們從FlowFile的內容中提取URL並將其作爲屬性放置。這樣我們就可以使用表達式語言在InvokeHttp的URL屬性中引用該屬性。

數據出口

最終,NiFi中的數據將達到已加載到另一個系統並且我們可以停止處理它的點,或者我們將FlowFile過濾掉並確定我們不再關心它。無論哪種方式,FlowFile最終都會被“刪除”。“DROP”是一個起源事件,意味着我們不再在Flow中處理FlowFile並且可以刪除它。它保留在FlowFile存儲庫中,直到下一個存儲庫檢查點。Provenance Repository將Provenance事件保留在'nifi.properties'中規定的時間內(默認爲24小時)。一旦FlowFile離開NiFi並且將預寫日誌的後臺檢查點處理髮生到緊湊/刪除,則內容回購中的內容將被標記爲刪除。這是因爲除非另一個FlowFile引用相同的內容或者在'nifi.properties'中啓用了歸檔。如果啓用了歸檔,則內容將一直存在,直到達到最大磁盤百分比或達到最大保留期限(也在'nifi.properties'中設置)。

更深入的視圖:檢查點後刪除

  此部分主要依賴於上面“深層視圖:內容聲明”部分中的信息。

一旦“.partial”文件與底層存儲機制同步並重命名爲新快照(詳見FlowFile Repo部分),就會回調FlowFile Repo以釋放所有舊內容聲明(這是在檢查點後完成的)如果出現問題,內容不會丟失)。FlowFile Repo知道可以發佈哪些內容聲明並通知資源聲明管理器。資源聲明管理器跟蹤已發佈的所有內容聲明以及準備刪除哪些資源聲明(當流中不再有任何FlowFiles引用它時,資源聲明已準備好被刪除)。

內容回購會定期向資源聲明管理器詢問可以清除哪些資源聲明。然後,內容回購決定是否應歸檔或刪除資源聲明(基於'nifi.properties'文件中“nifi.content.repository.archive.enabled”屬性的值)。如果禁用存檔,則只需從磁盤中刪除該文件。否則,運行後臺線程以查看何時應刪除存檔(基於上述條件)。此後臺線程保留10,000個最舊內容聲明的列表,並將其刪除,直到低於必要閾值。如果內容聲明用完,它會掃描倉庫中最舊的內容以重新填充列表。這提供了一個在Java堆利用率和磁盤I / O利用率方面都高效的模型。

關聯不同的數據

Provenance Repository的一個特性是它允許有效訪問順序發生的事件。然後可以使用NiFi報告任務來迭代這些事件並將它們發送到外部服務。如果其他系統也向此外部系統發送類似類型的事件,則可能需要將NiFi FlowFile與另一條信息相關聯。例如,如果使用GetSFTP來檢索數據,則NiFi使用其自己的唯一UUID來引用該FlowFile。但是,如果放置文件的系統通過文件名引用文件,則NiFi應該有一種機制來指示這些是同一條數據。這是通過調用ProvenanceReporter.associate()方法並提供FlowFile的UUID和備用名稱(在本例中爲文件名)來完成的。由於確定兩個數據相同可能是流依賴的,因此DataFlow Manager通常需要進行此關聯。一種簡單的方法是使用UpdateAttribute處理器並將其配置爲設置“alternate.identifier”屬性。這會自動發出“associate”事件,使用添加的任何值作爲“alternate.identifier”屬性。

閉幕致辭

NiFi與三個存儲庫結合使用寫時複製,傳遞引用和不變性概念,是一個快速,高效,強大的企業數據流平臺。本文檔介紹了可插拔接口的具體實現。其中包括FlowFile存儲庫的基於Write-Ahead Log的實現,基於文件的Provenance存儲庫和基於文件的內容存儲庫。這些實現是NiFi默認設置,但是可插拔,因此,如果需要,用戶可以編寫自己的實現以滿足某些用例。

希望本文檔能夠讓您更好地瞭解NiFi的低級功能及其背後的決策。如果您希望更深入地解釋某些內容,或者您​​認爲應該包含這些內容,請隨時發送電子郵件至Apache NiFi Developer郵件列表([email protected])。

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