poorbarcode commented on code in PR #19012:
URL: https://github.com/apache/pulsar/pull/19012#discussion_r1058831966


##########
site2/docs/cookbooks-message-dispatch-throttling.md:
##########
@@ -0,0 +1,105 @@
+---
+id: message-dispatch-throttling
+title: Message dispatch throttling
+sidebar_label: "Message dispatch throttling"
+---
+
+## Message Dispatch throttling
+Message dispatch throttling is a mechanism that limits the speed at which 
messages are delivered to the client.
+
+### When should I use message dispatch throttling?
+* Messages are persisted on disk, `Storage` is the component for this part of 
the work. If a large number of read
+  requests fail to match the cache, the Storage becomes too busy and cannot 
work properly. Use message dispatch
+  throttling makes Pulsar work steadily by keeping Storage's read request load 
stable.
+* An instance of 'Broker' serves multiple topics at the same time, and if a 
topic is too busy, it will occupy
+  almost all of the IO resources, other topics will not work well. Use message 
dispatch throttling can balance
+  the allocation of resources to agents across topics.
+* There have large backlog of messages to consume, clients may receive a large 
amount of data in a short period of time,
+  thus monopolizing the client computer resources. Message dispatch throttling 
can also be used to balance the resource
+  allocation of the client computer.
+
+### Concepts of message dispatch throttling
+- `ratePeriodInSecond` Usually the rate limiter is defined as how many times 
per second, how many times per minute, and
+   so on. In each of these definitions, there is the concept of a time period, 
such as one second, one minute, and the
+   counter is reset at the end of the time period. In Pulsar, the user can 
customize this time period, it is
+   `ratePeriodInSecond`, default is 1s. For example: if we want limit dispatch 
to 10,000 numbers of messages per minute,
+   we should set `ratePeriodInSecond` to 60 and set 
`dispatchThrottlingRateInMsg` to 10,000.
+- `dispatchThrottlingRateInMsg` Specifies the maximum number of messages to be 
delivered in each rate limiting period. 
+   The default is' -1 ', which means no limit.
+- `dispatchThrottlingRateInByte` The maximum number of bytes of messages 
delivered per rate-limiting period. The default
+   is' -1 ', which means no limit.
+
+> `dispatchThrottlingRateInMsg` and `dispatchThrottlingRateInByte` are AND 
relations.
+
+### How it works
+Message dispatch throttling works divided into these steps:
+1. Calculate the number of messages or bytes to be delivered.
+2. Estimate the amount of data to be read from the Storage (This estimate 
logic is not accurate, as described below).
+3. Update the counter of message dispatch throttling.
+4. Actually deliver the message to the client.
+
+> If the quota in the current rate limiting period is not used up, the quota 
will not be used in the next rate limiting
+> period. However, if the quota in the current rate limiting period is 
exceeded, the quota in the next rate limiting
+> period is reduced. For example, if the rate-limiting rule is set to `10 /s`, 
`11` messages are delivered to the client
+> in the first rate-limiting period,`9` messages will be delivered to the 
client in the next rate-limiting period.
+
+#### Why are messages over-delivered?
+- Cause-1: After batch-send enabled, we don't known how many messages per 
batch, so we can only estimate the number of
+batch to read(see [Estimate the amount of data to be read from the 
Storage](#Estimate-the-amount-of-data-to-be-read-from-the-Storage)),
+but the sum of all the number of messages in batches may already exceed the 
flow threshold. 
+- Cause-2: The logic of the dispatch throttling is: `1.get remaining amount` 
-> `2.load data` -> `3.deduct amount`, If
+there are two process `a & b` are executed in parallel, it is possible to 
execute in this order: 
+`process-a: 1.get remaining amount` -> `process-a: 2.load data` -> `process-b: 
1.get remaining amount` ->
+`process-b: 2.load data` -> `process-a: 3.deduct amount` -> `process-b: 
3.deduct amount`, both `process-a` and
+`process-b` dispatch enough messages, and the total number exceeds the 
threshold.
+
+#### Estimate the amount of data to be read from the Storage
+Messages is stored in blocks. If batch-send is not enabled, each message is 
packaged into an independent data block.And
+if batch-send is enabled, a batch of messages are packaged into one data 
block, then we can not determine the true count
+of messages in one data block; We also cannot determine the true size of this 
data block until we have actually read the
+it from Storage.So in order to satisfy the constraints 
`dispatchThrottlingRateInMsg` and `dispatchThrottlingRateInByte`,
+requires a mechanism to estimate how much need to read a data block.
+
+When delivering a message to the client, the Broker looks at the size and 
number of messages per data block, calculates
+an average and caches it in memory, using this average to estimate how many 
data blocks to be read. What if there is no
+estimated value in memory when the first reading of a new topic? The current 
workaround is that just delivers one data
+block to clients if it is the first delivery of a new topic. Of course, the 
broker does not store all the information
+of data blocks for a long time to process the average accurately, which would 
waste memory. Instead, a compromise
+algorithm 'avg = (history-avg * 0.9 + new-avg * 0.1)' is used.
+
+> If enabled the feature `dispatchThrottlingOnBatchMessageEnabled`, will 
support rate-limiting dispatching on the batch
+> messages rather than individual messages within batch messages. Since one 
batch is one data block, this is sufficient
+> to constrain the concurrency of read requests on storage. This makes the 
count of the number of messages inaccurate,
+> but also maximizes pulsar's throughput while keeping storage read requests 
stable.
+
+#### Automatically close message dispatch throttling when there is no backlog
+After we turn on `dispatchThrottlingOnNonBacklogConsumerEnabled`(default is 
enabled), if all consumers in one
+subscription have no backlog(it is clear that almost all read requests can hit 
the cache), then message dispatch
+throttling is turned off automatically(it means that even if we set 
`dispatchThrottlingRateInMsg` and
+`dispatchThrottlingRateInByte`, throttling won't work because there is no 
backlog),and if any consumer has backlog,
+it will be turned on automatically. If we need only to prevent the excessive 
read requests results in Storage can not

Review Comment:
   I changed the instructions to this:
   
   ```
   if all consumers in one subscription have no backlog(it is clear that almost 
all read requests can hit the cache, so Pulsar will not send read request to 
the Storage any more.)
   ``` 



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to