Looking at Azure Service Bus to replace some unreliable RabbitMQ servers and the one thing that isn't clear about the pricing is what exactly do they count as a "Brokered connection" for billing purposes?
We have about a dozen machines that are processing messages off over 1,000 queues (and one machine populating the queue), so does 1 application running on 1 machine count as one brokered connection (regardless of how many queues it's listening to)? Or would each machine count as 1,000+ brokered connections (which could add up very quickly)?
So let's say I did something like this:
var queues = queueNames.Select(q =>
{
if (!manager.QueueExists(q))
{
manager.CreateQueue(q);
}
return new QueueClient(ServiceBusConnectionString, q);
}).ToArray();
Add queueNames is an array of, let's say, 10 strings. Is that 10 brokered connections? 1 ? Or something else?
The polling of the queue encounters the cost for a brokered connection when you hold the queue connection open and sit waiting for a message (eg if you kept the queue open for 30 seconds waiting for a message). If you use the default zero timeout (which will just return null when there is no message to receive) it doesn't count as a brokered connection. An example of a non zero timeout would be using something like Receive(TimeSpan) where you wait for the timeout specified.
You could use OnMessageAsync to listen for messages rather than polling, which doesn't look like a brokered connection.
As for how its calculated, looks like this is concurrent connections averaged hourly over the month. There are some good example calculations in the pricing guide.
From this pricing guide
A brokered connection is defined as one of the following:
An AMQP connection from a client to a Service Bus queue or topic/subscription.
An HTTP call to receive a message from a Service Bus topic or queue that has a
receive timeout value greater than zero.
Service Bus charges for the peak number of concurrent brokered connections that exceed the included quantity (1,000 in the Standard tier). Peaks are measured on an hourly basis, prorated by dividing by 744 hours in a month, and added up over the monthly billing period. The included quantity (1,000 brokered connections per month) is applied at the end of the billing period against the sum of the prorated hourly peaks.
You should probably confirm this with the Azure team via support in the billing Portal, they are generally pretty good with requests like these.
Related
Is there any message receiving limit per device on Azure IoTHub?
If any, can I remove or raise the upper limit without registering additional devices?
I tested 2 things to make sure if I can place enough load (ideally, 18000 message/s)on Azure IoT Hub in the future load tests.
① Send a certain amount of mqtt messages from a VM.
② Send a certain amount of mqtt messages from two VMs.
I expected that the traffic of ② would be twice as large as that of ①. But it wasn't. Maximum messages per minute on IoTHub of ② is not so different from that of ①. Both of them are around 3.6k [message/min]. At that time, I registered only one device on IoT Hub. So I added another device and tested ② again to see if the second device could increase the traffic. As a result, it increased the traffic and IoT Hub had bigger messages per minute.
Judging from this result, I thought IoTHub has some kind of limit on receiving message per device. But I am not sure. So if anyone know about the limit, could you tell me what kind of limit it is and how to raise the upper limit without registering additional devices because in production we use only one device.
For your information, I know there is a "unit" to increase the throughput in IoTHub. To increase the load I changed the number of unit from 2 to 20 in both ① and ②. However, it did not make messages/min in IotHub bigger. I'd also like to know why the "unit" did not work as expected.
Thank you for reading, in advance. Any comment would be my help.
Every basic (B1,B2, B3) or standard unit of IoT Hub SKU (S1, S2, S3) has specific daily message quota as per https://azure.microsoft.com/en-us/pricing/details/iot-hub/. A single IoTHub can support 1 million devices and there is no per device cost associated, only the msg/day quota as above.
e.g. S1 SKU has 400,000 msg/day quota and you can add multiple units of S1 to increase capacity. S2 has 6000,000 msg/day and S3 has 300,000,000 msg/day quota per unit and more units can be added.
Before this limit is reached IoTHub will raise alert which can be used to automatically add more units or jump to higher SKU.
Regarding your test, there are specific throttling limits to avoid misuse of the service here -
https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-quotas-throttling
As an example, for 18000 msg/sec you will need 3 units of S3 SKU (each with 6000 msg/sec rate limit). In addition there are other limits like how quickly connections can be attempted, if using Azure IoT SDK's the built-in retry logic helps overcome this otherwise you need to have retry policy. Basically you dont want million device trying to connect at the same time, IoTHub will only accept connections at a certain rate. This is not concurrent connection limit but a rate at which new connnections are accepted.
We include dates in the events sent to our hub. Whenever I connect a new Azure Function to our Event Hub with a new consumer group, it seems to receive all events ever sent to the hub. This is somewhat expected, however I set the Message Retention on the hub to 1 day, so I expected at most to receive one day worth of events for the new consumer, but it seems to receive all events, even months old events, based on the date within the message, and lots more events than we generate over a day.
Based on this page:
https://blogs.msdn.microsoft.com/servicebus/2015/03/09/data-retention-in-event-hubs/
It seems like maybe this retention period is somewhat irrelevant, or misleading. If the "container" hasn't filled up yet, it could contain messages forever. If, for example, the container has a limit of 1000 messages before the event hub looks at it, but it takes a year to generate 1000 messages, does that mean any new consumer could get year-old messages, even with a 1-day "retention period"?
When the container does hit the limit of 1000 messages, are the messages older than 1 day discarded and the messages newer than 1 day ago (within the retention period) retained? Or is the whole container discarded?
From looking at our test and prod environments it seems like this container fits at least 50000 messages (or equivalent size).
Is a checkpoint the only way to limit this initial influx of messages for a new consumer group?
Retention time is the minimum guaranteed period, not the maximum or exact. 1 day retention means you will have all the messages from last day, but maybe some more messages too.
So you can rely on 1 day of retention, but be prepared to see older messages too.
I am trying to read the Azure Service Bus queue tech specs and pricing but it is not clear to me that
1) Is there any size limit for a message?
2) Is it possible that pricing is not depend on the message sizes? It seems, but I can not believe.
(I would like to send approx 10K - 100K data per message. Message queue will be consumed by concurrent identical worker roles running in multiple instances.
Thx in advance
1-)
Service Bus queues support a maximum message size of 256 KB (the
header, which includes the standard and custom application properties,
can have a maximum size of 64 KB). There is no limit on the number of
messages held in a queue but there is a cap on the total size of the
messages held by a queue. This queue size is defined at creation time,
with an upper limit of 5 GB.
http://www.windowsazure.com/en-us/documentation/articles/service-bus-dotnet-how-to-use-queues/
2-)
Queues and Topics
$0.01 for every 10,000 messages
Messages exceeding 64KB in size will result in an additional message being charged for every 64KB in message. Billable messages include any “no message available” replies from Service Bus in response to receive requests made against empty queues/subscriptions.
Relay
$0.10 for every 100 relay hours
$0.01 for every 10,000 messages
Relay hours start when the first listener connects to a given relay address and end when the last listener disconnects from that address, and are rounded up to the next clock hour. As with queues/topics, messages greater than 64KB in size will generate additional billable messages per 64KB of additional content.
http://www.windowsazure.com/en-us/pricing/details/service-bus/
Since Azure Service Bus limits the maximum number of concurrent connections to a Queue or Topic to 100, is there a method that we can use to query our Queues/Topics to determine how many concurrent connections there are?
We are aware that we can capture the throttling events, but would very much prefer an active approach, where we can proactively increase or decrease the number of Queues/Topics when the system is under a heavy load.
The use case here is a process waiting for a reply message, where the reply is coming from a long-running process, and the subscription is using a Correlation Filter to facilitate two-way communication between the Publisher and Subscriber. Thus, we must have a BeginReceive() going in order to await the response, and each such Publisher will be consuming a connection for the duration of their wait time. The system already balances load across multiple Topics, but we need a way to be proactive about how many Topics are created, so that we do not get throttled too often, but at the same time not have an excess of Topics for this purpose.
I don't believe it is currently possile to query the listener counts. I think that the subscriber object also figures into that so in theory, if you have up to 2000 subscribers per topic and if each allows up to 100 connections, that's alot of potential connections. We just need to keep in mind that subscribers are cooperative (each gets a copy of all messages) and receivers on subscriers are competitive (only one gets it).
I've also seen unconfirmed reports of performance delays when you start running > 1,000 subscribers so make sure you test this scenario.
But... given your scenario, I'd deduce that performance time likely isn't the biggest factor (you have long running processes already). So introducing a couple seconds lag into the workflow likely won't be critical. If that's the case, I'd set the timeout for your BeginRecieve to something fairly short (couple seconds) and have a sleep/wait delay between attempts. This gives other listeners an opportnity to get messsages as well. We might also want to consider an approach where we attempt to recieve multiple messages and then assign them out other processes for processing (coorelation in this case?).
Juts some thoughts.
What is the best way to handle 'urgent' messages in a Windows Azure Worker role?
I have a worker role that starts, does an infinite while(true) loop and in this loop:
reads to see if the queue has messages
processes them and deletes them
if there are no more messages in goes to sleep with Thread.Sleep(interval) for smaller intervals (10s) at first and progressively increases the sleep interval up to 2 minutes
if a message appears in the queue it resets the sleep interval to 0s and goes back to step one
The problem is that if the worker is sleeping for 2 minutes and a message appears in the queue I would like to wake up the worker and not wait for the remaining time.
Is there any way to get the worker role's instance and tell it to wake up?
I thought about writing something in the database, but then I have the same problem, even if I have a role that does this, how would I go about waking up the other worker role that is already sleeping?
This is one of the downsides of using Windows Azure Storage Queues. You have to make a choice between cost and latency. If you want to optimize costs you'll implement a backoff policy (like you did) but this means this will have an impact on when your message will be processed (increased latency).
In your case it might be interesting to evaluate Windows Azure Service Bus Queues (read about the differences here). The advantage of using Service Bus Queues is that it supports long-polling, meaning it will keep a connection to the server until a message arrives (or the timeout elapsed).
Here is some example code you would typically write (you will still need to manage exceptions etc...):
QueueClient queueClient = factory.CreateQueueClient("myqueue");
while (true)
{
BrokeredMessage msg = queueClient.Receive(TimeSpan.FromSeconds(45));
if (msg != null)
{
var request = msg.GetBody<CreateOrderMessage>();
// Do something
msg.Complete();
}
}
Here are a few good resources that will get you started:
http://www.cloudcasts.net/devguide/Default.aspx?id=12042
http://windowsazurecat.com/2011/08/how-to-simplify-scale-inter-role-communication-using-windows-azure-service-bus/
http://msdn.microsoft.com/en-us/library/windowsazure/hh697709.aspx
Just sleep for less time. Why are you sleeping for two minutes instead of, say, just one second? Polling a queue once per second from one instance will cost about $0.25 per month in transactions.