Skip to content

HBASE-28996: Implement Custom ReplicationEndpoint to Enable WAL Backup to External Storage - #6518

Closed
vinayakphegde wants to merge 5 commits into
apache:HBASE-28957from
vinayakphegde:HBASE-28996
Closed

HBASE-28996: Implement Custom ReplicationEndpoint to Enable WAL Backup to External Storage#6518
vinayakphegde wants to merge 5 commits into
apache:HBASE-28957from
vinayakphegde:HBASE-28996

Conversation

@vinayakphegde

Copy link
Copy Markdown
Contributor

This PR implements a custom ReplicationEndpoint for HBase to enable WAL backup to external storage. It introduces several components including ContinuousBackupReplicationEndpoint, ContinuousBackupManager, and StagedBulkloadFileRegistry, among others, to handle the backup process efficiently.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@anmolnar

Copy link
Copy Markdown
Contributor

@vinayakphegde You need to add ASF license header to all new files.
You also need to run mvn spotless:apply to fix code style issues.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

Copy link
Copy Markdown

🎊 +1 overall

VoteSubsystemRuntimeLogfileComment
+0 🆗reexec0m 41sDocker mode activated.
_ Prechecks _
+1 💚dupname0m 0sNo case conflicting files found.
+0 🆗codespell0m 0scodespell was not available.
+0 🆗detsecrets0m 0sdetect-secrets was not available.
+0 🆗buf0m 0sbuf was not available.
+0 🆗buf0m 0sbuf was not available.
+1 💚@author0m 0sThe patch does not contain any @author tags.
+1 💚hbaseanti0m 0sPatch does not have any anti-patterns.
_ HBASE-28957 Compile Tests _
+0 🆗mvndep0m 43sMaven dependency ordering for branch
+1 💚mvninstall3m 31sHBASE-28957 passed
+1 💚compile1m 5sHBASE-28957 passed
+1 💚checkstyle0m 17sHBASE-28957 passed
+1 💚spotbugs2m 51sHBASE-28957 passed
+1 💚spotless0m 46sbranch has no errors when running spotless:check.
_ Patch Compile Tests _
+0 🆗mvndep0m 11sMaven dependency ordering for patch
+1 💚mvninstall3m 5sthe patch passed
+1 💚compile1m 19sthe patch passed
+1 💚cc1m 19sthe patch passed
-0 ⚠️javac0m 30s/results-compile-javac-hbase-backup.txthbase-backup generated 2 new + 102 unchanged - 0 fixed = 104 total (was 102)
+1 💚blanks0m 0sThe patch has no blanks issues.
-0 ⚠️checkstyle0m 9s/results-checkstyle-hbase-backup.txthbase-backup: The patch generated 3 new + 0 unchanged - 0 fixed = 3 total (was 0)
+1 💚spotbugs3m 17sthe patch passed
+1 💚hadoopcheck11m 52sPatch does not cause any errors with Hadoop 3.3.6 3.4.0.
+1 💚hbaseprotoc1m 5sthe patch passed
+1 💚spotless0m 44spatch has no errors when running spotless:check.
_ Other Tests _
+1 💚asflicense0m 17sThe patch does not generate ASF License warnings.
39m 27s
SubsystemReport/Notes
DockerClientAPI=1.43 ServerAPI=1.43 base: https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-6518/3/artifact/yetus-general-check/output/Dockerfile
GITHUB PR#6518
JIRA IssueHBASE-28996
Optional Testsdupname asflicense javac spotbugs checkstyle codespell detsecrets compile hadoopcheck hbaseanti spotless cc buflint bufcompat hbaseprotoc
unameLinux 96564ffaa421 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Build toolmaven
Personalitydev-support/hbase-personality.sh
git revisionHBASE-28957 / 9f581d5
Default JavaEclipse Adoptium-17.0.11+9
Max. process+thread count86 (vs. ulimit of 30000)
modulesC: hbase-protocol-shaded hbase-backup U: .
Console outputhttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-6518/3/console
versionsgit=2.34.1 maven=3.9.8 spotbugs=4.7.3
Powered byApache Yetus 0.15.0 https://yetus.apache.org

This message was automatically generated.

@Apache-HBase

Copy link
Copy Markdown

💔 -1 overall

VoteSubsystemRuntimeLogfileComment
+0 🆗reexec0m 52sDocker mode activated.
-0 ⚠️yetus0m 4sUnprocessed flag(s): --brief-report-file --spotbugs-strict-precheck --author-ignore-list --blanks-eol-ignore-file --blanks-tabs-ignore-file --quick-hadoopcheck
_ Prechecks _
_ HBASE-28957 Compile Tests _
+0 🆗mvndep0m 12sMaven dependency ordering for branch
+1 💚mvninstall4m 15sHBASE-28957 passed
+1 💚compile1m 11sHBASE-28957 passed
+1 💚javadoc0m 39sHBASE-28957 passed
+1 💚shadedjars7m 20sbranch has no errors when building our shaded downstream artifacts.
_ Patch Compile Tests _
+0 🆗mvndep0m 14sMaven dependency ordering for patch
+1 💚mvninstall3m 40sthe patch passed
+1 💚compile1m 25sthe patch passed
+1 💚javac1m 25sthe patch passed
+1 💚javadoc0m 32sthe patch passed
+1 💚shadedjars6m 46spatch has no errors when building our shaded downstream artifacts.
_ Other Tests _
+1 💚unit0m 34shbase-protocol-shaded in the patch passed.
-1 ❌unit20m 37s/patch-unit-hbase-backup.txthbase-backup in the patch failed.
49m 39s
SubsystemReport/Notes
DockerClientAPI=1.47 ServerAPI=1.47 base: https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-6518/3/artifact/yetus-jdk17-hadoop3-check/output/Dockerfile
GITHUB PR#6518
JIRA IssueHBASE-28996
Optional Testsjavac javadoc unit compile shadedjars
unameLinux 70b0ec1b100c 5.4.0-200-generic #220-Ubuntu SMP Fri Sep 27 13:19:16 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
Build toolmaven
Personalitydev-support/hbase-personality.sh
git revisionHBASE-28957 / 9f581d5
Default JavaEclipse Adoptium-17.0.11+9
Test Resultshttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-6518/3/testReport/
Max. process+thread count3603 (vs. ulimit of 30000)
modulesC: hbase-protocol-shaded hbase-backup U: .
Console outputhttps://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-6518/3/console
versionsgit=2.34.1 maven=3.9.8
Powered byApache Yetus 0.15.0 https://yetus.apache.org

This message was automatically generated.

@anmolnaranmolnar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Few comments.

Comment on lines +63 to +68
if (backupFs.exists(dirPath)) {
LOG.info("{} Directory already exists: {}", Utils.logPeerId(peerId), dirPath);
} else {
backupFs.mkdirs(dirPath);
LOG.info("{} Successfully created directory: {}", Utils.logPeerId(peerId), dirPath);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How many HBase instances are running this code? Isn't there a race condition here?
Is this run by master only?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This will run on region servers. I believe we can simplify the logic by directly using backupFs.mkdirs(dirPath). It will create the directory if it doesn't exist, and simply return true if the directory already exists.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That would be better.

Comment on lines +211 to +214
continuousBackupWalWriter.write(walEntries, bulkLoadFiles);

// prevent bulk-loaded files from deleting HFileCleaner thread
stagedBulkloadFileRegistry.addStagedFiles(bulkLoadFiles);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We might have a race here:

  1. bulkLoadFiles are written by WalWriter
  2. bulkLoadFiles gets added to the exception list for HFileCleaner

If HFileCleaner runs between these 2 events, it will delete files which recently have been staged. I'm not sure yet how to do this properly.

@vinayakphegdevinayakphegdeDec 20, 2024

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

No, that scenario doesn't occur. The replication framework prevents the deletion of files using ReplicationHFileCleaner. Files are only deleted once the WALs and bulkload files are successfully replicated, as indicated by a success return from the replicate() method.
So, it the replicate() method is complete, it won't delete the file.

However, in our case, the bulkloaded files are still in the staging area and haven’t been copied yet. Therefore, we had to implement an additional cleaner for this purpose.


@Override
public boolean isFileDeletable(FileStatus fStat) {
// The actual deletion decision is made in getDeletableFiles, so returning true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why?
Check if the file available for deletion here. Connection to HBase can be kept open.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

A single GET op to HBase checking if filename is present in the table should be quick.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This approach would be slightly faster, right? In getDeletableFiles, we could run the query once and process all the results together, instead of executing multiple queries.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'm not sure about that. Currently you run a scanner while with my approach, you'll run multiple GETs. Generally speaking PUTs and GETs are the most performant operations in key-value stores, therefore they're preferred over scanners. But. The table is small, cached, etc.

Personally I don't like scanning the same table over and over again. It's like a Hashtable.

Comment on lines +90 to +92
// Fetch staged files from HBase
Set<String> stagedFiles = StagedBulkloadFileRegistry.listAllBulkloadFiles(connection);
LOG.debug("Fetched {} staged files from HBase.", stagedFiles.size());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we really need to maintain the list of staged files in an HBase table?
Why not just return false (do not delete) if the file is in the staging area?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Use special file name prefix while staging:

bulkload1.hfile
dontdelete_bulkload2.hfile
dontdelete_bulkload3.hfile

bulkload1.hfile can be deleted from staging area others should be kept. Rename operation is atomic in HDFS afaik.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

For the bulkload files, we are not moving them anywhere. They remain in the data directory or archive directory. We are simply maintaining a reference to them in the HBase table.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I suggested another way (file renaming) to avoid accidentally deleting them. This way we could avoid maintaining an HBase table.

Sign up for freeto 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.

3 participants

@vinayakphegde@Apache-HBase@anmolnar