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][client] Cache empty schema version in ProducerImpl schemaCache. #19929

Merged
merged 7 commits into from
Apr 12, 2023

Conversation

lifepuzzlefun
Copy link
Contributor

@lifepuzzlefun lifepuzzlefun commented Mar 26, 2023

Fixes #19928

Motivation

When use Schema.BYTES consumer and enable retry and dlq policy.

need cache the empty schema version to avoid send a lot of GetOrCreateSchema request to retrieve the schema version.

Modifications

  1. Cache empty schema version in ProducerImpl schemaCache.

  2. When read from schemaCache, check if the schema version means empty.

Verifying this change

  • Make sure that the change passes the CI checks.

Does this pull request potentially affect one of the following parts:

If the box was checked, please highlight the changes

  • Dependencies (add or upgrade a dependency)
  • The public API
  • The schema
  • The default values of configurations
  • The threading model
  • The binary protocol
  • The REST endpoints
  • The admin CLI options
  • The metrics
  • Anything that affects deployment

Documentation

  • doc
  • doc-required
  • doc-not-needed
  • doc-complete

Matching PR in forked repository

PR in forked repository:

When read from schemaCache, check if the schema version means empty.

when use Schema.BYTES consumer and enable retry and dlq policy.

need cache the empty schema version to avoid send a lot of GetOrCreateSchema request to retrieve the schema version.
@github-actions github-actions bot added the doc-not-needed Your PR changes do not impact docs label Mar 26, 2023
@lifepuzzlefun
Copy link
Contributor Author

lifepuzzlefun commented Mar 26, 2023

Why the BYTES schema consumer's retry producer and dlq consumer keeps sending GetOrCreateSchema to broker?

  1. the retry producer create with Schema.AUTO_PRODUCE_BYTES(Schema.BYTES)

    if (retryLetterProducer == null) {
    retryLetterProducer = client.newProducer(Schema.AUTO_PRODUCE_BYTES(schema))
    .topic(this.deadLetterPolicy.getRetryLetterTopic())
    .enableBatching(false)
    .blockIfQueueFull(false)
    .create();
    }

  2. when message send use Schema.AUTO_PRODUCE_BYTES(retryMessage.getReaderSchema()) schema.
    in this case retryMessage.getReaderSchema() is Schema.BYTES

deadLetterProducer.thenAccept(dlqProducer -> {
TypedMessageBuilder<byte[]> typedMessageBuilderNew =
dlqProducer.newMessage(Schema.AUTO_PRODUCE_BYTES(retryMessage.getReaderSchema().get()))
.value(retryMessage.getData())
.properties(propertiesMap);
typedMessageBuilderNew.sendAsync().thenAccept(msgId -> {
doAcknowledge(finalMessageId, ackType, Collections.emptyMap(), null).thenAccept(v -> {
result.complete(null);

  1. the method check both schema not equal. so an GetOrCreateSchema rpc is send to broker.

    @VisibleForTesting
    boolean populateMessageSchema(MessageImpl msg, SendCallback callback) {
    MessageMetadata msgMetadataBuilder = msg.getMessageBuilder();
    if (msg.getSchemaInternal() == schema) {
    schemaVersion.ifPresent(v -> msgMetadataBuilder.setSchemaVersion(v));
    msg.setSchemaState(MessageImpl.SchemaState.Ready);
    return true;
    }
    // If the message is from the replicator and without replicated schema

  2. broker return schemaVersion is an empty byte array (BYTES schema not support version).

  3. client has logic when broker return schemaVersion is an empty byte array. not cache it in ProducerImpl.schemaCache.

    } else {
    log.info("[{}] [{}] GetOrCreateSchema succeed", topic, producerName);
    // In broker, if schema version is an empty byte array, it means the topic doesn't have schema. In this
    // case, we should not cache the schema version so that the schema version of the message metadata will
    // be null, instead of an empty array.
    if (v.length != 0) {
    schemaCache.putIfAbsent(msg.getSchemaHash(), v);
    msg.getMessageBuilder().setSchemaVersion(v);
    }
    msg.setSchemaState(MessageImpl.SchemaState.Ready);
    }

so when each message is send to broker. an GetOrCreateSchema rpc is also send to broker.

@lifepuzzlefun lifepuzzlefun changed the title [fix] [client] Cache empty schema version in ProducerImpl schemaCache. [fix][client] Cache empty schema version in ProducerImpl schemaCache. Mar 27, 2023
@lifepuzzlefun
Copy link
Contributor Author

@BewareMyPower @poorbarcode @Technoboy- can you take a look ? this is a problem occur on master code and in our prod environment.

@BewareMyPower BewareMyPower added the type/enhancement The enhancements for the existing features or docs. e.g. reduce memory usage of the delayed messages label Mar 28, 2023
Copy link
Contributor

@BewareMyPower BewareMyPower left a comment

Choose a reason for hiding this comment

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

Could you also add a unit test for it? I think we can use a mocked ServerCnx to record the number of the CommandGetOrCreateSchema requests received.

Copy link
Contributor

@Technoboy- Technoboy- left a comment

Choose a reason for hiding this comment

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

Please also add the test mentioned in #19928

@lifepuzzlefun lifepuzzlefun force-pushed the fix_schema_version_not_cache branch from c66bc27 to 131dcbe Compare March 31, 2023 06:32
@lifepuzzlefun
Copy link
Contributor Author

@BewareMyPower @Technoboy- unit test added, please take a look

@lifepuzzlefun
Copy link
Contributor Author

ping @BewareMyPower @Technoboy- @congbobo184 @liangyepianzhou can you take a look ? thank you : - )

1. send more messages
2. make send case more like deadLetterProducer
@poorbarcode
Copy link
Contributor

Since we will start the RC version of 3.0.0 on 2023-04-11, I will change the label/milestone of PR who have not been merged.

  • The PR of type feature is deferred to 3.1.0
  • The PR of type fix is deferred to 3.0.1

So drag this PR to 3.0.1

@poorbarcode poorbarcode modified the milestones: 3.0.0, 3.1.0 Apr 10, 2023
@codecov-commenter
Copy link

Codecov Report

Merging #19929 (cec104b) into master (329e80b) will increase coverage by 11.35%.
The diff coverage is 100.00%.

Impacted file tree graph

@@              Coverage Diff              @@
##             master   #19929       +/-   ##
=============================================
+ Coverage     61.50%   72.85%   +11.35%     
- Complexity    25755    31623     +5868     
=============================================
  Files          1859     1861        +2     
  Lines        136792   137503      +711     
  Branches      15043    15143      +100     
=============================================
+ Hits          84129   100177    +16048     
+ Misses        44857    29366    -15491     
- Partials       7806     7960      +154     
Flag Coverage Δ
inttests 24.39% <20.00%> (-0.09%) ⬇️
systests 25.06% <80.00%> (+0.04%) ⬆️
unittests 72.12% <100.00%> (+13.48%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...va/org/apache/pulsar/client/impl/ProducerImpl.java 83.16% <100.00%> (+9.18%) ⬆️

... and 637 files with indirect coverage changes

@Technoboy- Technoboy- merged commit cff3f9b into apache:master Apr 12, 2023
@RobertIndie RobertIndie modified the milestones: 3.1.0, 3.0.0 Apr 12, 2023
RobertIndie pushed a commit that referenced this pull request Jun 2, 2023
RobertIndie pushed a commit that referenced this pull request Jun 2, 2023
Technoboy- added a commit that referenced this pull request Jun 2, 2023
nicoloboschi pushed a commit to datastax/pulsar that referenced this pull request Jun 6, 2023
…apache#19929)

Co-authored-by: wangjinlong <[email protected]>
(cherry picked from commit cff3f9b)
(cherry picked from commit a46acef)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cherry-picked/branch-2.10 cherry-picked/branch-2.11 doc-not-needed Your PR changes do not impact docs ready-to-test release/2.10.5 release/2.11.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.

[Bug] Retry & DLQ Producer keeps sending GET_OR_CREATE_SCHEMA when send message.
7 participants