Azure 上任務關鍵性工作負載的數據平臺
在任務關鍵架構中,任何狀態都必須盡可能儲存在計算外部。 技術的選擇是以下列關鍵架構特性為基礎:
特性 | 考量 |
---|---|
效能 | 需要多少計算? |
延遲 | 使用者與數據存放區之間的距離對延遲有何影響? 延遲取捨所需的一致性層級為何? |
回應能力 | 數據存放區是否一律可供使用? |
延展性 | 分割配置為何? |
持久性 | 數據預期會持續多久嗎? 什麼是保留原則? |
復原 | 如果失敗,數據存放區是否能夠自動故障轉移? 有哪些措施可減少故障轉移時間? |
安全性 | 資料是否會加密? 是否可以透過公用網路連線數據存放區? |
在此架構中,有兩個資料存放區:
Database
與工作負載相關的存放區。 建議將所有狀態全域儲存於與區域戳記分隔的資料庫中。 透過跨區域部署資料庫來建立備援。 對於關鍵任務工作負載而言,跨區域同步資料應該是首要考量。 此外,如果發生故障,對資料庫的寫入要求應該仍然可以運作。
強烈建議使用中-主動設定中的數據復寫。 該應用程式應能立即與另一個區域連線。 所有執行個體應能處理讀取和寫入要求。
訊息代理程式
區域戳記中唯一具狀態服務是訊息代理程式,它會儲存短期的要求。 代理程式可滿足緩衝和可靠訊息傳輸的需求。 處理過的要求會永續存在全域資料庫中。
如需其他數據考慮,請參閱 架構完善的架構中的 Misson 關鍵性指引:數據平台考慮。
Database
此架構使用適用於 NoSQL 的 Azure Cosmos DB。 之所以選擇此選項,是因為其提供此設計所需的最多功能:
多區域寫入
啟用多重區域寫入,且複本會部署到部署戳記的每個區域。 每個戳記都可以在本機寫入,而 Azure Cosmos DB 會處理戳記之間的數據復寫和同步處理。 這項功能可大幅降低應用程式的地理位置分散用戶延遲。 Azure Mission-Critical 參考實作會使用多宿主技術來提供最大的復原能力和可用性。
區域備援也會在每個復寫區域內啟用。
如需多區域寫入的詳細資訊,請參閱 在使用 Azure Cosmos DB 的應用程式中設定多區域寫入。
衝突管理
由於能夠跨多個區域執行寫入,因此必須採用衝突管理模型,因為同時寫入可能會造成記錄衝突。 最後寫入器 Wins 是預設模型,並用於任務關鍵性設計。 最後一個寫入器,如記錄的相關聯時間戳所定義,會贏得衝突。 適用於 NoSQL 的 Azure Cosmos DB 也允許定義自定義屬性。
查詢優化
具有大量分割區的大量讀取容器的一般查詢效率建議,是使用識別的itemID來新增相等篩選。 如需查詢優化建議的深入檢閱,請參閱 針對使用 Azure Cosmos DB 時的查詢問題進行疑難解答。
備份功能
建議您使用 Azure Cosmos DB 的原生備份功能進行資料保護。 Azure Cosmos DB 備份功能 支援在線備份和隨選數據還原。
注意
大部分的工作負載並非純粹是OLTP。 實時報告的需求不斷增加,例如針對操作系統執行報表。 這也稱為 HTAP(混合式交易和分析處理)。 Azure Cosmos DB 透過 適用於 Azure Cosmos DB 的 Azure Synapse Link 支援這項功能。
工作負載的數據模型
數據模型應該設計成不需要傳統關係資料庫所提供的功能。 例如,外鍵、嚴格的數據列/數據行架構、檢視和其他。
工作負載具有這些數據 存取特性:
- 讀取模式:
- 點讀取 - 擷取單一記錄。 項目標識碼和分割區索引鍵會直接用於優化上限(每個要求 1 RU)。
- 清單讀取 - 取得要顯示在清單中的目錄專案。
FeedIterator
使用結果數目的限制。
- 寫入模式:
- 小型寫入 - 要求通常會在交易中插入單一或少量記錄。
- 設計用來處理來自終端使用者的高流量,能夠調整以數百萬用戶的順序處理流量需求。
- 小型承載或數據集大小 - 通常是以 KB 的順序排列。
- 回應時間低(以毫秒為單位)。
- 低延遲(以毫秒為單位)。
組態
Azure Cosmos DB 設定如下:
一致性層級 會設定為預設 的會話一致性 ,因為它是單一區域和全域分散式應用程式最廣泛使用的層級。 不需要較弱的一致性與較高的輸送量,因為寫入處理的異步本質,而且不需要低延遲的資料庫寫入。
注意
會話一致性層級會針對此特定應用程式的延遲、可用性和一致性保證提供合理的取捨。 請務必了解 強 式一致性層級不適用於多宿主寫入資料庫。
分割區索引鍵 會針對所有集合設定為
/id
。 此決策是以使用模式為基礎,主要是 「以 GUID 撰寫新檔作為標識碼」 和 「依標識符讀取各種檔」。 提供應用程式程式代碼會維護其標識碼唯一性,新的數據會平均分散到 Azure Cosmos DB 的分割區,以啟用無限規模。索引編製原則 是在集合上設定,以優化查詢。 為了優化 RU 成本和效能,會使用自定義索引編製原則。 此原則只會為查詢述詞中使用的屬性編製索引。 例如,應用程式不會使用批註文字欄位作為查詢中的篩選。 它已從自定義索引編製原則中排除。
以下是實作的範例,顯示使用 Terraform 編製索引原則設定:
indexing_policy {
excluded_path {
path = "/description/?"
}
excluded_path {
path = "/comments/text/?"
}
included_path {
path = "/*"
}
}
如需此架構中從應用程式連線到 Azure Cosmos DB 的相關信息,請參閱 任務關鍵性工作負載的應用程式平台考慮
訊息服務
任務關鍵系統通常會利用傳訊服務來處理訊息或事件。 這些服務會促進鬆散結合,並作為緩衝器,將系統與非預期的需求尖峰隔離。
- 處理高價值訊息時,建議針對訊息型工作負載使用 Azure 服務匯流排。
- 針對處理大量事件或遙測的事件型系統,建議使用 Azure 事件中樞。
以下是任務關鍵架構中 Azure 服務匯流排 進階和 Azure 事件中樞 的設計考慮和建議。
處理負載
傳訊系統必須能夠處理所需的輸送量(以 MB/秒為單位)。 請考慮下列事項:
- 系統的非功能性需求(NFR)應該指定平均訊息大小,而且每個戳記都必須支援每個戳記的訊息尖峰數目。 此資訊可用來計算每個戳記所需的尖峰 MB/秒。
- 計算每個戳記所需的尖峰 MB/秒時,必須考慮故障轉移的影響。
- 針對 Azure 服務匯流排,NFR 應該指定任何進階 服務匯流排 功能,例如會話和取消刪除訊息。 這些功能會影響 服務匯流排的輸送量。
- 具有所需功能的 服務匯流排 輸送量,應透過每個傳訊單位 (MU) 的 MB/秒測試來計算。 如需本主題的詳細資訊,請參閱 服務匯流排 進階和標準傳訊層。
- Azure 事件中樞 的輸送量應該透過標準層或進階層處理單位 (PU) 的每個輸送量單位 (TU) 測試為 MB/秒來計算。 如需本主題的詳細資訊,請參閱 使用事件中樞調整。
- 上述計算可用來驗證傳訊服務可以處理每個戳記所需的負載,以及符合該負載所需的縮放單位數目。
- 作業區段將討論自動調整。
每個訊息都必須處理
Azure 服務匯流排 進階層是高價值訊息的建議解決方案,必須保證處理。 以下是使用 Azure 服務匯流排 Premium 時此需求的詳細數據:
為了確保訊息已正確傳送給訊息代理程式並接受,訊息產生者應該使用其中一個支援的 服務匯流排 API 用戶端。 如果訊息保存在佇列/主題上,則支援的 API 只會從傳送作業成功傳回。
若要確保總線上的訊息已處理,您應該使用 PeekLock 接收模式。 此模式至少會啟用一次處理。 下列概述程式:
- 訊息取用者會收到要處理的訊息。
- 取用者會在指定的時間期間內,為訊息提供獨佔鎖定。
- 如果取用者成功處理訊息,它會將通知傳回訊息代理程式,並將訊息從佇列中移除。
- 如果訊息代理程式未在分配的時段內收到通知,或處理程式明確放棄訊息,則會釋放獨佔鎖定。 訊息接著可供其他取用者處理訊息。
- 如果訊息未成功處理可設定的次數,或處理程式會將訊息轉送至 寄不出的信件佇列。
- 為了確保傳送至寄不出的信件佇列的訊息會受到處理,應監視寄不出的信件佇列,並設定警示。
- 系統應該有工具讓操作員能夠 檢查、更正和重新提交訊息。
因為訊息可能會處理一次以上,因此應該將訊息處理程式設為等冪。
等冪訊息處理
在 RFC 7231 中,超文字傳輸通訊協定指出「A ...如果與該方法相同之多個相同要求的伺服器上的預期效果與單一這類要求的效果相同,則方法會 被視為等冪 。
建立訊息處理等冪性的一個常見技術,就是檢查已處理訊息的持續性存放區,例如資料庫。 如果已處理,您就不會執行邏輯來再次處理它。
- 在某些情況下,訊息的處理包括資料庫作業,特別是插入具有資料庫產生標識元的新記錄。 新的訊息可以發出給訊息代理程式,其中包含這些標識符。 因為沒有包含資料庫和訊息代理程式的分散式交易,因此如果執行程式碼的程式發生失敗,可能會發生許多複雜狀況。 請參閱下列範例情況:
- 發出訊息的程式代碼可能會在認可資料庫交易之前執行,也就是有多少開發人員使用 工作單位模式運作。 如果呼叫訊息代理程式並要求認可資料庫交易,則這些訊息可能會 逸出。 當交易回復時,這些資料庫產生的標識碼也會復原,讓其他可能同時執行的程式碼可以使用這些標識碼。 這可能會導致逸出訊息的收件者處理錯誤的資料庫專案,這會損害系統的整體一致性和正確性。
- 如果開發人員將發出訊息 的程式代碼放在資料庫交易完成之後 ,程式仍然可以在這些作業之間失敗(交易認可 - 已傳送的訊息)。 發生這種情況時,訊息會再次經過處理,但這次等冪防護子句會看到它已經處理過(根據儲存在資料庫中的數據)。 子句會略過發出程式碼的訊息,並相信上次已順利完成一切。 下游系統預期會收到已完成程式的通知,但不會收到任何訊息。 這種情況再次導致整體狀態不一致。
- 上述問題的解決方案牽涉到使用 交易式寄件箱模式,其中傳出訊息會 儲存在與商務數據相同的交易存放區中。 然後,當成功處理初始訊息時,訊息會傳送至訊息代理程式。
- 由於許多開發人員不熟悉這些問題或其解決方案,因此為了保證這些技術一致地套用在任務關鍵系統中,我們建議您擁有收件匣的功能,以及與包裝在某種連結庫中的訊息代理程序互動。 所有處理和傳送交易式重要訊息的程式代碼都應該使用該連結庫,而不是直接與訊息代理程序互動。
- 在 .NET 中實作這項功能的連結庫包括 NServiceBus 和 MassTransit。
高可用性和災害復原
訊息代理程式必須可供產生者使用,才能傳送訊息和取用者來接收訊息。 以下是有關這項需求的詳細數據:
- 若要確保具有 服務匯流排 的最高可用性,請使用具有支援區域中可用性區域的進階層。 使用可用性區域時,訊息和元數據會復寫到相同區域中的三個不同數據中心。
- 使用支援的 服務匯流排 或事件中樞 SDK 來自動重試讀取或寫入失敗。
- 請考慮 主動-主動 復寫或 主動-被動複 寫模式,以隔離區域災害。
注意
Azure 服務匯流排 異地災害復原只會跨區域複寫元數據。 此功能不會復寫訊息。
監視
傳訊系統可作為訊息產生者和取用者之間的緩衝區。 在任務關鍵性系統中,您應該監視的重要指標類型,以提供以下所述的寶貴見解:
- 節流 - 節流表示系統沒有處理要求所需的資源。 服務匯流排和事件中樞都支援監視節流要求。 您應該在此指標上發出警示。
- 佇列深度 - 成長的佇列深度 可能表示訊息處理器無法運作,或沒有足夠的處理器來處理目前的負載。 佇列深度可用來通知處理程序的自動調整邏輯。
- 針對 服務匯流排,佇列深度會公開為訊息計數
- 針對事件中樞,取用者必須計算每個分割區的佇列深度,並將計量推送至您的監視軟體。 針對每個讀取,取用者會取得目前事件的序號,以及最後一個加入佇列事件的事件屬性。 取用者可以計算位移。
- 寄不出的信件佇列 - 寄不出的信件佇列 中的訊息代表無法處理的訊息。 這些訊息通常需要手動介入。 警示應該在寄不出的信件佇列上設定。
- 服務匯流排 有寄不出的信件佇列和 DeadLetteredMessages 計量。
- 針對事件中樞,這項功能必須是取用者內建的自定義邏輯。
- CPU/記憶體使用量 - 應監視 CPU 和記憶體,以確保傳訊系統有足夠的資源來處理目前的負載。 服務匯流排 進階和事件中樞進階都會公開 CPU 和記憶體使用量。
- 傳訊單位 (SU) 用於 服務匯流排 中,以隔離命名空間的 CPU 和記憶體等資源。 CPU 和記憶體高於臨界值可能會指出設定的 RU 不足,而低於其他閾值的 CPU 可能表示已設定太多 RU。 這些指標可用來 自動調整 RU。
- 事件中樞進階層會使用處理單位(PUS)來隔離資源,而標準層則使用輸送量單位(TU)。 這些層不需要與 CPU/記憶體互動,才能自動擴充 PU 或 TU。
健康情況檢查
訊息系統的健康情況必須在健康狀態檢查中考慮任務關鍵性應用程式。 請考慮下列因素:
- 傳訊系統可作為訊息產生者和取用者之間的緩衝區。 如果產生者能夠成功將訊息傳送至訊息代理程式,而且取用者能夠成功處理來自訊息代理程式的訊息,則可以將戳記視為狀況良好。
- 健康情況檢查應確保訊息可以傳送至訊息系統。
下一步
部署參考實施,以全面了解此架構中使用的資源及其設定。