

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 散佈集合模式
<a name="scatter-gather"></a>

## 意圖
<a name="scatter-gather-intent"></a>

散佈收集模式是一種訊息路由模式，涉及將類似或相關的請求廣播給多個收件人，並使用稱為彙總*工具*的元件將其回應彙總回單一訊息。此模式有助於實現平行化、減少處理延遲，並處理非同步通訊。使用同步方法實作散佈收集模式很簡單，但更強大的方法涉及在非同步通訊中將其實作為訊息路由，無論是否使用簡訊服務。

## 動機
<a name="scatter-gather-motivation"></a>

在應用程式處理中，可能需要很長時間才能依序處理的請求可以分割成多個平行處理的請求。您也可以透過 API 呼叫將請求傳送至多個外部系統，以取得回應。當您需要來自多個來源的輸入時，散佈集模式很有用。Scatter-gather 會彙總結果，以協助您做出明智的決定，或選取請求的最佳回應。

散佈集模式包含兩個階段，如其名稱所示：
+ *散佈階段*會處理請求訊息，並平行傳送給多個收件人。在此階段，應用程式會散佈請求至整個網路，並繼續執行，而無需等待立即回應。
+ 在*收集階段*，應用程式會收集收件人的回應，並篩選或將其合併為統一的回應。收集所有回應後，它們可以彙總成單一回應，也可以選擇最佳回應進行進一步處理。

## 適用性
<a name="scatter-gather-applicability"></a>

在下列情況下使用散佈集模式：
+ 您計劃從各種 APIs彙總和合併資料，以建立準確的回應。模式會將來自不同來源的資訊合併為具有凝聚力的整個。例如，預訂系統可以向多個收件人提出請求，從多個外部合作夥伴取得引號。
+ 相同的請求必須同時傳送給多個收件人，才能完成交易。例如，您可以使用此模式平行查詢庫存資料，以檢查產品的可用性。
+ 您想要實作可靠且可擴展的系統，透過將請求分散到多個收件人來實現負載平衡。如果某個收件人失敗或遇到高負載，其他收件人仍然可以處理請求。
+ 您想要在實作涉及多個資料來源的複雜查詢時最佳化效能。您可以將查詢分散至相關資料庫、收集部分結果，並將其合併為完整的答案。
+ 您正在實作一種映射縮減處理，其中資料請求會路由到多個資料處理端點以進行分片和複寫。部分結果會經過篩選並合併，以構成正確的回應。
+ 您想要在金鑰值資料庫中的大量寫入工作負載中，將寫入操作分散到分割區金鑰空間。彙總工具會透過查詢每個碎片中的資料來讀取結果，然後將它們合併為單一回應。

## 問題和考量
<a name="scatter-gather-issues"></a>
+ **容錯**能力：此模式依賴平行工作的多個收件人，因此正常處理失敗至關重要。若要減輕收件人失敗對整體系統的影響，您可以實作備援、複寫和故障偵測等策略。
+ **橫向擴展限制**：隨著處理節點的總數增加，相關聯的網路額外負荷也會增加。每個涉及透過網路進行通訊的請求都可能增加延遲，並對平行化的好處產生負面影響。
+ **回應時間瓶頸**：對於要求在最終處理完成之前處理所有收件人的操作，整體系統的效能會受到最慢收件人的回應時間限制。
+ **部分回應**：當請求分散到多個收件人時，有些收件人可能會逾時。在這些情況下，實作應該向用戶端傳達回應不完整。您也可以使用 UI 前端顯示回應彙總詳細資訊。
+ **資料一致性**：當您跨多個收件人處理資料時，您必須仔細考慮資料同步和衝突解決技術，以確保最終彙總結果準確一致。

## 實作
<a name="scatter-gather-implementation"></a>

### 高層級架構
<a name="scatter-gather-high-level-arch"></a>

散佈集模式使用根控制器將請求分發給將處理請求的收件人。在散佈階段，此模式可以使用兩種機制來傳送訊息給收件人：
+ 依分佈散佈：應用程式具有已知的收件人清單，必須呼叫才能取得結果。收件人可以是具有唯一 函數的不同程序，或已向外擴展以分配處理負載的單一程序。如果任何處理節點逾時或顯示回應延遲，控制器可以將處理重新分配到另一個節點。
+ 依競價散佈：應用程式會使用[發佈訂閱模式](publish-subscribe.md)，將訊息廣播給感興趣的收件人。在這種情況下，收件人可以隨時訂閱訊息或退出訂閱。

#### 依分佈散佈
<a name="scatter-gather-high-distribution"></a>

在依分佈方法的散佈中，根控制器會將傳入的請求分割為獨立任務，並將其指派給可用的收件人 (*散佈*階段）。每個收件人 （程序、容器或 Lambda 函數） 在其運算上獨立並平行運作，並產生回應的一部分。當收件人完成任務時，他們會將回應傳送到彙整工具 (*收集*階段）。彙總工具會結合部分回應，並將最終結果傳回給用戶端。下圖說明此工作流程。

![散佈集合模式的依分佈方法散佈](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/cloud-design-patterns/images/scatter-gather-1.png)


控制器 （資料檔案處理器） 會協調整組調用，並知道要呼叫的所有預訂端點。它可以設定逾時參數，以忽略花費太長的回應。傳送請求後，彙總工具會等待每個端點的回應傳回。若要實作彈性，每個微服務都可以部署多個執行個體以進行負載平衡。彙總工具會取得結果，將其合併為單一回應訊息，並在進一步處理之前移除重複的資料。系統會忽略逾時的回應。控制器也可以充當彙總工具，而不是使用單獨的彙總工具服務。

#### 依競價散佈
<a name="scatter-gather-high-auction"></a>

如果控制器不知道收件人或收件人鬆散耦合，您可以透過競價方法使用散佈。在此方法中，收件人會訂閱主題，而控制器會將請求發佈至主題。收件人會將結果發佈到回應佇列。由於根控制器不知道收件人，因此收集程序會使用彙總工具 （另一個傳訊模式） 來收集回應，並將其分割成單一回應訊息。彙總工具會使用唯一的 ID 來識別一組請求。

例如，在下圖中，透過競價散佈法用於實作航空公司網站的航班預訂服務。該網站允許使用者搜尋和顯示來自航空公司及其合作夥伴航空公司的航班，並且必須即時顯示搜尋的狀態。航班預訂服務包含三種搜尋微服務：直飛航班、停靠航班，以及合作夥伴航空公司。合作夥伴航空公司搜尋會呼叫合作夥伴的 API 端點以取得回應。

![散佈-收集模式的依競價方法散佈](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/cloud-design-patterns/images/scatter-gather-2.png)


1. 航班預訂服務 （控制器） 接受來自用戶端的搜尋條件作為輸入，並處理請求並將其發佈至主題。

1. 控制器使用唯一的 ID 來識別每個請求群組。

1. 用戶端會將唯一的 ID 傳送至步驟 6 的彙總器。

1. 已訂閱預訂主題的預訂搜尋微服務會收到請求。

1. 微服務會處理請求，並將指定搜尋條件的座位可用性傳回給回應佇列。

1. 彙總工具會整理存放在暫時資料庫中的所有回應訊息、依唯一 ID 將航班分組、建立單一統一回應，並將其傳回給用戶端。

### 使用 實作 AWS 服務
<a name="scatter-gather-aws-services"></a>

#### 依分佈散佈
<a name="scatter-gather-services-distribution"></a>

在下列架構中，根控制器是資料檔案處理器 (Amazon ECS)，可將傳入的請求資料分割為個別 Amazon Simple Storage Service (Amazon S3) 儲存貯體，並啟動 AWS Step Functions 工作流程。工作流程會下載資料並啟動平行檔案處理。`Parallel` 狀態會等待所有任務傳回回應。 AWS Lambda 函數會彙總資料並將其儲存回 Amazon S3。

![透過 AWS 架構上的分佈方法實作散佈](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/cloud-design-patterns/images/scatter-gather-3.png)


下圖說明 Step Functions 工作流程與 `Parallel` 狀態。

![依分佈方法實作散佈 AWS 步驟函數工作流程](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/cloud-design-patterns/images/scatter-gather-4.png)


#### 依競價散佈
<a name="scatter-gather-services-auction"></a>

下圖顯示依競價方法散佈的 AWS 架構。根控制器**航班預訂服務**會將航班搜尋請求分散至多個微服務。發佈訂閱頻道是使用 Amazon Simple Notification Service (Amazon SNS) 實作，Amazon Simple Notification Service 是用於通訊的受管傳訊服務。Amazon SNS 支援解耦微服務應用程式或直接與使用者通訊之間的訊息。您可以在 Amazon Elastic Kubernetes Service (Amazon EKS) 或 Amazon Elastic Container Service (Amazon ECS) 上部署收件人微服務，以獲得更好的管理和可擴展性。**航班結果服務**會將結果傳回給用戶端。它可以在 AWS Lambda 或其他容器協同運作服務中實作，例如 Amazon ECS 或 Amazon EKS。

![依競價方法散佈的 AWS 架構](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/cloud-design-patterns/images/scatter-gather-5.png)


1. 航班預訂服務 （控制器） 接受搜尋條件做為用戶端的輸入，並處理請求並將其發佈至 SNS 主題。

1. 控制器會將唯一 ID 發佈至 Amazon Aurora 資料庫，以識別請求。

1. 用戶端會將唯一 ID 傳送至步驟 6 的用戶端。

1. 已訂閱預訂主題的預訂搜尋微服務會收到請求。

1. 微服務會處理請求，並將指定搜尋條件的座位可用性傳回 Amazon Simple Queue Service (Amazon SQS) 中的回應佇列。彙總工具會整理所有回應訊息，並將其存放在暫時資料庫中。

1. 航班結果服務會依唯一 ID 將航班分組，建立單一統一的回應，並將其傳回給用戶端。

如果您想要將另一家航空公司搜尋新增至此架構，您可以新增訂閱 SNS 主題並發佈至 SQS 佇列的微服務。

總而言之，散佈收集模式可讓分散式系統達成高效率的平行處理、減少延遲，並順暢地處理非同步通訊。

#### GitHub 儲存庫
<a name="scatter-gather-repo"></a>

如需此模式範例架構的完整實作，請參閱 GitHub 儲存庫，網址為 https：//[https://github.com/aws-samples/asynchronous-messaging-workshop/tree/master/code/lab-3](https://github.com/aws-samples/asynchronous-messaging-workshop/tree/master/code/lab-3)。

## 研討會
<a name="scatter-gather-workshop"></a>
+ *Decoupled Microservices *研討會中的[散佈集實驗室](https://catalog.us-east-1.prod.workshops.aws/workshops/e8738cf6-6eb0-4d1d-9e98-ae240d229535/en-US/scatter-gather) 

## 部落格參考
<a name="scatter-gather-blog"></a>
+ [微服務的應用程式整合模式](https://aws.amazon.com/blogs/compute/application-integration-patterns-running-distributed-rfqs/)

## 相關內容
<a name="scatter-gather-resources"></a>
+ [發佈訂閱](https://docs.aws.amazon.com/prescriptive-guidance/latest/cloud-design-patterns/publish-subscribe.html)模式