-
Notifications
You must be signed in to change notification settings - Fork 588
HDDS-6611. Remove chunksPath and metadataPath from container yaml file #7930
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
Conversation
adoroszlai
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ChenSammi for the patch. Mostly LGTM, few minor improvements suggested.
| if (isFinalized(HDDSLayoutFeature.DATANODE_SCHEMA_V4)) { | ||
| return KV_YAML_FIELDS_SCHEMA_V4; | ||
| } else { | ||
| return Collections.unmodifiableList(KV_YAML_FIELDS); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should return unmodifiableList in both cases.
| if (isFinalized(HDDSLayoutFeature.DATANODE_SCHEMA_V4)) { | |
| return KV_YAML_FIELDS_SCHEMA_V4; | |
| } else { | |
| return Collections.unmodifiableList(KV_YAML_FIELDS); | |
| } | |
| List<String> list = isFinalized(HDDSLayoutFeature.DATANODE_SCHEMA_V4) | |
| ? KV_YAML_FIELDS_SCHEMA_V4 | |
| : KV_YAML_FIELDS; | |
| return Collections.unmodifiableList(list); |
| if (!kvData.hasSchema(SCHEMA_V4)) { | ||
| kvData.setMetadataPath((String) nodes.get(OzoneConsts.METADATA_PATH)); | ||
| kvData.setChunksPath((String) nodes.get(OzoneConsts.CHUNKS_PATH)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This condition would need to be updated if SCHEMA_V5 is introduced. Can it be changed to something like: kvData.hasSchemaBefore(SCHEMA_V4)? Please feel free to come up with a better name.
(Same applies to conversion to YAML.)
| conf.setBoolean(OzoneConfigKeys.HDDS_CONTAINER_RATIS_DATASTREAM_ENABLED, true); | ||
| conf.setBoolean(OzoneConfigKeys.HDDS_CONTAINER_RATIS_DATASTREAM_RANDOM_PORT, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is datastream used in the test? Is it needed?
| // sleep 1s to make sure creationTime will change | ||
| Thread.sleep(1000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid this? Not only does it make tests slower, assertions about timing are flaky when relying on sleep.
If prod code already uses Clock, we can use TestClock in the tests. Otherwise, I'd propose removing assertions about creationTime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sleep here is for detecting the container directory is recreated during container import. Without this sleep, the creationTime of old directory and new directory most time will be same. I prefer to keep the creationTime here. As the creationTime is set by OS file system, I guess TestClock is not applicable here.
| assertTrue(new File(newContainerData.getContainerPath()).exists()); | ||
| assertTrue(new File(newContainerData.getChunksPath()).exists()); | ||
| assertTrue(new File(newContainerData.getMetadataPath()).exists()); | ||
| if (schemaV3Enabled) { | ||
| assertTrue(newContainerData.getDbFile().exists()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: assertThat(<some File>).exists(); provides better error message if the assertion fails.
| assertEquals(newContainerData.getContainerDBType(), oldContainerData.getContainerDBType()); | ||
| assertEquals(newContainerData.getState(), oldContainerData.getState()); | ||
| assertEquals(newContainerData.getBlockCount(), oldContainerData.getBlockCount()); | ||
| assertEquals(newContainerData.getLayoutVersion(), oldContainerData.getLayoutVersion()); | ||
| assertEquals(newContainerData.getMaxSize(), oldContainerData.getMaxSize()); | ||
| assertEquals(newContainerData.getBytesUsed(), oldContainerData.getBytesUsed()); | ||
| assertEquals(newContainerData.getMetadataPath(), oldContainerData.getMetadataPath()); | ||
| assertEquals(newContainerData.getChunksPath(), oldContainerData.getChunksPath()); | ||
| assertEquals(newContainerData.getContainerPath(), oldContainerData.getContainerPath()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Please extract a method to avoid duplicating a bunch of assertions in test cases.
| public static final String CONTAINER_SCHEMA_V4_ENABLED = | ||
| "hdds.datanode.container.schema.v4.enabled"; | ||
| public static final boolean CONTAINER_SCHEMA_V4_ENABLED_DEFAULT = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We had issues with the schema v3 feature flag in the past because if it was enabled then disabled, the schema v3 containers would not get loaded. I don't think we should have config keys for container schema versions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's merely for some existing test cases specifically for V3. Let me check if they can be refactored.
|
@adoroszlai @errose28 , thanks for the review. Comments are addressed. Would you like to take another look? |
|
Thanks @ChenSammi for updating the patch. Let's wait for @errose28 to take a look. |
| HBASE_SUPPORT(8, "Datanode RocksDB Schema Version 3 has an extra table " + | ||
| "for the last chunk of blocks to support HBase.)"); | ||
| "for the last chunk of blocks to support HBase.)"), | ||
| DATANODE_SCHEMA_V4(9, "Container yaml file doesn't require chunksPath and metadataPath"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| DATANODE_SCHEMA_V4(9, "Container yaml file doesn't require chunksPath and metadataPath"); | |
| DATANODE_SCHEMA_V4(9, "Container YAML file doesn't require chunksPath and metadataPath"); |
| // V4: Column families is same as V3, | ||
| // removed chunkPath and metadataPath in .container file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // V4: Column families is same as V3, | |
| // removed chunkPath and metadataPath in .container file | |
| /** | |
| * Schema version 4 for Ozone container files. | |
| * <p> | |
| * The column families remain the same as defined in {@link #SCHEMA_V3}. | |
| * However, the {@code chunkPath} and {@code metadataPath} | |
| * fields have been removed in this version of the .container files. | |
| * </p> | |
| */ |
|
|
||
| Yaml yaml = ContainerDataYaml.getYamlForContainerType( | ||
| containerData.getContainerType(), | ||
| containerData.getContainerType(), containerData, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| containerData.getContainerType(), containerData, | |
| containerData.getContainerType(), | |
| containerData, |
| return readContainer(inputFileStream); | ||
| KeyValueContainerData containerData = (KeyValueContainerData) readContainer(inputFileStream); | ||
| if (containerData.getChunksPath() == null) { | ||
| containerData.setChunksPath(containerFile.getParentFile().getParentFile().getAbsolutePath() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move containerFile.getParentFile().getParentFile().getAbsolutePath() .concat(OZONE_URI_DELIMITER).concat(STORAGE_DIR_CHUNKS) into separate variable.
| yamlFields = new ArrayList<>(yamlFields); | ||
| yamlFields.add(REPLICA_INDEX); | ||
| } | ||
| if (((KeyValueContainerData)containerData).olderSchemaThan(SCHEMA_V4)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (((KeyValueContainerData)containerData).olderSchemaThan(SCHEMA_V4)) { | |
| if (((KeyValueContainerData) containerData).olderSchemaThan(SCHEMA_V4)) { |
| KeyValueContainerData newContainerData = | ||
| new KeyValueContainerData(containerID1, | ||
| oldContainerData.getLayoutVersion(), | ||
| oldContainerData.getMaxSize(), pipeline.getId().getId().toString(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| oldContainerData.getMaxSize(), pipeline.getId().getId().toString(), | |
| oldContainerData.getMaxSize(), | |
| pipeline.getId().getId().toString(), |
| KeyValueContainerData data = (KeyValueContainerData) ContainerDataYaml | ||
| .readContainer(containerDescriptorYaml); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| KeyValueContainerData data = (KeyValueContainerData) ContainerDataYaml | |
| .readContainer(containerDescriptorYaml); | |
| KeyValueContainerData data = (KeyValueContainerData) ContainerDataYaml.readContainer(containerDescriptorYaml); |
| newContainer.importContainerData(fis, packer); | ||
| } | ||
|
|
||
| assertTrue(isContainerEqual(newContainerData, oldContainerData)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use assertThat
| newContainer.getContainerData().getChunksPath()); | ||
| assertEquals(yamlFile.getParentFile().getAbsolutePath(), newContainer.getContainerData().getMetadataPath()); | ||
| FileTime creationTime2 = (FileTime) Files.getAttribute( | ||
| Paths.get(newContainer.getContainerData().getContainerPath()), "creationTime"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move into a separate variable
| assertNotEquals(creationTime1.toInstant(), creationTime2.toInstant()); | ||
| } | ||
|
|
||
| private boolean isContainerEqual(KeyValueContainerData containerData1, KeyValueContainerData containerData2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not need such method. Usually matchers have field-by-field comparison methods.
|
@ChenSammi I've reviewed the code in context with your comment on the jira and I still do not think this requires a schema version. Actually the change should be much simpler without it:
Checking usages of
|
@errose28 , it's different, you can check ContainerUtils#verifyChecksum, where the container yaml file checksum is verified. I would love to adopt it if it can verify both container yaml file with these two fields and without the two fields in an elegant way. One possible solution is read the entire container file into String first, check whether the String contains "chunksPath" and "metadataPath", and then create Yaml object. |
|
@ivanzlenko , thank you for the review. I will try to address some of them in next patch. For the rest, I would like to keep them, for example, keeping multiple parameters in one line. Actually one line one parameter is not a recommended style in Ozone, we should avoid to use that. And those style related comments in test case codes. |
In many cases it is very much hurts readability: callFunc(param1, param2, param3,
param4, param5,
aVeryLongParameterNameWhichTakesAlmostAllSpace,
param7, param8);Compared to: callFunc(
param1,
param2,
param3,
param4,
param5,
aVeryLongParameterNameWhichTakesAlmostAllSpace,
param7,
param8
);It is way easier to understand what is going on and which parameters are involved in a function call. |
|
/pending conflicts, reviews |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Marking this issue as un-mergeable as requested.
Please use /ready comment when it's resolved.
Please note that the PR will be closed after 21 days of inactivity from now. (But can be re-opened anytime later...)
conflicts, reviews
|
Thank you very much for the patch. I am closing this PR temporarily as there was no activity recently and it is waiting for response from its author. It doesn't mean that this PR is not important or ignored: feel free to reopen the PR at any time. It only means that attention of committers is not required. We prefer to keep the review queue clean. This ensures PRs in need of review are more visible, which results in faster feedback for all PRs. If you need ANY help to finish this PR, please contact the community on the mailing list or the slack channel." |
What changes were proposed in this pull request?
Remove chunkPath and metadataPath from container yaml file
Changes made in this patch,
So if it's a V2/V3 schema container, its yaml file will have chunkPath and metadataPath. If it's a V4 schema container, then its yaml file doesn't have chunkPath and metadataPath.
What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-6611
How was this patch tested?