Skip to content
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

Throttle greedy clients in orderer Broadcast API #4640

Merged
merged 1 commit into from
Jan 30, 2024

Conversation

yacovm
Copy link
Contributor

@yacovm yacovm commented Jan 28, 2024

This commit implements a shared rate limiter for connections authenticated with mutual TLS. The throttling and rate limiting is applied at both the Authority Key Identifier and Subject Key Identifier level, which guarantees no single organization or client can bombard the orderer with endless transactions on the expense of others.

The effective rate is divided across all clients and orgs for a time period specified by InactivityTimeout.

By default this feature is turned off.

@yacovm yacovm requested a review from a team as a code owner January 28, 2024 23:23
@yacovm yacovm force-pushed the throttle branch 3 times, most recently from 27e2bcc to 4b29392 Compare January 29, 2024 01:27
@yacovm yacovm force-pushed the throttle branch 4 times, most recently from b04dd53 to 25d96ea Compare January 29, 2024 14:37
@yacovm yacovm force-pushed the throttle branch 2 times, most recently from 1084f62 to 746f2dc Compare January 29, 2024 15:17
@pfi79
Copy link
Contributor

pfi79 commented Jan 29, 2024

@yacovm
Why didn't you use an off-the-shelf library like golang.org/x/time/rate?

@yacovm
Copy link
Contributor Author

yacovm commented Jan 29, 2024

@yacovm Why didn't you use an off-the-shelf library like golang.org/x/time/rate?

I am not sure it fits our need. I need a dynamic rate limiter that limits on a per client basis and the budget is adjusted dynamically according to how many clients are connected.

@pfi79
Copy link
Contributor

pfi79 commented Jan 29, 2024

@yacovm Why didn't you use an off-the-shelf library like golang.org/x/time/rate?

I am not sure it fits our need. I need a dynamic rate limiter that limits on a per client basis and the budget is adjusted dynamically according to how many clients are connected.

I used it for dynamic loading. Conditionally: the TPS of the system had to be X and had to be divided by all nodes. Nodes could crash and restart. And the throughput of the system should not change.

@C0rWin
Copy link
Contributor

C0rWin commented Jan 29, 2024

There are already rate limiters implemented for Endorsering, Deliver, and Gateway services; wouldn't it be better to extend its usage for ordering service as well? See here: #647 . I understand the existing approach probably doesn't provide the desired granularity, though still, even putting rate limits with the grpc interceptor is a little bit cleaner approach rather than extending the broadcast handler.

@C0rWin
Copy link
Contributor

C0rWin commented Jan 29, 2024

@yacovm, btw, do you also intend to add metrics to expose limiter budget utilization so operators can trace down setup and alerts to notify whenever the limit is exhausted per client or organization? Now, where the model is to use gateway service, meaning peers are collecting endorsements and submitting transactions, this might be crucial.

@yacovm
Copy link
Contributor Author

yacovm commented Jan 29, 2024

@yacovm Why didn't you use an off-the-shelf library like golang.org/x/time/rate?

I am not sure it fits our need. I need a dynamic rate limiter that limits on a per client basis and the budget is adjusted dynamically according to how many clients are connected.

I used it for dynamic loading. Conditionally: the TPS of the system had to be X and had to be divided by all nodes. Nodes could crash and restart. And the throughput of the system should not change.

I think you're talking about sending transactions and not receiving them, am I mistaken?

@yacovm
Copy link
Contributor Author

yacovm commented Jan 29, 2024

There are already rate limiters implemented for Endorsering, Deliver, and Gateway services; wouldn't it be better to extend its usage for ordering service as well? See here: #647 . I understand the existing approach probably doesn't provide the desired granularity, though still, even putting rate limits with the grpc interceptor is a little bit cleaner approach rather than extending the broadcast handler.

They are not rate limiters, they are simply locks that limit too many gRPC streams being opened. This does not address the problem solved here.

I think what I could have done alternatively was to make a proxy Broadcast(srv ab.AtomicBroadcast_BroadcastServer) wrapper which throttles right after calling Recv() and then forwards and returns the backend Recv() of the gRPC stream, and then the broadcast.go would have stayed intact.

@C0rWin I made the above modification, now the broadcast service implementation remains as-is.

@yacovm
Copy link
Contributor Author

yacovm commented Jan 29, 2024

@yacovm, btw, do you also intend to add metrics to expose limiter budget utilization so operators can trace down setup and alerts to notify whenever the limit is exhausted per client or organization? Now, where the model is to use gateway service, meaning peers are collecting endorsements and submitting transactions, this might be crucial.

The idea is cool but I have no intention of doing this, as this piece of work is not meant to be used in this manner.
This is only to prevent a client from spamming an orderer with too many transactions.
As long as you're an "average" client and you don't over saturate your budget on a timely manner, you should be good.

@yacovm yacovm force-pushed the throttle branch 3 times, most recently from 2feef45 to 93f3501 Compare January 30, 2024 15:11
This commit implements a shared rate limiter for connections authenticated with mutual TLS.
The throttling and rate limiting is applied at both the Authority Key Identifier and Subject Key Identifier level,
which guarantees no single organization or client can bombard the orderer with endless transactions on the expense of others.

The effective rate is divided across all clients and orgs for a time period specified by InactivityTimeout.

By default this feature is turned off.

Signed-off-by: Yacov Manevich <[email protected]>
@yacovm yacovm enabled auto-merge (squash) January 30, 2024 22:42
@yacovm yacovm merged commit 5cb00be into hyperledger:main Jan 30, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants