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

[Transaction] Transaction timeout implementation. #9229

Merged

Conversation

congbobo184
Copy link
Contributor

Motivation

in order to handle the transaction timeout.

when aborting and committing finish we should change the status in transaction coordinator.

implement

  1. add the transaction timeout tracker factory
  2. add the transaction timeout tracker
  3. use HashedWheelTimer to implement it.

Verifying this change

Add the tests for it

Does this pull request potentially affect one of the following parts:
If yes was chosen, please highlight the changes

Dependencies (does it add or upgrade a dependency): (no)
The public API: (no)
The schema: (no)
The default values of configurations: (no)
The wire protocol: (no)
The rest endpoints: (no)
The admin cli options: (no)
Anything that affects deployment: (no)

congbo added 7 commits January 12, 2021 23:40
# Conflicts:
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/TransactionMetadataStoreService.java
#	pulsar-broker/src/main/java/org/apache/pulsar/broker/service/ServerCnx.java
#	pulsar-common/src/main/proto/PulsarMarkers.proto
#	pulsar-transaction/coordinator/src/main/java/org/apache/pulsar/transaction/coordinator/impl/MLTransactionMetadataStore.java

private Timer timer;

private static final long tickTimeMillis = 1L;
Copy link
Contributor

Choose a reason for hiding this comment

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

Use 1 millis as the default tick duration will lead to high CPU workload, it's better to use the default tick duration 100ms of the HashedWheelTimer

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this tick time is for one timeOut, the timer is use by default.


@Override
public void initialize() {
this.timer = new HashedWheelTimer(new DefaultThreadFactory("transaction-timeout-tracker"),
Copy link
Contributor

Choose a reason for hiding this comment

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

Please consider reusing the external timer such as the timer that the broker used? This will saving CPU workload.

long timeoutTime = priorityQueue.peekN1();
long nowTime = clock.millis() / BASE_OF_MILLIS_TO_SECOND;
if (timeoutTime < nowTime){
transactionMetadataStoreService.endTransaction(new TxnID(priorityQueue.peekN2(),
Copy link
Contributor

Choose a reason for hiding this comment

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

How to handle the transaction is committed? we don't need to abort a transaction that already committed or aborted.

return CompletableFuture.completedFuture(false);
}
synchronized (this){
long nowTime = clock.millis() / BASE_OF_MILLIS_TO_SECOND;
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 use millis directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Transaction timeout unit is second.

Comment on lines 46 to 47
private final static long INITIAL_TIMEOUT = 1L;
private long nowTaskTimeoutTime = INITIAL_TIMEOUT;
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please give more details about these 2 fields?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The timeout may wait time longer than the new transaction timeout time, so we should cancel the current timeout and create a timeout wait time is the new transaction timeout time.

* @param timeout
* the absolute timestamp for transaction timeout
*/
void replayAddTransaction(long sequenceId, long timeout);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't use addTransaction?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

transaction log not reply complete, we can't start timer to abort transaction.

Comment on lines 179 to 217
new Thread(() -> {
for (int i = 0; i < 100; i ++) {
try {
transactionMetadataStore.newTransaction(1);
} catch (Exception e) {
//no operation
}
}
}).start();

new Thread(() -> {
for (int i = 0; i < 100; i ++) {
try {
transactionMetadataStore.newTransaction(3);
} catch (Exception e) {
//no operation
}
}
}).start();

new Thread(() -> {
for (int i = 0; i < 100; i ++) {
try {
transactionMetadataStore.newTransaction(2);
} catch (Exception e) {
//no operation
}
}
}).start();

new Thread(() -> {
for (int i = 0; i < 100; i ++) {
try {
transactionMetadataStore.newTransaction(10);
} catch (Exception e) {
//no operation
}
}
}).start();
Copy link
Contributor

Choose a reason for hiding this comment

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

use for i ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in order to new 100 transaction, we also change the for to while.

/**
* When replay the log finished, we need to start the tracker.
*/
void start();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the start method does not only used by transactions replay? Is there any problem that call start first then replay the transactions?

Copy link
Contributor

Choose a reason for hiding this comment

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

BTW, we can only define all method async.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

return void, we also need to async?

@Override
public void close() {
priorityQueue.close();
this.close();
Copy link
Contributor

Choose a reason for hiding this comment

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

should cancel the timeout?

@congbobo184
Copy link
Contributor Author

/pulsarbot run-failure-checks

1 similar comment
@congbobo184
Copy link
Contributor Author

/pulsarbot run-failure-checks

@congbobo184
Copy link
Contributor Author

/pulsarbot run-failure-checks

1 similar comment
@congbobo184
Copy link
Contributor Author

/pulsarbot run-failure-checks

@congbobo184
Copy link
Contributor Author

/pulsarbot run-failure-checks

1 similar comment
@congbobo184
Copy link
Contributor Author

/pulsarbot run-failure-checks

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.

2 participants