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

feat(wal): optimize the start-up and shutdown of WAL #1625

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

CLFutureX
Copy link
Contributor

@CLFutureX CLFutureX commented Jul 23, 2024

Motivation :
As a core component of AutoMQ that is closely related to memory resources, the initialization and termination processes of WAL must ensure a high degree of robustness. However, there are currently some flaws in these processes that fail to achieve a complete operational loop. This means that during the startup and shutdown processes, all relevant resources may not be properly handled, which can affect the stability and reliability of the system. It is necessary to further optimize these processes to ensure they can manage memory resources seamlessly from start to finish, avoiding potential resource leaks or other issues.

@CLFutureX CLFutureX changed the title feat(wal): wal start optimization feat(wal): Optimize the start-up and shutdown of WAL Jul 24, 2024
@CLFutureX
Copy link
Contributor Author

@superhx @Chillax-0v0 hey, PTAL

Copy link
Contributor

@Chillax-0v0 Chillax-0v0 left a comment

Choose a reason for hiding this comment

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

Hi @CLFutureX,

I apologize for the delay in reviewing this PR. Thank you for your patience and for the effort you've put into this work.

I've gone through the changes and have a few suggestions that I believe will improve the implementation. Could you please consider these modifications?

Thank you again for your contribution!

Comment on lines 281 to 298
switch (WAL_STATE.get(this)) {
case WAL_STATE_INIT:
if (WAL_STATE.compareAndSet(this, WAL_STATE_INIT, WAL_STATE_STARTED)) {
boolean success = false;
try {
doStart();
success = true;
} finally {
if (!success) {
WAL_STATE.compareAndSet(this, WAL_STATE_STARTED, WAL_STATE_INIT);
LOGGER.warn("block WAL service started fail");
}
}
}
break;
case WAL_STATE_STARTED:
LOGGER.warn("block WAL service already started");
break;
Copy link
Contributor

@Chillax-0v0 Chillax-0v0 Jul 30, 2024

Choose a reason for hiding this comment

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

Currently, the "started" state is primarily used to check whether the metadata required for WAL operation (e.g., WAL Header) is ready (see callers of checkStarted), in order to avoid data corruption caused by premature writes.

Therefore, the state can only be set to "started" after the doStart method executes successfully.

Adding an intermediate "starting" state might resolve the issue.

private static final int WAL_STATE_STARTED = 2;
private static final int WAL_STATE_SHUTING_DOWN = 3;
private static final int WAL_STATE_SHUTDOWN = 4;
private static final AtomicIntegerFieldUpdater<BlockWALService> WAL_STATE = AtomicIntegerFieldUpdater.newUpdater(BlockWALService.class, "state");
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 there is no need to use AtomicIntegerFieldUpdater here; an AtomicReference<State> should suffice. Here are a few reasons:

  • In our scenario, there won't be many WAL instances simultaneously (in fact, in most cases, there is only one). So a global static updater is unnecessary.
  • Compared to AtomicIntegerFieldUpdater, AtomicReference can provide better code readability and maintainability.
  • I conducted a simple benchmark, and there is no significant performance difference between them (in fact, for the most frequently called get method in our use case, AtomicReference performs slightly better).

Comment on lines 119 to 122
private static final int WAL_STATE_INIT = 1;
private static final int WAL_STATE_STARTED = 2;
private static final int WAL_STATE_SHUTING_DOWN = 3;
private static final int WAL_STATE_SHUTDOWN = 4;
Copy link
Contributor

@Chillax-0v0 Chillax-0v0 Jul 30, 2024

Choose a reason for hiding this comment

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

If we use AtomicReference to maintain the state of WAL (as I mentioned above), then these int constants can also be replaced with a separate enum class.

@Chillax-0v0 Chillax-0v0 changed the title feat(wal): Optimize the start-up and shutdown of WAL feat(wal): optimize the start-up and shutdown of WAL Jul 30, 2024
@CLFutureX
Copy link
Contributor Author

Hi @CLFutureX,

I apologize for the delay in reviewing this PR. Thank you for your patience and for the effort you've put into this work.

I've gone through the changes and have a few suggestions that I believe will improve the implementation. Could you please consider these modifications?

Thank you again for your contribution!

Thank you for your reply, I am very willing to make the modifications according to your suggestions.

Hi @CLFutureX,

I apologize for the delay in reviewing this PR. Thank you for your patience and for the effort you've put into this work.

I've gone through the changes and have a few suggestions that I believe will improve the implementation. Could you please consider these modifications?

Thank you again for your contribution!

Thank you for your reply. I am happy to modify according to your suggestions:

Firstly, I plan to create a new WalState enum and the corresponding AtomicReference object as advised

enum WalState {
INIT(1),
STARTING(2),
STARTED(3),
SHUTTING_DOWN(4),
SHUTDOWN(5);
private final int state;
WalState(int state) {
this.state = state;
}
}

However, during the modification process, I found that the state branch judgment in the start() method is not very
friendly due to the syntax of switch-case, which leads to the need to rewrite the conditional branches as if-else.
Therefore, I chose another method based on final constants plus AtomicInteger.

Secondly, a starting state has been added to the state machine. The state is only changed to started after a successful startup.

@CLFutureX CLFutureX requested a review from Chillax-0v0 July 31, 2024 07:44
@Chillax-0v0
Copy link
Contributor

@CLFutureX Hello, I have submitted a PR to your branch CLFutureX#1, which converts WalState into an enum class. Please take a look.

refactor(s3stream/wal): use an enum class to identify the WAL state
@CLFutureX
Copy link
Contributor Author

@CLFutureX Hello, I have submitted a PR to your branch CLFutureX#1, which converts WalState into an enum class. Please take a look.

LGTM

Copy link

This PR is being marked as stale since it has not had any activity in 90 days. If you would like to keep this PR alive, please ask a committer for review. If the PR has merge conflicts, please update it with the latest from trunk (or appropriate release branch)

If this PR is no longer valid or desired, please feel free to close it. If no activity occurs in the next 30 days, it will be automatically closed.

@github-actions github-actions bot added the Stale label Nov 21, 2024
@daniel-y daniel-y requested a review from Gezi-lzq as a code owner December 30, 2024 12:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants