事件中樞和Azure Functions的效能和規模指引

Azure 事件中樞
Azure Functions

本文提供在應用程式中一起使用Azure 事件中樞和Azure Functions時,優化延展性和效能的指引。

函式群組

一般而言,函式會在事件處理資料流程中封裝工作單位。 例如,函式可以將事件轉換成新的資料結構,或擴充下游應用程式的資料。

在 Functions 中,函式應用程式會提供函式的執行內容。 函式應用程式行為適用于函式應用程式裝載的所有函式。 函式應用程式中的函式會一起部署,並一起調整。 函數應用程式中的所有函式都必須是相同語言。

如何將函式分組至函式應用程式,可能會影響函式應用程式的效能和調整功能。 您可以根據叫用程式碼的存取權、部署和使用模式來分組。

如需群組和其他層面之函式最佳做法的指引,請參閱可靠Azure Functions的最佳作法改善Azure Functions的效能和可靠性

下列清單是群組函式的指引。 指導方針會考慮儲存體和取用者群組層面:

  • 在函式應用程式中裝載單一 函式:如果事件中樞觸發函式,您可以減少該函式與其他函式之間的競爭,在自己的函式應用程式中隔離函式。 如果其他函式需要大量 CPU 或記憶體,隔離就特別重要。 這項技術有助於因為每個函式都有自己的記憶體使用量和使用模式,而這可能會直接影響裝載它的函式應用程式調整。

  • 為每個函式應用程式提供自己的儲存體帳戶: 避免在函式應用程式之間共用儲存體帳戶。 此外,如果函式應用程式使用儲存體帳戶,請勿將該帳戶用於其他儲存體作業或需求。 請務必避免共用事件中樞觸發之函式的儲存體帳戶,因為這類函式可能會因為檢查點而擁有大量儲存體交易。

  • 為每個函式應用程式建立專用的取用者群組: 取用者群組是事件中樞的檢視。 不同的取用者群組有不同的檢視,這表示狀態、位置和位移可能會有所不同。 取用者群組讓多個取用應用程式能夠有自己的事件資料流程檢視,並單獨以自己的步調和自己的位移來讀取資料流程。 如需取用者群組的詳細資訊,請參閱Azure 事件中樞中的功能和術語

    取用者群組有一或多個與其相關聯的取用者應用程式,而取用者應用程式可以使用一或多個取用者群組。 在串流處理解決方案中,每個取用者應用程式都等於取用者群組。 函式應用程式是取用者應用程式的主要範例。 下圖提供從事件中樞讀取的兩個函式應用程式範例,其中每個應用程式都有自己的專用取用者群組:

    每個函式應用程式的專用取用者群組

    請勿在函式應用程式與其他取用者應用程式之間共用取用者群組。 每個函式應用程式都應該是具有自己指派取用者群組的不同應用程式,以確保每個取用者的位移完整性,並簡化事件串流架構中的相依性。 這類設定,以及提供每個事件中樞觸發函式自己的函式應用程式和儲存體帳戶,有助於設定最佳效能和調整的基礎。

函式主控方案

每個函式應用程式都會根據三個主控方案的其中一個來裝載。 如需這些方案的相關資訊,請參閱Azure Functions裝載選項。 記下這三個選項調整的方式。

取用方案是預設值。 取用計畫中的函式應用程式會獨立調整,而且在避免長時間執行的工作時最有效。

進階和專用方案通常用來裝載多個需要大量 CPU 和記憶體的函式應用程式和函式。 使用專用方案時,您會以一般App Service方案費率,在Azure App 服務方案中執行函式。 請務必注意,這些方案中的所有函式應用程式都會共用配置給方案的資源。 如果函式有不同的負載設定檔或獨特的需求,最好將它們裝載在不同的方案中,特別是在串流處理應用程式中。

事件中樞調整

當您部署事件中樞命名空間時,您需要正確設定幾個重要的設定,以確保尖峰效能和調整。 本節著重于事件中樞的標準層,以及當您也使用 Functions 時影響調整的該層的獨特功能。 如需事件中樞層的詳細資訊,請參閱 基本與標準與進階與專用層

事件中樞命名空間會對應至 Kafka 叢集。 如需事件中樞和 Kafka 彼此關聯的詳細資訊,請參閱Apache Kafka 的Azure 事件中樞

瞭解 RU) (輸送量單位

在事件中樞標準層中,輸送量會分類為輸入的資料量,而且會依時間單位從命名空間讀取。 RU 是預先購買的輸送量容量單位。

RU 會每小時計費。

命名空間中的所有事件中樞都會共用 TU。 若要正確計算容量需求,您必須考慮發行者和取用者的所有應用程式和服務。 函式會影響發行至事件中樞並從中讀取的位元組和事件數目。

判斷 RU 數目的強調在於輸入點。 不過,取用者應用程式的匯總,包括處理這些事件的速率,也必須包含在計算中。

如需事件中樞輸送量單位的詳細資訊,請參閱 輸送量單位

使用自動擴充相應增加

您可以在事件中樞命名空間上啟用自動擴充,以容納負載超過已設定的 TU 數目的情況。 使用自動擴充可防止應用程式的節流,並協助確保處理,包括事件擷取,不會中斷。 由於 TU 設定會影響成本,因此使用自動擴充有助於解決過度布建的疑慮。

自動擴充是事件中樞的功能,通常與自動調整混淆,特別是在無伺服器解決方案的內容中。 不過,自動擴充與自動調整不同,在不再需要新增容量時不會相應減少。

如果應用程式需要超過允許的最大 RU 數目的容量,請考慮使用事件中樞 進階層專用層

資料分割和並行函式

建立事件中樞時,必須指定 分割 區數目。 分割區計數會維持固定狀態,但無法從進階和專用層變更。 當事件中樞觸發函式應用程式時,並行實例數目可能會等於分割區數目。

在 [取用和進階裝載方案] 中,函式應用程式實例會視需要動態相應放大,以符合分割區數目。 專用主控方案會在App Service方案中執行函式,並要求您手動設定實例或設定自動調整配置。 如需詳細資訊,請參閱適用于Azure Functions的專用主控方案

最後,資料分割數目和函式應用程式實例之間的一對一關聯性是串流處理解決方案中最大輸送量的理想目標。 若要達到最佳平行處理原則,請在取用者群組中擁有多個取用者。 對於 Functions,此目標會轉譯為方案中許多函式應用程式的實例。 結果稱為 分割層級平行 處理原則或 平行處理原則的最大程度,如下圖所示:

平行處理原則的最大程度

設定盡可能達到最大輸送量的分割區,並考慮較高的事件量可能很合理。 不過,當您設定許多分割區時,需要考慮幾個重要因素:

  • 更多分割區可能會導致更多輸送量: 因為平行處理原則的程度是 (函式應用程式實例) 取用者數目,所以有的分割區越多,並行輸送量就越高。 當您與其他取用者應用程式共用事件中樞的指定 RU 數目時,這個事實很重要。
  • 更多函式可能需要更多記憶體: 隨著函式應用程式實例的數目增加,因此計畫中的資源記憶體使用量也會增加。 有時候,太多分割區可能會對取用者產生效能。
  • 下游服務有反向壓力的風險:產生更多輸送量時,您會執行壓倒下游服務的風險,或收到來自這些服務的壓力。 考慮周邊資源的結果時,必須考慮取用者展開。 可能的結果包括來自其他服務的節流、網路飽和度,以及其他類型的資源爭用。
  • 分割區可以疏鬆填入: 許多分割區與少量事件的組合可能會導致資料疏鬆分散到分割區。 相反地,較少的分割區可提供更佳的效能和資源使用量

可用性和一致性

未指定分割區索引鍵或識別碼時,事件中樞會將傳入事件路由傳送至下一個可用的分割區。 此做法提供高可用性,並協助增加取用者的輸送量。

當需要一組事件的順序時,事件產生者可以指定特定分割區要用於集合的所有事件。 從資料分割讀取的取用者應用程式會依適當順序接收事件。 此取捨可提供一致性,但會危害可用性。 除非必須保留事件順序,否則請勿使用此方法。

對於 Functions,當事件發佈至特定分割區,而事件中樞觸發的函式會取得相同分割區的租用時,就會達到排序。 目前不支援使用事件中樞輸出系結設定資料分割的功能。 相反地,最佳方法是使用其中一個事件中樞 SDK 來發佈至特定分割區。

如需事件中樞如何支援可用性和一致性的詳細資訊,請參閱 事件中樞的可用性和一致性

事件中樞觸發程序

本節著重于優化事件中樞所觸發函式的設定和考慮。 因素包括批次處理、取樣和相關功能,這些特徵會影響事件中樞觸發程式系結的行為。

觸發函式的批次處理

您可以設定事件中樞觸發的函式,以一次處理一批事件或一個事件。 處理批次事件更有效率,因為它可消除函式調用的一些額外負荷。 除非您只需要處理單一事件,否則您的函式應該設定為在叫用時處理多個事件。

啟用事件中樞觸發程式系結的批次處理會因語言而異:

  • JavaScript、Python 和其他語言會在函式的 function.json 檔案中,將 基數 屬性設定為 許多 時,啟用批次處理。
  • 在 C# 中,當針對EventHubTrigger屬性中的類型指定陣列時,會自動設定基數

如需如何啟用批次處理的詳細資訊,請參閱Azure Functions的Azure 事件中樞觸發程式

觸發程序設定

host.json檔案中的數個組態設定在 Functions 事件中樞觸發程式系結的效能特性中扮演重要角色:

  • maxEventBatchSize: 此設定代表叫用函式時可接收的事件數目上限。 如果收到的事件數目小於此數量,則函式仍會使用可用的事件數目來叫用。 您無法設定最小批次大小。
  • prefetchCount: 預先擷取計數是優化效能時最重要的設定之一。 基礎 AMQP 通道會參考此值,以判斷要擷取和快取用戶端的訊息數目。 預先擷取計數應該大於或等於 maxEventBatchSize 值,而且通常會設定為該數量的倍數。 將此值設定為小於 maxEventBatchSize 設定的數位可能會降低效能。
  • batchCheckpointFrequency: 當您的函式處理批次時,此值會決定建立檢查點的速率。 預設值為 1,這表示每當函式成功處理批次時,就會有檢查點。 系統會針對取用者群組中的每個讀取器,在資料分割層級建立檢查點。 如需此設定如何影響事件重新執行和重試的資訊,請參閱 事件中樞觸發的 Azure 函式:重新執行和重試 (部落格文章)

執行數個效能測試,以判斷要為觸發程式系結設定的值。 建議您以累加方式變更設定,並持續測量以微調這些選項。 預設值是大部分事件處理解決方案的合理起點。

檢查點檢查

檢查點會標示或認可分割區事件序列中的讀取器位置。 函式主機負責處理事件,並符合批次檢查點頻率的設定。 如需檢查點的詳細資訊,請參閱Azure 事件中樞中的功能和術語

下列概念可協助您瞭解檢查點與函式處理事件的方式之間的關聯性:

  • 例外狀況仍計入成功: 如果函式進程在處理事件時不會當機,即使發生例外狀況,函式的完成也會被視為成功。 函式完成時,Functions 主機會評估 batchCheckpointFrequency。 如果是檢查點的時間,不論是否有例外狀況,它都會建立一個檢查點。 例外狀況不會影響檢查點的事實,不應影響您適當地使用例外狀況檢查和處理。
  • 批次頻率很重要: 在大量事件串流解決方案中,將 batchCheckpointFrequency 設定變更為大於 1 的值會很有説明。 增加此值可降低檢查點建立率,因此儲存體 I/O 作業的數目也一樣。
  • 重新執行可能會發生: 每次使用事件中樞觸發程式系結來叫用函式時,都會使用最新的檢查點來判斷繼續處理的位置。 每個取用者的位移都會儲存在每個取用者群組的資料分割層級。 重新執行會在函式的最後一次叫用期間未發生檢查點,並再次叫用函式時發生。 如需重複和重復資料刪除技術的詳細資訊,請參閱 等冪性。

當您考慮錯誤處理和重試的最佳做法時,瞭解檢查點會變得很重要,本文稍後會討論的主題。

遙測取樣

Functions 提供 Application Insights 的內建支援,這是 Azure 監視器的延伸模組,可提供應用程式效能監視功能。 透過這項功能,您可以記錄函式活動、效能、執行時間例外狀況等相關資訊。 如需詳細資訊,請參閱 Application Insights 概觀

這項功能強大的功能提供會影響效能的一些重要組態選擇。 監視和效能的一些值得注意的設定和考慮包括:

  • 啟用遙測取樣: 針對高輸送量案例,您應該評估所需的遙測和資訊數量。 請考慮在 Application Insights 中使用遙測 取樣 功能,以避免使用不必要的遙測和計量降低函式的效能。
  • 設定匯總設定: 檢查並設定匯總和傳送資料至 Application Insights 的頻率。 此組態設定位於 host.json 檔案中,以及許多其他取樣和記錄相關選項。 如需詳細資訊,請參閱 設定匯總工具
  • 停用 AzureWebJobDashboard: 對於以 Functions 執行時間 1.x 版為目標的應用程式,此設定會將連接字串儲存至 Azure SDK 用來保留 WebJobs 儀表板記錄的儲存體帳戶。 如果使用 Application Insights 而不是 WebJobs 儀表板,則應該移除此設定。 如需詳細資訊,請參閱 AzureWebJobsDashboard

啟用 Application Insights 而不進行取樣時,會傳送所有遙測。 傳送所有事件的相關資料可能會對函式的效能造成負面影響,特別是在高輸送量事件串流案例下。

利用取樣並持續評估監視所需的適當遙測量,對於最佳效能至關重要。 遙測應該用於一般平臺健康情況評估,以及偶爾進行疑難排解,而不是擷取核心商務計量。 如需詳細資訊,請參閱設定取樣

輸出繫結

使用Azure Functions的事件中樞輸出系結,簡化從函式發佈至事件資料流程。 使用此系結的優點包括:

  • 資源管理: 系結會為您處理用戶端和連線生命週期,並減少埠耗盡和連線集區管理可能發生的問題。
  • 較少的程式碼: 系結會抽象化基礎 SDK,並減少您需要發佈事件的程式碼數量。 它可協助您撰寫更容易撰寫和維護的程式碼。
  • 配料: 針對數種語言,支援批次處理以有效率地發佈至事件資料流程。 批次處理可以改善效能,並協助簡化傳送事件的程式碼。

強烈建議您檢閱 Functions 支援的語言 清單,以及這些語言的開發人員指南。 每個語言的 [ 系結] 區 段會提供詳細的範例和檔。

發佈事件時的批次處理

如果您的函式只發佈單一事件,設定系結以傳回值是一種常見的方法,如果函式執行一律以傳送事件的語句結束,則很有用。 這項技術應該只用于只傳回一個事件的同步函式。

建議您在將多個事件傳送至資料流程時改善效能。 批次處理可讓系結以最有效率的方式發佈事件。

支援使用輸出系結將多個事件傳送至事件中樞,可在 C#、JAVA、Python 和 JavaScript 中使用。

(C#) 輸出多個事件

當您從 C# 中的函式傳送多個事件時,請使用 ICollectorIAsyncCollector 類型。

  • ICollector < T > 。Add () 方法可用於同步和非同步函式。 它會在呼叫時立即執行新增作業。
  • IAsyncCollector < T > 。AddAsync () 方法會準備要發行至事件資料流程的事件。 如果您撰寫非同步函式,您應該使用 IAsyncCollector 來更妥善地管理已發佈的事件。

如需使用 C# 發佈單一和多個事件的範例,請參閱Azure 事件中樞輸出系結以進行Azure Functions

節流和退壓

節流考慮適用于輸出系結,不僅適用于事件中樞,也適用于 Azure Cosmos DB 等 Azure服務。 請務必熟悉這些服務適用的限制和配額,並據以規劃。

若要處理下游錯誤,您可以將 AddAsyncFlushAsync 包裝在 .NET Functions 的例外狀況處理常式中,以攔截來自 IAsyncCollector 的例外狀況。 另一個選項是直接使用事件中樞 SDK,而不是使用輸出系結。

函式程式碼

本節涵蓋撰寫程式碼來處理事件中樞所觸發函式中事件時必須考慮的重要區域。

非同步程式設計

建議您撰寫函式來 使用非同步程式碼,並避免封鎖呼叫,特別是在涉及 I/O 呼叫時。

以下是撰寫函式以非同步方式處理時應遵循的指導方針:

  • 所有非同步或全部同步: 如果函式設定為以非同步方式執行,則所有 I/O 呼叫都應該是非同步。 在大部分情況下,部分非同步程式碼比完全同步的程式碼更糟。 選擇非同步或同步,並一直保持選擇。
  • 避免封鎖呼叫: 只有在呼叫完成之後,封鎖呼叫才會傳回給呼叫端,與立即傳回的非同步呼叫相反。 C# 中的範例是在非同步作業上呼叫 Task.ResultTask.Wait

深入瞭解封鎖通話

使用非同步作業的封鎖呼叫可能會導致執行緒集區耗盡,並導致函式進程當機。 當機發生的原因是封鎖呼叫需要建立另一個執行緒,以補償目前正在等候的原始呼叫。 因此,需要兩倍的執行緒才能完成作業。

當涉及事件中樞時,避免 透過非同步 方法進行這項同步處理特別重要,因為函式損毀不會更新檢查點。 下次叫用函式時,它最後可能會在此週期中出現,而且似乎停滯或隨著函式執行最終逾時而緩慢移動。

針對此問題進行疑難排解時,通常會從檢閱觸發程式設定和執行可能涉及增加資料分割計數的實驗開始。 調查也可能會導致變更數個批次處理選項,例如批次大小上限或預先擷取計數。 印象是,這是只需要據以微調的輸送量問題或組態設定。 不過,核心問題位於程式碼本身,而且必須加以解決。

參與者

本文由 Microsoft 維護。 它原本是由下列參與者所撰寫。

主體作者:

若要查看非公用LinkedIn設定檔,請登入 LinkedIn。

下一步

繼續之前,請考慮檢閱下列相關文章: