分割的佇列和主題

Azure 服務匯流排會採用多個訊息代理人來處理訊息,並採用多個訊息存放區來儲存訊息。 傳統的佇列或主題由單一訊息代理程式處理並儲存在一個訊息存放區中。 服務匯流排「分割區」可讓佇列和主題或「傳訊實體」分割到多個訊息代理程式及訊息存放區。 分割表示分割實體的整體輸送量不會再受到單一訊息代理程式或訊息存放區的效能所限制。 此外,即使訊息存放區暫時中斷也不會讓分割的佇列或主題無法使用。 分割的佇列和主題可以包含所有進階的服務匯流排功能,例如支援交易和工作階段。

注意

在分割方面,基本/標準和進階 SKU 之間有一些差異。

  • 基本或標準 SKU 中的所有佇列與主題在建立實體時均可使用分割。 命名空間可以同時具有分割和非分割實體。
  • 為進階傳訊 SKU 建立命名空間時可使用分割,而且該命名空間中的所有佇列和主題都會進行分割。 進階命名空間中任何先前遷移的分割實體都會繼續如預期般運作。
  • 在基本或標準 SKU 中啟用分割時,我們一律會建立 16 個資料分割區。
  • 在進階 SKU 中啟用分割時,會在命名空間建立期間指定分割區數目。

無法變更任何現有命名空間、佇列或主題上的分割選項,您只能在建立實體時設定此選項。

運作方式

每個分割的佇列或主題都包含多個分割。 每個分割儲存在不同的訊息存放區中,並由不同的訊息代理人處理。 當訊息傳送至分割的佇列或主題時,服務匯流排會指派訊息到其中一個分割。 選取作業由服務匯流排或使用傳送者可指定的分割索引鍵隨機進行。

當用戶端想要從分割的佇列或從分割主題的訂用帳戶接收訊息時,服務匯流排會查詢所有分割的訊息,然後將取自任何訊息存放區的第一個訊息傳回給接收者。 服務匯流排會快取其他訊息,然後在其收到更多接收要求時將快取傳回。 接收的用戶端並不知道分割。分割佇列或主題的用戶端對向行為 (例如讀取、完成、延遲、無效化、預先擷取) 和一般實體的行為相同。

非分割實體上的窺視作業一律會傳回最舊的訊息,但不會傳回分割實體上的作業。 相反地,其會傳回訊息代理第一個回應的分割區中最舊的訊息。 不保證傳回的訊息是所有分割區中最舊的訊息。

傳送訊息給分割的佇列或主題,或從該處接收訊息時,不需要額外成本。

注意

瞄核作業會根據訊息的序號,從分割區傳回最舊的訊息。 對於分割的實體,發行的序號與分割區相關。 如需詳細資訊,請參閱訊息排序和時間戳記

分割索引鍵的用途

當訊息加入佇列至分割的佇列或主題時,服務匯流排會檢查分割區索引鍵是否存在。 如果找到,其會根據該索引鍵選取分割區。 如果找不到分割索引鍵,其會根據內部演算法選取分割區。

使用分割區索引鍵

某些案例,例如工作階段或交易,需要儲存在特定分割區的訊息。 這些案例都需要使用分割區索引鍵。 使用相同分割索引鍵的所有訊息都會指派給相同的分割區。 若分割區暫時無法使用,服務匯流排會傳回錯誤。

根據這個案例,會使用不同的訊息屬性做為分割索引鍵:

SessionId:若訊息已設定工作階段識別碼屬性,則服務匯流排會使用該工作階段識別碼屬性做為分割索引鍵。 如此一來,所有屬於相同工作階段的訊息都會由相同的訊息代理人處理。 工作階段可讓服務匯流排保證訊息的排序以及工作階段狀態的一致性。

PartitionKey:若訊息已設定分割索引鍵屬性而非分割索引鍵屬性,則服務匯流排會使用該分割索引鍵屬性做為分割索引鍵。 如果訊息已設定工作階段識別碼和分割索引鍵屬性,這兩個屬性必須相同。 如果分割索引鍵屬性設為和工作階段識別碼屬性不同的值,服務匯流排會傳回無效作業例外狀況。 如果傳送者傳送非ession 感知交易訊息,則應該使用分割區索引鍵屬性。 分割索引鍵可確保在交易內傳送的所有訊息都由相同的訊息代理人處理。

MessageId:如果使用重複偵測功能建立佇列或主題,而且未設定工作階段識別碼或分割索引鍵屬性,則訊息識別碼屬性值會作為分割索引鍵。 (如果傳送的應用程式並未指派訊息識別碼,Microsoft 用戶端程式庫會自動指派。)在此情況下,相同訊息的所有複本會由相同的訊息代理人處理。 此識別碼可讓服務匯流排偵測並排除重複的訊息。 如果未啟用重複偵測功能,服務匯流排不會將訊息識別碼屬性視為分割索引鍵。

不使用分割索引鍵

沒有分割索引鍵時,服務匯流排會以循環配置的方式將訊息分配到分割區佇列或主題的所有分割區。 如果找不到所選的分割區,服務匯流排會將訊息指派至不同的分割區。 如此一來,儘管訊息存放區暫時無法使用,傳送作業仍會成功。 不過,您將無法達到分割索引鍵所提供的保證排序。

如需可用性 (無分割索引鍵) 和一致性 (使用分割索引鍵) 之間權衡取捨的深入討論,請參閱事件中樞的可用性和一致性。 除了未對使用者公開資料分割識別碼之外,這項資訊同樣適用於分割的服務匯流排實體。

若要讓服務匯流排有足夠的時間將訊息加入佇列的不同分割區中,由傳送訊息的用戶端所指定的逾時值必須大於 15 秒。 建議使用預設值 60 秒。

分割索引鍵會將訊息「釘選」到指定的分割區。 如果保留此分割區的訊息存放區無法使用,服務匯流排會傳回錯誤。 沒有分割索引鍵時,服務匯流排可以選擇不同的分割區,而作業就會成功。 因此,建議您若非必要,請勿提供分割索引鍵。

進階主題

透過分割實體使用交易

傳送做為交易一部分的訊息必須指定資料分割索引鍵。 索引鍵可以是下列屬性的其中一個:工作階段識別碼、分割索引鍵或訊息識別碼。 傳送做為相同交易一部分的所有訊息必須指定相同的分割索引鍵。 如果您嘗試在交易內傳送沒有分割索引鍵的訊息,服務匯流排會傳回無效作業例外狀況。 如果您嘗試在相同交易內傳送多個具有不同分割索引鍵的訊息,服務匯流排會傳回無效作業例外狀況。 例如:

CommittableTransaction committableTransaction = new CommittableTransaction();
using (TransactionScope ts = new TransactionScope(committableTransaction))
{
    ServiceBusMessage msg = new ServiceBusMessage("This is a message");
    msg.PartitionKey = "myPartitionKey";
    await sender.SendMessageAsync(msg); 
    ts.Complete();
}
committableTransaction.Commit();

如果設定任何做為分割索引鍵的屬性,服務匯流排會將訊息釘選到特定分割區。 無論是否使用交易,都會發生這個行為。 建議您若非必要請勿指定分割索引鍵。

搭配分割的實體使用工作階段中的交易

若要將交易訊息傳送至工作階段感知的主題或佇列,該訊息必須設定工作階段識別碼屬性。 如果也指定分割索引鍵屬性,它必須與工作階段識別碼屬性相同。 如果兩者不同,服務匯流排會傳回無效作業例外狀況。

不同於一般(非分割)佇列或主題,您無法使用單一交易將多個訊息傳送至不同的會話。 如果嘗試這樣做,服務匯流排會傳回無效作業例外狀況。 例如:

CommittableTransaction committableTransaction = new CommittableTransaction();
using (TransactionScope ts = new TransactionScope(committableTransaction))
{
    ServiceBusMessage msg = new ServiceBusMessage("This is a message");
    msg.SessionId = "mySession";
    await sender.SendMessageAsync(msg); 
    ts.Complete();
}
committableTransaction.Commit();

使用分割實體的自動訊息轉送

服務匯流排支援往返於分割實體或在它們之間自動轉送訊息。 您可以在建立或更新佇列和訂用帳戶時啟用此功能。 如需詳細資訊,請參閱啟用訊息轉接。 如果訊息指定分割索引鍵 (工作階段識別碼、分割索引鍵或訊息識別碼),該分割索引鍵會用於目的地實體。

考量和指導方針

  • 高度一致性功能︰如果實體使用工作階段、重複偵測或明確控制資料分割索引鍵等功能,則傳訊作業一定會路由至特定的分割。 如果任何分割遇到過高的流量,或基礎存放區的狀況不良,這些作業將會失敗,而且可用性會降低。 整體而言,一致性仍遠高於非分割實體:只有一部分的流量遇到問題,而不是所有流量。 如需詳細資訊,請參閱這篇針對可用性和一致性的討論
  • 管理︰必須在實體的所有分割上執行如建立、更新及刪除等作業。 如果任何分割的狀況不良,可能會造成這些作業失敗。 以「Get」作業來說,必須彙總來自所有分割的資訊,例如訊息計數。 如果任何分割的狀況不良,則實體可用性狀態會報告為受限制。
  • 低磁碟區訊息案例:針對這類案例,特別是使用 HTTP 通訊協定時,您可能必須執行多個接收作業,才能取得所有訊息。 對於接收要求,前端會在所有分割上執行接收,並快取所有收到的回應。 相同連線上的後續接收要求會受益於此快取和接收延遲較低。 不過,如果您有多個連線或使用 HTTP,則會針對每個要求建立新的連接。 因此,不保證抵達相同的節點。 如果所有現有的訊息遭鎖定,而且在另一個前端中快取,接收作業會傳回 null。 訊息最後會到期,您可以再次接收它們。 建議使用 HTTP 持續作用。 在低磁碟區案例中使用分割時,接收作業可能需要比預期更長的時間。 因此,建議您不要在這些案例中使用資料分割。 刪除任何現有的分割實體,並停用資料分割來重新建立分割實體,以改善效能。
  • 瀏覽/瞄核訊息:瞄核作業不一定會傳回所要求的訊息數目。 此行為有兩個常見的原因。 其中一個原因是訊息集合的彙總大小超過大小上限。 另一個原因是,在分割佇列或主題中,分割區可能沒有足夠的訊息以傳回要求的訊息數目。 一般而言,如果應用程式想要瞄核/瀏覽一定數目的訊息,其應該重複呼叫瞄核作業,直到取得該數目的訊息,或已沒有更多訊息可查看為止。 如需詳細資訊,包括程式碼範例,請參閱訊息瀏覽

分割實體限制

目前服務匯流排會為分割的佇列和主題設定下列限制:

  • 針對分割的進階命名空間,訊息大小在個別傳送訊息時限製為1 MB,而批次大小限制為1 MB時,訊息會以批次方式傳送訊息。
  • 分割的佇列及主題不支援在單一交易中傳送屬於不同工作階段的訊息。
  • 對於基本和標準 SKU,服務匯流排目前每個命名空間允許最多 100 個分割佇列或主題。 每個分割佇列或主題的配額計數為每個命名空間 10,000 個實體。

下一步

您可以使用 Azure 入口網站、PowerShell、CLI、Resource Manager 範本、.NET、Java、Python 和 JavaScript 來啟用資料分割。 如需詳細資訊,請參閱啟用資料分割 (基本/標準)

請參閱AMQP 1.0通訊協定指南中的進階消息佇列通訊協定 (AMQP) 1.0 傳訊規格的核心概念。