Skip to content

HDDS-12233. Atomically import a container - #7934

Merged
swamirishi merged 20 commits into
apache:masterfrom
ptlrs:HDDS-12233-atomic-container-replication
Apr 1, 2025
Merged

swamirishi merged 20 commits into
apache:masterfrom
ptlrs:HDDS-12233-atomic-container-replication

Conversation

@ptlrs

@ptlrs ptlrs commented Feb 19, 2025

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

This PR implements changes to atomically import a container.

  1. Place a container in the RECOVERING state before it is imported.
  2. Restore the container to its original state only after a successful import.
  3. Import the SST files of a container in a single transaction.
  4. Delete the partially-imported ratis-replicated recovering container upon datanode restart.
  5. Updated tests to match the new behavior.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-12233

How was this patch tested?

CI: https://github.com/ptlrs/ozone/actions/runs/13518880080

Added some tests which check for the state of the container.

@swamirishi swamirishi 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.

Thanks for working on the patch @ptlrs. This patch is incomplete from the sense where we are not updating the container state on disk and just doing it on memory and the problem could still persist on restarts.

Comment on lines +75 to +88
private static final String TEST_DESCRIPTOR_FILE_CONTENT = "!<KeyValueContainerData>\n" +
"checksum: 2215d39f2ae1de89fec837d18dc6387d8cba22fb5943cf4616f80c4b34e2edfe\n" +
"chunksPath: target/test-dir/MiniOzoneClusterImpl-23c1bb30-d86a-4f79-88dc-574d8259a5b3/ozone-meta/datanode-4/data-0/hdds/23c1bb30-d86a-4f79-88dc-574d8259a5b3/current/containerDir0/1/chunks\n" +
"containerDBType: RocksDB\n" +
"containerID: 1\n" +
"containerType: KeyValueContainer\n" +
"layOutVersion: 2\n" +
"maxSize: 5368709120\n" +
"metadata: {}\n" +
"metadataPath: target/test-dir/MiniOzoneClusterImpl-23c1bb30-d86a-4f79-88dc-574d8259a5b3/ozone-meta/datanode-4/data-0/hdds/23c1bb30-d86a-4f79-88dc-574d8259a5b3/current/containerDir0/1/metadata\n" +
"originNodeId: 25a48afa-f8d8-44ff-b268-642167e5354b\n" +
"originPipelineId: d7faca81-407f-4a50-a399-bd478c9795e5\n" +
"schemaVersion: '3'\n" +
"state: CLOSED";

@ptlrs ptlrs Feb 24, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The dummy content for the descriptor file resulted in test failure as we now parse the descriptor file content and save to disk when performing the ATOMIC_MOVE. Updated the content to dummy parseable data.

@ptlrs
ptlrs requested a review from swamirishi February 24, 2025 23:37
@ptlrs
ptlrs marked this pull request as ready for review February 25, 2025 15:20
@ptlrs

ptlrs commented Feb 26, 2025

Copy link
Copy Markdown
Contributor Author

Hi @ChenSammi, could you please take a look and review this PR. Thanks.

@ptlrs
ptlrs requested a review from swamirishi February 27, 2025 01:26

@sumitagrawl sumitagrawl 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.

@ptlrs given a comment to handle RECOVERING in code, plz have a look and it will simplify code

@ptlrs
ptlrs requested a review from sumitagrawl March 11, 2025 04:00

@sumitagrawl sumitagrawl 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.

LGTM

@ptlrs

ptlrs commented Mar 11, 2025

Copy link
Copy Markdown
Contributor Author

Hi @umamaheswararao, @swamirishi, @ChenSammi, @errose28, @kerneltime could you please review this PR. Thanks.

@errose28

Copy link
Copy Markdown
Contributor

The existing RECOVERING container handling will mark the failed import as unhealthy on restart. It will then be reported to SCM where it may or may not get deleted later if all the other replicas are also unhealthy. I think we should change this such that all RECOVERING containers (either Ratis imports or EC reconstructions) are deleted by the datanode on startup, since we know they are incomplete. cc @swamirishi

@swamirishi swamirishi 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.

@ptlrs thanks for the patch changes overall look good to me, excepting for some minor nitpicky comments. You may choose to address them in another follow up jira or the same, I am letting it on you to decide.

return descriptorFileContent;
}

private void persistCustomContainerState(Container<KeyValueContainerData> container, byte[] descriptorContent,

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 explicitly Container ? Can this just not be any Container<? extends ContainerData>?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Since this class implements ContainerPacker<KeyValueContainerData> I kept it consistent with the other methods. I have now made it generic since it's now part of the interface.

}

KeyValueContainerData originalContainerData =
(KeyValueContainerData) ContainerDataYaml.readContainer(descriptorContent);

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 needn't make this KeyValueContainerData specific. Do you think we can actually move this function ContainerPacker interface itself and make it a default function?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed

if (VersionedDatanodeFeatures.isFinalized(HDDSLayoutFeature.HBASE_SUPPORT)) {
getLastChunkInfoTable().loadFromFile(
getTableDumpFile(getLastChunkInfoTable(), dumpDir));
throws IOException, RocksDBException {

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.

nit: Do you want to throw RockDBException here? Why not wrap RocksDBException inside IOException? Technically RocksDBException for ozone is actually like an IO error.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed by throwing IOException instead

sstFileReader.open(tableDumpFile.getAbsolutePath());
try (ManagedReadOptions managedReadOptions = new ManagedReadOptions();
ManagedSstFileReaderIterator iterator =
ManagedSstFileReaderIterator.managed(sstFileReader.newIterator(managedReadOptions))) {

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.

Are we sure there are no tombstones in this sst file?

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.

Can you confirm this? How we are generating this sst file.

@ptlrs ptlrs Mar 28, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We dump the files by reading all the keys via an iterator so there should be no tombstones.

  1. public void dumpToFileWithPrefix(File externalFile, byte[] prefix)
    throws IOException {
    try (TableIterator<byte[], KeyValue<byte[], byte[]>> iter
    = iterator(prefix);
    DumpFileWriter fileWriter = new RDBSstFileWriter()) {
    fileWriter.open(externalFile);
    while (iter.hasNext()) {
    final KeyValue<byte[], byte[]> entry = iter.next();
    fileWriter.put(entry.getKey(), entry.getValue());



@Test
public void testImportedContainerIsClosed() throws Exception {

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.

Can we have miniOzoneCluster test case for the container cleanup on DN restart?

ptlrs added 2 commits March 28, 2025 10:50
…-container-replication

# Conflicts:
#	hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/TarContainerPacker.java
@ptlrs
ptlrs marked this pull request as draft March 28, 2025 17:58
@ptlrs
ptlrs requested a review from swamirishi April 1, 2025 00:14
@ptlrs

ptlrs commented Apr 1, 2025

Copy link
Copy Markdown
Contributor Author

Hi @swamirishi, can you please review the latest changes.

@swamirishi swamirishi 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.

LGTM @ptlrs thanks for addressing all the review comments.

@swamirishi
swamirishi marked this pull request as ready for review April 1, 2025 14:07
@swamirishi
swamirishi merged commit af5301e into apache:master Apr 1, 2025
@ptlrs
ptlrs deleted the HDDS-12233-atomic-container-replication branch April 1, 2025 18:18
@swamirishi

ghost commented Apr 1, 2025

Copy link
Copy Markdown
Contributor

Thanks for the patch @ptlrs and @sumitagrawl for reviewing the patch

@ptlrs

ghost commented Apr 1, 2025

Copy link
Copy Markdown
Contributor Author

Thank you for the extensive reviews @umamaheswararao @sumitagrawl @ChenSammi @swamirishi @errose28.

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.

6 participants