分割的佇列和主題Partitioned queues and topics

Azure 服務匯流排會採用多個訊息代理人來處理訊息,並採用多個訊息存放區來儲存訊息。Azure Service Bus employs multiple message brokers to process messages and multiple messaging stores to store messages. 傳統的佇列或主題由單一訊息代理程式處理並儲存在一個訊息存放區中。A conventional queue or topic is handled by a single message broker and stored in one messaging store. 服務匯流排「分割區」 可讓佇列和主題或「傳訊實體」 分割到多個訊息代理程式及訊息存放區。Service Bus partitions enable queues and topics, or messaging entities, to be partitioned across multiple message brokers and messaging stores. 分割表示分割實體的整體輸送量不會再受到單一訊息代理程式或訊息存放區的效能所限制。Partitioning means that the overall throughput of a partitioned entity is no longer limited by the performance of a single message broker or messaging store. 此外,即使訊息存放區暫時中斷也不會讓分割的佇列或主題無法使用。In addition, a temporary outage of a messaging store does not render a partitioned queue or topic unavailable. 分割的佇列和主題可以包含所有進階的服務匯流排功能,例如支援交易和工作階段。Partitioned queues and topics can contain all advanced Service Bus features, such as support for transactions and sessions.

注意

基本或標準 SKU 中的所有佇列與主題在建立實體時均可使用分割。Partitioning is available at entity creation for all queues and topics in Basic or Standard SKUs. 進階傳訊 SKU 無法使用分割,但先前已存在於進階命名空間中的已分割實體會繼續如預期運作。It is not available for the Premium messaging SKU, but any previously existing partitioned entities in Premium namespaces continue to work as expected.

無法變更任何現有佇列或主題上的分割選項,您只能在建立實體時設定此選項。It is not possible to change the partitioning option on any existing queue or topic; you can only set the option when you create the entity.

運作方式How it works

每個資料分割的佇列或主題包含多個資料分割。Each partitioned queue or topic consists of multiple partitions. 每個分割區是儲存在不同的訊息存放區,並由不同的訊息代理人處理。Each partition is stored in a different messaging store and handled by a different message broker. 當訊息傳送至分割的佇列或主題時,服務匯流排會指派訊息到其中一個分割區。When a message is sent to a partitioned queue or topic, Service Bus assigns the message to one of the partitions. 選取作業由服務匯流排或使用傳送者可指定的分割索引鍵隨機進行。The selection is done randomly by Service Bus or by using a partition key that the sender can specify.

若用戶端想要收到一則訊息從分割的佇列或訂用帳戶的資料分割的主題,服務匯流排會查詢訊息的所有資料分割,則會傳回取自任何訊息存放區給接收者的第一個訊息。When a client wants to receive a message from a partitioned queue, or from a subscription to a partitioned topic, Service Bus queries all partitions for messages, then returns the first message that is obtained from any of the messaging stores to the receiver. 服務匯流排會快取其他訊息,然後在它收到其他接收要求時將其傳回。Service Bus caches the other messages and returns them when it receives additional receive requests. 接收的用戶端並不知道分割。分割佇列或主題的用戶端對向行為 (例如讀取、完成、延遲、無效化、預先擷取) 和一般實體的行為相同。A receiving client is not aware of the partitioning; the client-facing behavior of a partitioned queue or topic (for example, read, complete, defer, deadletter, prefetching) is identical to the behavior of a regular entity.

傳送訊息給分割的佇列或主題,或從該處接收訊息時,不需要額外成本。There is no additional cost when sending a message to, or receiving a message from, a partitioned queue or topic.

啟用分割Enable partitioning

若要搭配 Azure 服務匯流排使用分割的佇列和主題,請使用 Azure SDK 2.2 版或更新版本,或在您的 HTTP 要求中指定 api-version=2013-10 或更新版本。To use partitioned queues and topics with Azure Service Bus, use the Azure SDK version 2.2 or later, or specify api-version=2013-10 or later in your HTTP requests.

標準Standard

在標準傳訊層中,您可以建立 1、2、3、4 或 5 GB 大小的服務匯流排佇列和主題 (預設值為 1 GB)。In the Standard messaging tier, you can create Service Bus queues and topics in 1, 2, 3, 4, or 5-GB sizes (the default is 1 GB). 啟用分割時,服務匯流排會建立實體,每個指定的相同大小的 16 的複本 (16 個資料分割)。With partitioning enabled, Service Bus creates 16 copies (16 partitions) of the entity, each of the same size specified. 因此,如果您建立 5 GB 大小的佇列,每 GB 有 16 個資料分割,則佇列大小上限會變成 (5 * 16) = 80 GB。As such, if you create a queue that's 5 GB in size, with 16 partitions the maximum queue size becomes (5 * 16) = 80 GB. 如果要查看分割佇列或主題的大小上限,您可以在 Azure 入口網站上,在該實體的 [概觀] 刀鋒視窗中檢視其項目。You can see the maximum size of your partitioned queue or topic by looking at its entry on the Azure portal, in the Overview blade for that entity.

進階Premium

在進階層命名空間中,不支援資料分割的實體。In a Premium tier namespace, partitioning entities are not supported. 然而,您仍然可以建立 1、2、3、4、5、10、20、40 或 80 GB 大小的服務匯流排佇列與主題 (預設值為 1 GB)。However, you can still create Service Bus queues and topics in 1, 2, 3, 4, 5, 10, 20, 40, or 80-GB sizes (the default is 1 GB). 如果要查看佇列或主題的大小,您可以至 Azure 入口網站,在該實體的 [概觀] 刀鋒視窗中檢視其項目。You can see the size of your queue or topic by looking at its entry on the Azure portal, in the Overview blade for that entity.

建立分割實體Create a partitioned entity

有多種方式可以建立分割的佇列或主題。There are several ways to create a partitioned queue or topic. 當您從應用程式建立佇列或主題時,您可以分別將 QueueDescription.EnablePartitioningTopicDescription.EnablePartitioning 屬性設為 true 來啟用佇列或主題的分割。When you create the queue or topic from your application, you can enable partitioning for the queue or topic by respectively setting the QueueDescription.EnablePartitioning or TopicDescription.EnablePartitioning property to true. 這些屬性必須在建立佇列或主題時設定,並且僅適用於較舊的 WindowsAzure.ServiceBus 程式庫中。These properties must be set at the time the queue or topic is created, and are available only in the older WindowsAzure.ServiceBus library. 如先前所述,在現有的佇列或主題上無法變更這些屬性。As stated previously, it is not possible to change these properties on an existing queue or topic. 例如:For example:

// Create partitioned topic
NamespaceManager ns = NamespaceManager.CreateFromConnectionString(myConnectionString);
TopicDescription td = new TopicDescription(TopicName);
td.EnablePartitioning = true;
ns.CreateTopic(td);

或者,您可以在 Azure 入口網站中建立分割的佇列或主題。Alternatively, you can create a partitioned queue or topic in the Azure portal. 當您在入口網站建立佇列或主題時,依預設會勾選佇列或主題 [建立] 對話方塊中的 [啟用分割] 選項。When you create a queue or topic in the portal, the Enable partitioning option in the queue or topic Create dialog box is checked by default. 您只能在標準層實體中停用此選項,進階層不支援分割,且核取方塊沒有作用。You can only disable this option in a Standard tier entity; in the Premium tier partitioning is not supported, and the checkbox has no effect.

分割索引鍵的用途Use of partition keys

當訊息加入佇列至分割的佇列或主題時,服務匯流排會檢查分割區索引鍵是否存在。When a message is enqueued into a partitioned queue or topic, Service Bus checks for the presence of a partition key. 如果找到,它會選取該索引鍵為基礎的資料分割。If it finds one, it selects the partition based on that key. 如果找不到資料分割索引鍵,它會選取內部演算法為基礎的資料分割。If it does not find a partition key, it selects the partition based on an internal algorithm.

使用分割區索引鍵Using a partition key

某些情況下,例如工作階段或交易,需要特定的資料分割中儲存的訊息。Some scenarios, such as sessions or transactions, require messages to be stored in a specific partition. 這些案例都需要使用分割區索引鍵。All these scenarios require the use of a partition key. 使用相同的資料分割索引鍵的所有訊息都會都指派給相同的資料分割。All messages that use the same partition key are assigned to the same partition. 如果分割區暫時無法使用時,服務匯流排會傳回錯誤。If the partition is temporarily unavailable, Service Bus returns an error.

根據這個案例,會使用不同的訊息屬性做為分割索引鍵:Depending on the scenario, different message properties are used as a partition key:

SessionId:若訊息已設定 SessionId 屬性,則服務匯流排會使用 SessionID 做為分割區索引鍵。SessionId: If a message has the SessionId property set, then Service Bus uses SessionID as the partition key. 如此一來,所有屬於相同工作階段的訊息都會由相同的訊息代理人處理。This way, all messages that belong to the same session are handled by the same message broker. 工作階段可讓服務匯流排保證訊息的排序以及工作階段狀態的一致性。Sessions enable Service Bus to guarantee message ordering as well as the consistency of session states.

PartitionKey:若訊息已設定 PartitionKey 屬性而非 SessionId 屬性,則服務匯流排會使用 PartitionKey 屬性做為分割區索引鍵。PartitionKey: If a message has the PartitionKey property but not the SessionId property set, then Service Bus uses the PartitionKey property value as the partition key. 如果訊息已設定 SessionIdPartitionKey 屬性,這兩個屬性必須相同。If the message has both the SessionId and the PartitionKey properties set, both properties must be identical. 如果 PartitionKey 屬性設為和 SessionId 屬性不同的值,服務匯流排會傳回無效作業例外狀況。If the PartitionKey property is set to a different value than the SessionId property, Service Bus returns an invalid operation exception. 如果傳送者傳送非工作階段感知的交易訊息,應使用 PartitionKey 屬性。The PartitionKey property should be used if a sender sends non-session aware transactional messages. 分割索引鍵可確保在交易內傳送的所有訊息都由相同的訊息代理人處理。The partition key ensures that all messages that are sent within a transaction are handled by the same messaging broker.

MessageId:如果佇列或主題已將 RequiresDuplicateDetection 屬性設為 true,且未設定 SessionIdPartitionKey 屬性,則 MessageId 屬性值可做為分割區索引鍵。MessageId: If the queue or topic has the RequiresDuplicateDetection property set to true and the SessionId or PartitionKey properties are not set, then the MessageId property value serves as the partition key. (如果傳送應用程式沒有指派訊息識別碼,Microsoft .NET 和 AMQP 程式庫會自動指派)。在此情況下,相同訊息的所有複本會由相同的訊息代理人處理。(The Microsoft .NET and AMQP libraries automatically assign a message ID if the sending application does not.) In this case, all copies of the same message are handled by the same message broker. 此識別碼可讓服務匯流排偵測並排除重複的訊息。This ID enables Service Bus to detect and eliminate duplicate messages. 如果 RequiresDuplicateDetection 屬性未設為 true,服務匯流排不會將 MessageId 屬性視為分割區索引鍵。If the RequiresDuplicateDetection property is not set to true, Service Bus does not consider the MessageId property as a partition key.

不使用分割索引鍵Not using a partition key

在 資料分割索引鍵不存在,服務匯流排會將以循環配置資源方式的資料分割的佇列或主題的所有資料分割的訊息。In the absence of a partition key, Service Bus distributes messages in a round-robin fashion to all the partitions of the partitioned queue or topic. 如果找不到所選的資料分割,服務匯流排會指派訊息給不同的資料分割。If the chosen partition is not available, Service Bus assigns the message to a different partition. 如此一來,儘管訊息存放區暫時無法使用,傳送作業仍會成功。This way, the send operation succeeds despite the temporary unavailability of a messaging store. 不過,您將無法達到分割區索引鍵所提供的保證排序。However, you will not achieve the guaranteed ordering that a partition key provides.

如需可用性 (無分割區索引鍵) 和一致性 (使用分割區索引鍵) 之間權衡取捨的深入討論,請參閱這篇文章For a more in-depth discussion of the tradeoff between availability (no partition key) and consistency (using a partition key), see this article. 此資訊同時適用於已分割的服務匯流排實體。This information applies equally to partitioned Service Bus entities.

若要提供服務匯流排足夠時間訊息佇列到不同的資料分割中, OperationTimeout用戶端所傳送的訊息必須大於 15 秒指定的值。To give Service Bus enough time to enqueue the message into a different partition, the OperationTimeout value specified by the client that sends the message must be greater than 15 seconds. 建議將 OperationTimeout 屬性設為預設值 60 秒。It is recommended that you set the OperationTimeout property to the default value of 60 seconds.

資料分割索引鍵 「 釘選 」 到特定的磁碟分割的訊息。A partition key "pins" a message to a specific partition. 如果包含此資料分割的訊息存放區無法使用時,服務匯流排會傳回錯誤。If the messaging store that holds this partition is unavailable, Service Bus returns an error. 資料分割索引鍵不存在,服務匯流排可以選擇不同的資料分割,並在作業執行成功。In the absence of a partition key, Service Bus can choose a different partition and the operation succeeds. 因此,建議您若非必要請勿提供分割索引鍵。Therefore, it is recommended that you do not supply a partition key unless it is required.

進階主題:搭配交易使用分割的實體Advanced topics: use transactions with partitioned entities

傳送做為交易一部分的訊息必須指定資料分割索引鍵。Messages that are sent as part of a transaction must specify a partition key. 金鑰可以是下列屬性其中之一:SessionIdPartitionKeyMessageId 屬性。The key can be one of the following properties: SessionId, PartitionKey, or MessageId. 傳送做為相同交易一部分的所有訊息必須指定相同的分割索引鍵。All messages that are sent as part of the same transaction must specify the same partition key. 如果您嘗試在交易內傳送沒有分割索引鍵的訊息,服務匯流排會傳回無效作業例外狀況。If you attempt to send a message without a partition key within a transaction, Service Bus returns an invalid operation exception. 如果您嘗試在相同交易內傳送多個具有不同分割索引鍵的訊息,服務匯流排會傳回無效作業例外狀況。If you attempt to send multiple messages within the same transaction that have different partition keys, Service Bus returns an invalid operation exception. 例如:For example:

CommittableTransaction committableTransaction = new CommittableTransaction();
using (TransactionScope ts = new TransactionScope(committableTransaction))
{
    Message msg = new Message("This is a message");
    msg.PartitionKey = "myPartitionKey";
    messageSender.SendAsync(msg); 
    ts.CompleteAsync();
}
committableTransaction.Commit();

如果設定的任何屬性做為資料分割索引鍵,則服務匯流排訊息釘選到特定的分割區。If any of the properties that serve as a partition key are set, Service Bus pins the message to a specific partition. 無論是否使用交易,都會發生這個行為。This behavior occurs whether or not a transaction is used. 建議您若非必要請勿指定分割索引鍵。It is recommended that you do not specify a partition key if it is not necessary.

搭配工作階段使用分割的實體Using sessions with partitioned entities

若要將交易訊息傳送至工作階段感知的主題或佇列,該訊息必須設定 SessionId 屬性。To send a transactional message to a session-aware topic or queue, the message must have the SessionId property set. 如果也指定 PartitionKey 屬性,它必須與 SessionId 屬性相同。If the PartitionKey property is specified as well, it must be identical to the SessionId property. 如果兩者不同,服務匯流排會傳回無效作業例外狀況。If they differ, Service Bus returns an invalid operation exception.

不同於一般 (非分割) 的佇列或主題,無法使用單一交易將多則訊息傳送到不同的工作階段。Unlike regular (non-partitioned) queues or topics, it is not possible to use a single transaction to send multiple messages to different sessions. 如果嘗試這樣做,服務匯流排會傳回無效作業例外狀況。If attempted, Service Bus returns an invalid operation exception. 例如:For example:

CommittableTransaction committableTransaction = new CommittableTransaction();
using (TransactionScope ts = new TransactionScope(committableTransaction))
{
    Message msg = new Message("This is a message");
    msg.SessionId = "mySession";
    messageSender.SendAsync(msg); 
    ts.CompleteAsync();
}
committableTransaction.Commit();

使用分割實體的自動訊息轉送Automatic message forwarding with partitioned entities

服務匯流排支援往返於分割實體或在它們之間自動轉送訊息。Service Bus supports automatic message forwarding from, to, or between partitioned entities. 若要啟用自動訊息轉送,請在來源佇列或訂用帳戶上設定 QueueDescription.ForwardTo 屬性。To enable automatic message forwarding, set the QueueDescription.ForwardTo property on the source queue or subscription. 如果該訊息指定分割索引鍵 (SessionIdPartitionKeyMessageId),該分割索引鍵會用於目的地實體。If the message specifies a partition key (SessionId, PartitionKey, or MessageId), that partition key is used for the destination entity.

考量和指導方針Considerations and guidelines

  • 高度一致性功能︰如果實體使用功能,例如工作階段、 重複偵測或明確控制資料分割索引鍵,然後傳訊作業一定會路由至特定的分割區。High consistency features: If an entity uses features such as sessions, duplicate detection, or explicit control of partitioning key, then the messaging operations are always routed to specific partition. 如果任何資料分割時遇到高流量,或是基礎存放區會處於狀況不良,這些作業會失敗,而且可用性會降低。If any of the partitions experience high traffic or the underlying store is unhealthy, those operations fail and availability is reduced. 整體來說,一致性仍然遠高於非分割實體,只有一部分流量會遭遇問題,而不是所有的流量。Overall, the consistency is still much higher than non-partitioned entities; only a subset of traffic is experiencing issues, as opposed to all the traffic. 如需詳細資訊,請參閱這篇針對可用性和一致性的討論For more information, see this discussion of availability and consistency.
  • 管理︰必須執行作業,例如建立、 更新和刪除之實體的所有資料分割上。Management: Operations such as Create, Update, and Delete must be performed on all the partitions of the entity. 如果任何磁碟分割的狀況不良,它可能會導致這些作業失敗。If any partition is unhealthy, it could result in failures for these operations. Get 作業,例如訊息計數必須彙總資訊來自所有分割區。For the Get operation, information such as message counts must be aggregated from all partitions. 如果任何磁碟分割的狀況不良,則實體可用性狀態會報告為受限制。If any partition is unhealthy, the entity availability status is reported as limited.
  • 少量訊息案例︰對於這類案例,尤其是當使用 HTTP 通訊協定時,您可能必須執行多次接收作業,才能取得所有訊息。Low volume message scenarios: For such scenarios, especially when using the HTTP protocol, you may have to perform multiple receive operations in order to obtain all the messages. 對於接收要求,前端會接收對所有資料分割,並快取所有收到的回應。For receive requests, the front end performs a receive on all the partitions and caches all the responses received. 相同連接上的後續接收要求將受益於此快取,而且接收延遲將會縮短。A subsequent receive request on the same connection would benefit from this caching and receive latencies will be lower. 不過,如果您有多個連線或使用 HTTP,則會針對每個要求建立新的連接。However, if you have multiple connections or use HTTP, that establishes a new connection for each request. 因此,不保證抵達相同的節點。As such, there is no guarantee that it would land on the same node. 如果所有現有的訊息遭鎖定,而且在另一個前端中快取,接收作業會傳回 nullIf all existing messages are locked and cached in another front end, the receive operation returns null. 訊息最後會到期,您可以再次接收它們。Messages eventually expire and you can receive them again. 建議使用 HTTP 持續作用。HTTP keep-alive is recommended.
  • 瀏覽/查看訊息:僅適用於較舊的 WindowsAzure.ServiceBus 程式庫。Browse/Peek messages: Available only in the older WindowsAzure.ServiceBus library. PeekBatch 不一定會傳回 MessageCount 屬性中指定的訊息數目。PeekBatch does not always return the number of messages specified in the MessageCount property. 此行為有兩個常見的原因。There are two common reasons for this behavior. 其中一個原因是訊息集合的彙總大小超過大小上限 256 KB。One reason is that the aggregated size of the collection of messages exceeds the maximum size of 256 KB. 另一個原因是,如果佇列或主題的 EnablePartitioning 屬性設為 true,分割區可能沒有足夠的訊息來完成所要求的訊息數目。Another reason is that if the queue or topic has the EnablePartitioning property set to true, a partition may not have enough messages to complete the requested number of messages. 一般而言,如果應用程式想要接收一定數目的訊息,它應該重複呼叫 PeekBatch,直到取得該數目的訊息,或已沒有更多訊息可查看為止。In general, if an application wants to receive a specific number of messages, it should call PeekBatch repeatedly until it gets that number of messages, or there are no more messages to peek. 如需詳細資訊,包括程式碼範例,請參閱 QueueClient.PeekBatchSubscriptionClient.PeekBatch API 文件。For more information, including code samples, see the QueueClient.PeekBatch or SubscriptionClient.PeekBatch API documentation.

最新加入的功能Latest added features

分割實體限制Partitioned entities limitations

目前服務匯流排會為分割的佇列和主題設定下列限制:Currently Service Bus imposes the following limitations on partitioned queues and topics:

  • 進階傳訊層中不支援分割的佇列和主題。Partitioned queues and topics are not supported in the Premium messaging tier. 在進階層中支援使用 SessionId 的工作階段。Sessions are supported in the premier tier by using SessionId.
  • 分割的佇列及主題不支援在單一交易中傳送屬於不同工作階段的訊息。Partitioned queues and topics do not support sending messages that belong to different sessions in a single transaction.
  • 服務匯流排目前每個命名空間允許最多 100 個分割佇列或主題。Service Bus currently allows up to 100 partitioned queues or topics per namespace. 每個分割佇列或主題的配額計數為每個命名空間 10,000 個實體 (不適用於高階層)。Each partitioned queue or topic counts towards the quota of 10,000 entities per namespace (does not apply to Premium tier).

後續步驟Next steps

閱讀 AMQP 1.0 通訊協定指南中 AMQP 1.0 訊息規格的核心概念。Read about the core concepts of the AMQP 1.0 messaging specification in the AMQP 1.0 protocol guide.