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

fix: Reuse KsqlClient instance for inter node requests #5624

Closed
wants to merge 4 commits into from

Conversation

purplefox
Copy link
Contributor

@purplefox purplefox commented Jun 16, 2020

Description

Fixes: #5600

Previously a new KsqlClient instance was being created for each inter node request (e.g. pull query forwarding). There is a KsqlClient constructor which takes a sharedClient instance but this was never being used in the production code path.

This PR does the following:

  1. Each server now maintains a KsqlClient instance which is used for all inter node requests
  2. The server's Vert.x instance is passed to the KsqlClient instance.

Imho, the code around ServiceContext and KsqlRestApplication is very convoluted, has poor encapsulation and is very hard to reason about. I recommend this code is refactored and simplified, but that's a bigger task.

Testing done

Describe the testing strategy. Unit and integration tests are expected for any behavior changes.

Reviewer checklist

  • Ensure docs are updated if necessary. (eg. if a user visible feature is being added or changed).
  • Ensure relevant issues are linked (description should include text like "Fixes #")

@purplefox purplefox changed the title fix: Reuse connections fix: Reuse ksqlClient instance for inter node requests Jun 16, 2020
@purplefox purplefox marked this pull request as ready for review June 16, 2020 13:22
@purplefox purplefox requested a review from a team as a code owner June 16, 2020 13:22
@purplefox purplefox requested a review from AlanConfluent June 16, 2020 13:22
@purplefox purplefox changed the title fix: Reuse ksqlClient instance for inter node requests fix: Reuse KsqlClient instance for inter node requests Jun 16, 2020
@purplefox
Copy link
Contributor Author

This should be tested with a long running pull query soak test which hammers at least two nodes as fast as possible with a high level of concurrency (thousands of concurrent requests over many connections), and where half the requests get forwarded to the other node.

I believe @AlanConfluent and @vpapavas are working on this.

I'd recommend that soak test is run before this is shipped.

@purplefox purplefox requested a review from vpapavas June 17, 2020 07:02
final KsqlSecurityContextProvider ksqlSecurityContextProvider =
new DefaultKsqlSecurityContextProvider(
securityExtension,
RestServiceContextFactory::create,
RestServiceContextFactory::create, ksqlConfig, schemaRegistryClientFactory);
RestServiceContextFactory::create, ksqlConfig, schemaRegistryClientFactory,
sharedClient);
Copy link
Member

Choose a reason for hiding this comment

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

Does this mean that the shared client will be used for all internode communication? Also heartbeat and lag reporting?

@vpapavas
Copy link
Member

Can we add a unit test to make sure we don't regress on this?

@vpapavas vpapavas self-assigned this Jun 17, 2020
.setMetricsOptions(setUpHttpMetrics(ksqlConfig)));
vertx.exceptionHandler(t -> log.error("Unhandled exception in Vert.x", t));

final KsqlClient sharedClient = new KsqlClient(
Copy link
Member

Choose a reason for hiding this comment

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

I have logic in DefaultKsqlClient that sets up the KsqlClient specifically for inter-node communication. Since it appears that the client module cannot depend on rest app configurations, I created a variant of the constructor for KsqlClient that takes a factory for HttpClientOptions so it can be setup in DefaultKsqlClient instead.

I think the main solution is to move out that logic to a central place so that it can be used by this or DefaultKsqlClient. Maybe an InterNodeKsqlClientFactory?

@@ -554,7 +554,7 @@ public static KsqlRestApplication buildApplication(final KsqlRestConfig restConf
new KsqlSchemaRegistryClientFactory(ksqlConfig, Collections.emptyMap())::get;
final ServiceContext serviceContext = new LazyServiceContext(() ->
RestServiceContextFactory.create(ksqlConfig, Optional.empty(),
schemaRegistryClientFactory));
schemaRegistryClientFactory, Optional.empty()));
Copy link
Member

Choose a reason for hiding this comment

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

This is already a singleton, so it's not a big savings, but you could use the same vertx object and KsqlClient here too, if you wanted. That way it wouldn't have to be optional and I think you might be able to remove some of the boolean sharedClients around.

@apurvam
Copy link
Contributor

apurvam commented Jun 25, 2020

Once this is fixed, we nede to merge this to 6.0.x / 0.10.x

@big-andy-coates
Copy link
Contributor

Once this is fixed, we nede to merge this to 6.0.x / 0.10.x

Feels like too big a change to put into a point release. Why not leave for 0.11?

@purplefox
Copy link
Contributor Author

Closing as superseded by #5742

@purplefox purplefox closed this Jul 2, 2020
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.

Thread blocks and multiple vert.x context issues when using ksqldb in multi-node cluster
5 participants