Skip to content

Commit aacd4ff

Browse files
authored
Merge pull request #24743 from sethmanheim/cv13
Adding article on prefetch messages
2 parents 0ed3a37 + cc48fb1 commit aacd4ff

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

articles/service-bus-messaging/TOC.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
### [Message browsing](message-browsing.md)
5454
### [Message transfers, locks, and settlement](message-transfers-locks-settlement.md)
5555
### [Message expiration (Time to Live)](message-expiration.md)
56+
### [Prefetch messages](service-bus-prefetch.md)
5657
### [Topic filters and actions](topic-filters.md)
5758
### [Suspend and reactivate messaging entities](entity-suspend.md)
5859
### AMQP
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
title: Azure Service Bus prefetch messages | Microsoft Docs
3+
description: Improve performance by prefetching Azure Service Bus messages.
4+
services: service-bus-messaging
5+
documentationcenter: ''
6+
author: clemensv
7+
manager: timlt
8+
editor: ''
9+
10+
ms.service: service-bus-messaging
11+
ms.workload: na
12+
ms.tgt_pltfrm: na
13+
ms.devlang: na
14+
ms.topic: article
15+
ms.date: 10/04/2017
16+
ms.author: sethm
17+
18+
---
19+
20+
# Prefetch Azure Service Bus messages
21+
22+
When *Prefetch* is enabled in any of the official Service Bus clients, the receiver quietly acquires more messages, up to the [PrefetchCount](/dotnet/api/microsoft.azure.servicebus.queueclient.prefetchcount#Microsoft_Azure_ServiceBus_QueueClient_PrefetchCount) limit, beyond what the application initially asked for.
23+
24+
A single initial [Receive](/dotnet/api/microsoft.servicebus.messaging.queueclient.receive) or [ReceiveAsync](/dotnet/api/microsoft.azure.servicebus.core.messagereceiver.receiveasync) call therefore acquires a message for immediate consumption that is returned as soon as available. The client then acquires further messages in the background, to fill the prefetch buffer.
25+
26+
## Enable prefetch
27+
28+
In .NET, you enable the Prefetch feature by setting the [PrefetchCount](/dotnet/api/microsoft.azure.servicebus.queueclient.prefetchcount#Microsoft_Azure_ServiceBus_QueueClient_PrefetchCount) property of a **MessageReceiver**, **QueueClient**, or **SubscriptionClient** to a number greater than zero. Setting the value to zero turns off prefetch.
29+
30+
You can easily add this setting to the receive-side of the [QueuesGettingStarted](https://github.com/Azure/azure-service-bus/tree/master/samples/DotNet/Microsoft.ServiceBus.Messaging/QueuesGettingStarted) or [ReceiveLoop](https://github.com/Azure/azure-service-bus/tree/master/samples/DotNet/Microsoft.ServiceBus.Messaging/ReceiveLoop) samples' settings to see the effect in those contexts.
31+
32+
While messages are available in the prefetch buffer, any subsequent **Receive**/**ReceiveAsync** calls are immediately fulfilled from the buffer, and the buffer is replenished in the background as space becomes available. If there are no messages available for delivery, the receive operation empties the buffer and then waits or blocks, as expected.
33+
34+
Prefetch also works in the same way with the [OnMessage](/dotnet/api/microsoft.servicebus.messaging.queueclient.onmessage) and [OnMessageAsync](/dotnet/api/microsoft.servicebus.messaging.queueclient.onmessageasync) APIs.
35+
36+
## If it is faster, why is Prefetch not the default option?
37+
38+
Prefetch speeds up the message flow by having a message readily available for local retrieval when and before the application asks for one. This throughput gain is the result of a trade-off decision that the application author must make explicitly:
39+
40+
With the [ReceiveAndDelete](/dotnet/api/microsoft.azure.servicebus.receivemode.receiveanddelete) receive mode, all messages that are acquired into the prefetch buffer are no longer available in the queue, and only reside in the in-memory prefetch buffer until they are received into the application through the **Receive**/**ReceiveAsync** or **OnMessage**/**OnMessageAsync** APIs. If the application terminates before the messages are received into the application, those messages are irrecoverably lost.
41+
42+
In the [PeekLock](/dotnet/api/microsoft.azure.servicebus.receivemode.peeklock) receive mode, messages fetched into the Prefetch buffer are acquired into the buffer in a locked state, and have the timeout clock for the lock ticking. If the prefetch buffer is large, and processing takes so long that message locks expire while residing in the prefetch buffer or even while the application is processing the message, there might be some confusing events for the application to handle.
43+
44+
The application might acquire a message with an expired or imminently expiring lock. If so, the application might process the message, but then find that it cannot complete it due to a lock expiration. The application can check the [LockedUntilUtc](/dotnet/api/microsoft.azure.servicebus.core.messagereceiver.lockeduntilutc#Microsoft_Azure_ServiceBus_Core_MessageReceiver_LockedUntilUtc) property (which is subject to clock skew between the broker and local machine clock). If the message lock has expired, the application must ignore the message; no API call on or with the message should be made. If the message is not expired but expiration is imminent, the lock can be renewed and extended by another default lock period by calling [message.RenewLock()](/dotnet/api/microsoft.azure.servicebus.core.messagereceiver.renewlockasync#Microsoft_Azure_ServiceBus_Core_MessageReceiver_RenewLockAsync_System_String_)
45+
46+
If the lock silently expires in the prefetch buffer, the message is treated as abandoned and is again made available for retrieval from the queue. That might cause it to be fetched into the prefetch buffer; placed at the end. If the prefetch buffer cannot usually be worked through during the message expiration, this causes messages to be repeatedly prefetched but never effectively delivered in a usable (validly locked) state, and are eventually moved to the dead-letter queue once the maximum delivery count is exceeded.
47+
48+
If you need a high degree of reliability for message processing, and processing takes significant work and time, it is recommended that you use the prefetch feature conservatively, or not at all.
49+
50+
If you need high throughout and message processing is commonly cheap, prefetch yields significant throughput benefits.
51+
52+
The maximum prefetch count and the lock duration configured on the queue or subscription need to be balanced such that the lock timeout at least exceeds the cumulative expected message processing time for the maximum size of the prefetch buffer, plus one message. At the same time, the lock timeout ought not to be so long that messages can exceed their maximum [TimeToLive](/dotnet/api/microsoft.azure.servicebus.message.timetolive#Microsoft_Azure_ServiceBus_Message_TimeToLive) when they are accidentally dropped, thus requiring their lock to expire before being redelivered.
53+
54+
## Next steps
55+
56+
To learn more about Service Bus messaging, see the following topics:
57+
58+
* [Service Bus fundamentals](service-bus-fundamentals-hybrid-solutions.md)
59+
* [Service Bus queues, topics, and subscriptions](service-bus-queues-topics-subscriptions.md)
60+
* [Get started with Service Bus queues](service-bus-dotnet-get-started-with-queues.md)
61+
* [How to use Service Bus topics and subscriptions](service-bus-dotnet-how-to-use-topics-subscriptions.md)

0 commit comments

Comments
 (0)