-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Draft] [improve] [pip] PIP-314 Add metrics for redelivery_messages #21488
base: master
Are you sure you want to change the base?
Changes from 7 commits
8485cc9
b4043bf
0f73654
c0c2ed4
ef0bf5e
8fadb6a
cebc37f
fab4742
1d2be55
93b706c
675321d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# PIP-314: Add metrics pulsar_subscription_redelivery_messages | ||
|
||
# Background knowledge | ||
|
||
## Delivery of messages in normal | ||
|
||
To simplify the description of the mechanism, let's take the policy [Auto Split Hash Range](https://pulsar.apache.org/docs/3.0.x/concepts-messaging/#auto-split-hash-range) as an example: | ||
|
||
| `0 ~ 16,384` | `16,385 ~ 32,768` | `32,769 ~ 65,536` | | ||
|-------------------|-------------------|--------------------------------| | ||
| ------- C1 ------ | ------- C2 ------ | ------------- C3 ------------- | | ||
|
||
- If the entry key is between `-1(non-include) ~ 16,384(include)`, it is delivered to C1 | ||
- If the entry key is between `16,384(non-include) ~ 32,768(include)`, it is delivered to C2 | ||
- If the entry key is between `32,768(non-include) ~ 65,536(include)`, it is delivered to C3 | ||
|
||
# Motivation | ||
|
||
For the example above, if `C1` is stuck or consumed slowly, the Broker will push the entries that should be delivered to `C1` into a memory collection `redelivery_messages` and read next entries continue, then the collection `redelivery_messages` becomes larger and larger and take up a lot of memory. When sending messages, it will also determine the key of the entries in the collection `redelivery_messages`, affecting performance. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When you write "V1 is stuck" you mean the internal queue of C1 is full? When that happens, messages are continued to be read from the topic, but messages whose keys belongs to c1 will be placed in a buffer called Redelivery Mesages? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
After a client-side consumer's incoming queue is full, the Broker will stop delivering messages to it and just push these messages into the queue
Yes.
If the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you mean by "determine" the key ? Also, why doing that would ruin performance? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
After reading new messages, the Broker should filter out which messages have the same key, which is stuck in
The Broker uses the data structure |
||
|
||
# Goals | ||
- Add metrics | ||
- Broker level: | ||
- Add a metric `pulsar_broker_max_subscription_redelivery_messages_total` to indicate the max one `{redelivery_messages}` of subscriptions in the broker, used by pushing an alert if it is too large. Nit: The Broker will print a log, which contains the name of the subscription(which has the maximum count of redelivery messages). This will help find the issue subscription. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't make sense for a broker-level metrics, right? Because we will not have topic level metrics for the redelivery messages. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And I'm confused here.
How can they work together? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This name is super confusing: Max of a (single) subscription of redelivery messages , then total? I'll add suggestions soon There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Agree with you, the original type of this metric is Waiting for your suggestions. |
||
- Add a metric `pulsar_broker_memory_usage_of_redelivery_messages_bytes` to indicate the memory usage of all `redelivery_messages` in the broker. This is helpful for memory health checks. | ||
- Improve `Topic stats`. | ||
- Add an attribute `redeliveryMessageCount` under `SubscriptionStats` | ||
|
||
Differ between `redelivery_messages` and `pulsar_subscription_unacked_messages & pulsar_subscription_back_log` | ||
|
||
- `pulsar_subscription_unacked_messages`: the messages have been delivered to the client but have not been acknowledged yet. | ||
- `pulsar_subscription_back_log`: how many messages should be acknowledged, contains delivered messages, and the messages which should be delivered. | ||
|
||
### Public API | ||
|
||
<strong>SubscriptionStats.java</strong> | ||
```java | ||
long getRedeliveryMessageCount(); | ||
``` | ||
|
||
### Metrics | ||
|
||
**pulsar_broker_max_subscription_redelivery_messages_total** | ||
- Description: the max one of `{pulsar_broker_memory_usage_of_redelivery_messages_bytes}` maintains by subscriptions in the broker. | ||
poorbarcode marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- Attributes: `[cluster]` | ||
- Unit: `Counter` | ||
poorbarcode marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
**pulsar_broker_memory_usage_of_redelivery_messages_bytes** | ||
- Description: the memory usage of all `redelivery_messages` in the broker. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do you calculate the memory? message count * X? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are three collections under the instance
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @asafm Do you think that makes sense to add topic-level metrics but only for top X topics? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's take a similar problem in MySQL or Elasticsearch. You have so many queries entering the system, and you want to know the ones the are the slowest. You can enable slow-query log for example and it will log the slowest queries (above certain threshold). We can decide to have an histogram for buffer size, with 0 buckets (basically count and max) on a namespace level. Users can be alerted when an unknown topic in a namespace have max of redelivery buffer size greater than certain threshold. If you want to query which was that we can select 2 mechanisms:
@codelipenghui Your suggestion is to also define threshold but expose the topics/subscriptions via Prometheus metrics and not logs, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, for Pulsar transactions, it also has a slow transactions endpoint to query all the slow transactions. Let's take an example. Backlogs. If we only have broker level backlog, we can have a backlog limitation for each broker. But the limitation is not easy to set because it will related to the topics. Set to 100k for example, but maybe 10k topic, one topic only has 10 backlogs. It shouldn't be a problem. But if we have a topic level metrics only for the top 100 topics with the large backlogs. We can set the backlog to 10k so that we can detect at most 100 topics with the backlog issues. A REST API can also integrate with the alert systems, but it's hard to check historical data. Logs solution will work for this case; you can get historical data, but if you want to get the trend of the backlogs, it's not easy. We must set up another dashboard (Kibana) based on the logs. Because the trend is also important when troubleshooting problems. If the bottleneck is the consumer side, we should see things get better after consumers scale up. Sorry, I think I provided a wrong example before. The latency is not a good case. Counter and Gauge should be good cases. I will continue to think about the essential differences between different solutions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I have given it some thought. Here's what I think: I'm going to separate the solution into long and short term. Long termWith each feature added you're bound to have more metric you'll need to add, which might be topic or subscription level (granularity). The core problem is that we export too many metrics, right? I think the solution lies within PIP-264. In summary, I think PIP-264 solves this problem. Short termStill for now, we need a way to get alerted when topic A crosses threshold X of a certain metric. Ok, now that you know a certain namespace is in trouble, you need to know which topics. For that I was thinking of several ideas which are not finalized, so just bringing up ideas:
Previous idea discussion
|
||
- Attributes: `[cluster]` | ||
- Unit: `Counter` | ||
poorbarcode marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
# Monitoring | ||
|
||
- Push an alert if `pulsar_broker_max_subscription_redelivery_messages_total` is too large. This indicates that some `Key_Shared` consumers may be stuck, and it will affect the consumption speed and increase CPU usage. | ||
- Push an alert if `pulsar_broker_memory_usage_of_redelivery_messages_bytes` is too large. This means Redelivery messages used too much memory, which may cause OOM. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This described Key Shared. Is Redelivery or messages only relevant for Key Shared subscriptions? If so, I would state that in the background.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, in
Shared
mode, the messages can be delivered to any consumer after a new reading, so the Broker will deliver messages to other consumers when a consumer is stuck. The messages will not be pushed into theredelivery_messages
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added