最小化協調

Azure 儲存體
Azure SQL Database
Azure Cosmos DB

將應用程式服務之間的協調降至最低,以達到延展性

大部分的雲端應用程式是由多個應用程式服務所組成,包括 Web 前端、資料庫、商務程式、報告和分析等等。 為了達到延展性和可靠性,每個服務都應該在多個實例上執行。

當兩個實例嘗試執行影響某些共用狀態的並行作業時,會發生什麼事? 在某些情況下,必須跨節點協調,例如保留 ACID 保證。 在此圖表中, Node2 正在等候 Node1 釋放資料庫鎖定:

Database lock diagram

協調會限制水準規模的優點,並造成瓶頸。 在此範例中,當您相應放大應用程式並新增更多實例時,您會看到鎖定競爭增加。 在最壞的情況下,前端實例會花大部分時間等候鎖定。

「正好一次」語意是另一個經常協調的來源。 例如,訂單必須只處理一次。 兩名工人正在接聽新訂單。 Worker1 會挑選處理訂單。 應用程式必須確定 Worker2 不會複製工作,但如果 Worker1 當機,則不會卸載訂單。

Coordination diagram

您可以使用排程器代理程式監督員 模式來協調背景工作,但在此情況下,更好的方法是分割工作。 每個背景工作角色都會獲派特定範圍的訂單(例如,依計費區域)。 如果背景工作角色當機,新的實例會從先前的實例離開的地方挑選,但多個實例沒有競爭。

建議

接受最終一致性。 當資料散發時,需要協調才能強制執行強式一致性保證。 例如,假設作業會更新兩個資料庫。 如果系統可以容納最終一致性,或許使用 補償交易模式在失敗後以邏輯方式復原,而不是將其放入單一交易 範圍,則最好是。

使用網域事件來同步處理狀態。 網域 事件是一個事件 ,會在發生具有定義域內重要性的事件時記錄。 感興趣的服務可以接聽事件,而不是使用全域交易來協調多個服務。 如果使用此方法,系統必須容許最終一致性(請參閱上一個專案)。

請考慮 CQRS 和事件來源等模式。 這兩種模式有助於減少讀取工作負載與寫入工作負載之間的爭用。

  • CQRS 模式 會分隔讀取作業與寫入作業。 在某些實作中,讀取資料會實際與寫入資料分開。

  • 在事件來源模式 ,狀態變更會記錄為僅附加資料存放區的一系列事件。 將事件附加至資料流程是不可部分完成的作業,需要最少的鎖定。

這兩種模式彼此互補。 如果 CQRS 中的唯寫存放區使用事件來源,唯讀存放區可以接聽相同的事件,以建立目前狀態的可讀取快照集,並針對查詢優化。 不過,在採用 CQRS 或事件來源之前,請注意此方法的挑戰。

資料分割資料。 避免將所有資料放入一個跨許多應用程式服務共用的資料架構。 微服務架構會藉由讓每個服務負責自己的資料存放區,來強制執行此原則。 在單一資料庫中,將資料分割成分區可以改善並行,因為寫入某個分區的服務不會影響寫入至不同分區的服務。

設計等冪作業。 可能的話,設計作業為等冪。 如此一來,就可以使用至少一次語意來處理它們。 例如,您可以將工作專案放在佇列中。 如果背景工作角色在作業中間當機,另一個背景工作角色只會挑選工作專案。 如果背景工作角色需要更新資料,併發出其他訊息做為其邏輯的一部分, 則應該使用等冪訊息處理模式

盡可能使用開放式平行存取。 悲觀並行控制會使用資料庫鎖定來防止衝突。 這可能會導致效能不佳並降低可用性。 透過開放式並行控制,每個交易都會修改資料的複本或快照集。 認可交易時,資料庫引擎會驗證交易,並拒絕任何會影響資料庫一致性的交易。

Azure SQL 資料庫和 SQL Server 支援透過 快照集隔離 的開放式平行存取。 某些 Azure 儲存體服務透過使用 Etag 支援開放式平行存取,包括 Azure Cosmos DB Azure 儲存體

請考慮 MapReduce 或其他平行分散式演算法。 根據要執行的工作資料和類型,您可以將工作分割成可由多個節點平行執行的獨立工作。 請參閱 大型計算架構樣式

使用領導者選舉進行協調。 如果您需要協調作業,請確定協調器不會成為應用程式中的單一失敗點。 使用領導者選舉模式 時,一個實例隨時都是領導者,並擔任協調器。 如果領導者失敗,則會將新的實例選取為領導者。