Skip to content

[feat][txn] Transaction buffer snapshot writer reuse#19641

Merged
gaoran10 merged 7 commits intoapache:masterfrom
gaoran10:tb-snapshot-writer-reuse-new
Mar 20, 2023
Merged

[feat][txn] Transaction buffer snapshot writer reuse#19641
gaoran10 merged 7 commits intoapache:masterfrom
gaoran10:tb-snapshot-writer-reuse-new

Conversation

@gaoran10
Copy link
Contributor

Motivation

The transaction buffer(short for TB) snapshot topic is used to persistent snapshot data for TB, the snapshot can reduce read data when recovering.

Currently, if enable the transaction feature, every topic will create a TB snapshot producer, the topic of the producer is a namespace system topic, so we don't need to create a producer for every topic, one producer per namespace is enough.

Modifications

Add a new inner class ReferenceCountedWriter, if the ReferenceCountedWriter for one namespace does not exist, it will be initialized, or else its reference count will be increased, if the reference count reduces to 0, it will be removed from map-cache.

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: gaoran10#23

@gaoran10 gaoran10 self-assigned this Feb 27, 2023
@gaoran10 gaoran10 added type/feature The PR added a new feature or issue requested a new feature area/sql Pulsar SQL related features labels Feb 27, 2023
@github-actions github-actions bot added the doc-not-needed Your PR changes do not impact docs label Feb 27, 2023
Copy link
Contributor

@poorbarcode poorbarcode left a comment

Choose a reason for hiding this comment

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

Great improve, left some comments

});
}

private SystemTopicClient<T> getTransactionBufferSystemTopicClient(TopicName topicName) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not change the param TopicName to Namespace?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

return future;
}

private void retain() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we lock in release and retain? Otherwise, it may result in getting a writer whose referenceCount is 0

Copy link
Contributor

Choose a reason for hiding this comment

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

We may not only need to lock release and retain.
If we do not lock release and retain.

time task execute ReferenceCountedWriter::close task execute getReferenceWriter
0 check referenceCount != 0 retain check referenceCount != 0
1 decrement referenceCount = 0
2 remove and close the writer
3 increment referenceCount
4 return the closed writer

Copy link
Contributor

Choose a reason for hiding this comment

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

If we only lock release and retain.

time task execute ReferenceCountedWriter::close task execute getReferenceWriter
0 check referenceCount != 0
1 decrement referenceCount = 0
2 remove and close the writer
3 retain check referenceCount == 0
4 throw RuntimeException

Copy link
Contributor

Choose a reason for hiding this comment

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

We can change the retain method to

        private synchronized boolean retain() {
            if (referenceCount.get() == 0) {
                return false;
            } else {
                this.referenceCount.incrementAndGet();
                return true;
            }
        }

And change getReferenceWriter to

    public ReferenceCountedWriter<T> getReferenceWriter(TopicName topicName) {
        return refCountedWriterMap.compute(topicName.getNamespaceObject(), (k, v) -> {
            if (v != null && v.retain()) {
                return v;
            } else {
                return new ReferenceCountedWriter<>(topicName.getNamespaceObject(),
                        getTransactionBufferSystemTopicClient(topicName).newWriterAsync(), this);

            }
        });
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch! I adjust logic.

this.refCountedWriterMap = new ConcurrentHashMap<>();
}

public CompletableFuture<SystemTopicClient.Writer<T>> createWriter(TopicName topicName) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This method is useless. We can delete it, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

return future;
}

private void retain() {
Copy link
Contributor

Choose a reason for hiding this comment

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

We may not only need to lock release and retain.
If we do not lock release and retain.

time task execute ReferenceCountedWriter::close task execute getReferenceWriter
0 check referenceCount != 0 retain check referenceCount != 0
1 decrement referenceCount = 0
2 remove and close the writer
3 increment referenceCount
4 return the closed writer

return future;
}

private void retain() {
Copy link
Contributor

Choose a reason for hiding this comment

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

If we only lock release and retain.

time task execute ReferenceCountedWriter::close task execute getReferenceWriter
0 check referenceCount != 0
1 decrement referenceCount = 0
2 remove and close the writer
3 retain check referenceCount == 0
4 throw RuntimeException

return future;
}

private void retain() {
Copy link
Contributor

Choose a reason for hiding this comment

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

We can change the retain method to

        private synchronized boolean retain() {
            if (referenceCount.get() == 0) {
                return false;
            } else {
                this.referenceCount.incrementAndGet();
                return true;
            }
        }

And change getReferenceWriter to

    public ReferenceCountedWriter<T> getReferenceWriter(TopicName topicName) {
        return refCountedWriterMap.compute(topicName.getNamespaceObject(), (k, v) -> {
            if (v != null && v.retain()) {
                return v;
            } else {
                return new ReferenceCountedWriter<>(topicName.getNamespaceObject(),
                        getTransactionBufferSystemTopicClient(topicName).newWriterAsync(), this);

            }
        });
    }

@gaoran10
Copy link
Contributor Author

gaoran10 commented Mar 2, 2023

@liangyepianzhou Good idea! I make some changes, PLTA.

@gaoran10
Copy link
Contributor Author

gaoran10 commented Mar 6, 2023

An error was encountered while deleting the namespace, I'm trying to fix it.

@gaoran10 gaoran10 force-pushed the tb-snapshot-writer-reuse-new branch from cb945b8 to 4472ee6 Compare March 13, 2023 03:31
@gaoran10 gaoran10 force-pushed the tb-snapshot-writer-reuse-new branch from 11cd55e to 299d196 Compare March 15, 2023 05:02
@dao-jun
Copy link
Member

dao-jun commented Mar 16, 2023

Please rebase master branch, the testBatchMetadataMetrics should be fixed

@gaoran10 gaoran10 force-pushed the tb-snapshot-writer-reuse-new branch from 299d196 to bdbc228 Compare March 20, 2023 02:22
@gaoran10 gaoran10 merged commit 5d2d61e into apache:master Mar 20, 2023
@gaoran10 gaoran10 deleted the tb-snapshot-writer-reuse-new branch March 21, 2023 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sql Pulsar SQL related features doc-not-needed Your PR changes do not impact docs ready-to-test type/feature The PR added a new feature or issue requested a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants