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

[ISSUE 9783][pulsar-client] Allow pulsar client receive external timer #9802

Merged
merged 8 commits into from
Mar 29, 2021

Conversation

linlinnn
Copy link
Contributor

@linlinnn linlinnn commented Mar 4, 2021

Fixed #9783

Motivation

Allow pulsar client to receive external timer instance

Modifications

Add new constructor to provide an external timer, and share timer in pulsar proxy

Verifying this change

  • Make sure that the change passes the CI checks.

Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this is the right approach.
Probably it would be better to allow the PulsarClient to receive an external instance of the timer

How many PulsarClient instances do you have in your application?

@codelipenghui
Copy link
Contributor

@eolivelli Make sense, receive an external instance is a better choice.

Copy link
Contributor

@codelipenghui codelipenghui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It needs to add some tests to cover the changes.

@codelipenghui codelipenghui added the type/enhancement The enhancements for the existing features or docs. e.g. reduce memory usage of the delayed messages label Mar 4, 2021
@codelipenghui codelipenghui added this to the 2.8.0 milestone Mar 4, 2021
@linlinnn
Copy link
Contributor Author

linlinnn commented Mar 5, 2021

Is that means to we need to refact the constructor of the PulsarClient? or take a stratege when there are so many PulsarClient instances that over the threshold.

@codelipenghui
Copy link
Contributor

@linlinnn No, we can add a new method for the Client Builder such as .timer(Timer timer) to allow users to provide the HashedWheelTimer, so that users can decide how to create the HashedWheelTimer and when to close it.

@linlinnn
Copy link
Contributor Author

linlinnn commented Mar 5, 2021

@codelipenghui thanks, get it.

Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@codelipenghui
Copy link
Contributor

@linlinnn Are you working on this PR?

@linlinnn
Copy link
Contributor Author

@codelipenghui PTAL, I will add test cases soon if this PR is reasonable

Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't find a way for the user to use this feature.
Users use the Client Builder and they must not use the public constructors directly.

Can you please add support for the timer to the builder ?

@codelipenghui
Copy link
Contributor

@eolivelli Could you please check the previous comments? I think there is a discussion that @merlimat brings up to discuss why do not expose it to the ClientBuilder.

@eolivelli
Copy link
Contributor

@codelipenghui @linlinnn
@merlimat comment is

Instead, we could take a Timer instance from the PulsarClientImpl constructor and have the Pulsar proxy to pass it there.

now the patch is only adding a way to pass a Timer to the PulsarClientImpl.

I believe that the comment from Matteo is that is it okay to add a new constructor to PulsarClientImpl as far as it is only used in Pulsar codebase.
This new constructor is not meant to be used by users (by code outside Pulsar internals) but it is not used by Pulsar itelft.

I expect this patch to change Pulsar Proxy in order to use the new constructor.

@codelipenghui
Copy link
Contributor

@eolivelli Yes, so this PR is trying to allow pass the external timer to the client, we can fix the proxy side in a separate PR? @linlinnn I think we can update the comment? this one can't fix #9783 totally, we need to create a separate to fix the proxy side.

@linlinnn
Copy link
Contributor Author

/pulsarbot run-failure-checks

@linlinnn
Copy link
Contributor Author

@merlimat please help review again

@codelipenghui
Copy link
Contributor

ping @merlimat Please help review this PR again.

1 similar comment
@codelipenghui
Copy link
Contributor

ping @merlimat Please help review this PR again.

@linlinnn
Copy link
Contributor Author

@codelipenghui @eolivelli Please take a look, I add share timer in pulsar proxy

Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good progress!

I left one suggestion

Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me!

thank you very much

@merlimat PTAL

Copy link
Contributor

@merlimat merlimat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@linlinnn
Copy link
Contributor Author

@codelipenghui @eolivelli @merlimat Thanks for your review.

@linlinnn
Copy link
Contributor Author

/pulsarbot run-failure-checks

@linlinnn
Copy link
Contributor Author

ping @codelipenghui PTAL

@codelipenghui codelipenghui merged commit af6eaba into apache:master Mar 29, 2021
codelipenghui added a commit that referenced this pull request Mar 29, 2021
codelipenghui pushed a commit that referenced this pull request Mar 30, 2021
#9802)

Fixed #9783

Allow pulsar client to receive external timer instance

Add new constructor to provide an external timer, and share timer in pulsar proxy

- [x] Make sure that the change passes the CI checks.

(cherry picked from commit af6eaba)
codelipenghui pushed a commit that referenced this pull request Mar 30, 2021
#9802)

Fixed #9783

Allow pulsar client to receive external timer instance

Add new constructor to provide an external timer, and share timer in pulsar proxy

- [x] Make sure that the change passes the CI checks.

(cherry picked from commit af6eaba)
@codelipenghui codelipenghui added the cherry-picked/branch-2.7 Archived: 2.7 is end of life label Mar 30, 2021
codelipenghui pushed a commit that referenced this pull request Jan 19, 2022
…12037)

### Motivation

In load and performance testing, there's a need to simulate production use cases and production workloads.
For this purpose, it would be useful to be able to share the thread pools used by Pulsar client instances in order to be able to run a large amount of Pulsar clients in a single JVM without the overhead of a lot of threads. 
In the current solution, it's already possible to share the EventLoopGroup and HashedWheelTimer instances.
The solution for sharing the thread pools for the external / internal executors was missing. This PR adds support for that.

Example usage:

```java
// shared thread pool related resources
ExecutorProvider internalExecutorProvider = new ExecutorProvider(8, "shared-internal-executor");
ExecutorProvider externalExecutorProvider = new ExecutorProvider(8, "shared-external-executor");
Timer sharedTimer = new HashedWheelTimer(getThreadFactory("shared-pulsar-timer"), 1, TimeUnit.MILLISECONDS);
EventLoopGroup sharedEventLoopGroup = new EpollEventLoopGroup();

// example of creating a client which uses the shared thread pools
PulsarClientImpl client = PulsarClientImpl.builder().conf(conf)
                .internalExecutorProvider(internalExecutorProvider)
                .externalExecutorProvider(externalExecutorProvider)
                .timer(sharedTimer)
                .eventLoopGroup(sharedEventLoopGroup)
                .build();
```

It seems that this would also improve the performance of the Pulsar Proxy since new thread pools for every client connection.

That happens in the Pulsar Proxy currently: 
https://github.com/apache/pulsar/blob/af63e96d4aaa0ae4c4086583aa4f9b1edd72279b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConnection.java#L445-L451

An optimization was added in #9802 for sharing the timer, but it would be useful to also share the internal / external executors.
@lhotari
Copy link
Member

lhotari commented Jan 19, 2022

It turns out the PulsarClientImpl isn't needed at all in Pulsar Proxy. There's a PR #13836 to optimize the resource usage of Pulsar Proxy. This reduces 2 threads per proxied connection which will help improve Pulsar Proxy scalability. Please review #13836

congbobo184 pushed a commit that referenced this pull request Nov 10, 2022
…12037)

In load and performance testing, there's a need to simulate production use cases and production workloads.
For this purpose, it would be useful to be able to share the thread pools used by Pulsar client instances in order to be able to run a large amount of Pulsar clients in a single JVM without the overhead of a lot of threads.
In the current solution, it's already possible to share the EventLoopGroup and HashedWheelTimer instances.
The solution for sharing the thread pools for the external / internal executors was missing. This PR adds support for that.

Example usage:

```java
// shared thread pool related resources
ExecutorProvider internalExecutorProvider = new ExecutorProvider(8, "shared-internal-executor");
ExecutorProvider externalExecutorProvider = new ExecutorProvider(8, "shared-external-executor");
Timer sharedTimer = new HashedWheelTimer(getThreadFactory("shared-pulsar-timer"), 1, TimeUnit.MILLISECONDS);
EventLoopGroup sharedEventLoopGroup = new EpollEventLoopGroup();

// example of creating a client which uses the shared thread pools
PulsarClientImpl client = PulsarClientImpl.builder().conf(conf)
                .internalExecutorProvider(internalExecutorProvider)
                .externalExecutorProvider(externalExecutorProvider)
                .timer(sharedTimer)
                .eventLoopGroup(sharedEventLoopGroup)
                .build();
```

It seems that this would also improve the performance of the Pulsar Proxy since new thread pools for every client connection.

That happens in the Pulsar Proxy currently:
https://github.com/apache/pulsar/blob/af63e96d4aaa0ae4c4086583aa4f9b1edd72279b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConnection.java#L445-L451

An optimization was added in #9802 for sharing the timer, but it would be useful to also share the internal / external executors.

(cherry picked from commit 4591a21)
congbobo184 pushed a commit that referenced this pull request Nov 26, 2022
…12037)

In load and performance testing, there's a need to simulate production use cases and production workloads.
For this purpose, it would be useful to be able to share the thread pools used by Pulsar client instances in order to be able to run a large amount of Pulsar clients in a single JVM without the overhead of a lot of threads.
In the current solution, it's already possible to share the EventLoopGroup and HashedWheelTimer instances.
The solution for sharing the thread pools for the external / internal executors was missing. This PR adds support for that.

Example usage:

```java
// shared thread pool related resources
ExecutorProvider internalExecutorProvider = new ExecutorProvider(8, "shared-internal-executor");
ExecutorProvider externalExecutorProvider = new ExecutorProvider(8, "shared-external-executor");
Timer sharedTimer = new HashedWheelTimer(getThreadFactory("shared-pulsar-timer"), 1, TimeUnit.MILLISECONDS);
EventLoopGroup sharedEventLoopGroup = new EpollEventLoopGroup();

// example of creating a client which uses the shared thread pools
PulsarClientImpl client = PulsarClientImpl.builder().conf(conf)
                .internalExecutorProvider(internalExecutorProvider)
                .externalExecutorProvider(externalExecutorProvider)
                .timer(sharedTimer)
                .eventLoopGroup(sharedEventLoopGroup)
                .build();
```

It seems that this would also improve the performance of the Pulsar Proxy since new thread pools for every client connection.

That happens in the Pulsar Proxy currently:
https://github.com/apache/pulsar/blob/af63e96d4aaa0ae4c4086583aa4f9b1edd72279b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyConnection.java#L445-L451

An optimization was added in #9802 for sharing the timer, but it would be useful to also share the internal / external executors.

(cherry picked from commit 4591a21)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cherry-picked/branch-2.7 Archived: 2.7 is end of life release/2.7.2 type/enhancement The enhancements for the existing features or docs. e.g. reduce memory usage of the delayed messages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Pulsar Proxy HashedWheelTimer and Frame Exception
6 participants