-
Notifications
You must be signed in to change notification settings - Fork 588
HDDS-4272. Volume namespace: add usedNamespace and update it when create and delete bucket #1445
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
Changes from all commits
f28ad78
505bf7b
cdfe3ba
b8b6e48
7268bec
42d7b33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -270,6 +270,7 @@ private OzoneConsts() { | |
| public static final String SRC_KEY = "srcKey"; | ||
| public static final String DST_KEY = "dstKey"; | ||
| public static final String USED_BYTES = "usedBytes"; | ||
| public static final String USED_NAMESPACE = "usedNamespace"; | ||
| public static final String QUOTA_IN_BYTES = "quotaInBytes"; | ||
| public static final String QUOTA_IN_COUNTS = "quotaInCounts"; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I see we defined usedBytes corresponding to quotaInBytes, so quotaInCounts expected to be quotaInNamespace. This is just my first feeling for this variable name. We could revisit these later in a separate JIRA to make this more understandable.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. Created https://issues.apache.org/jira/browse/HDDS-4582 to revisit it later.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I started to use
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense to me. |
||
| public static final String OBJECT_ID = "objectID"; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -885,6 +885,51 @@ public void testCheckUsedBytesQuota() throws IOException { | |
| Assert.assertEquals(3, countException); | ||
| } | ||
|
|
||
| @Test | ||
| public void testVolumeUsedNamespace() throws IOException { | ||
| String volumeName = UUID.randomUUID().toString(); | ||
| String bucketName = UUID.randomUUID().toString(); | ||
| String bucketName2 = UUID.randomUUID().toString(); | ||
| OzoneVolume volume = null; | ||
|
|
||
| // set Volume namespace quota as 1 | ||
| store.createVolume(volumeName, | ||
| VolumeArgs.newBuilder().setQuotaInCounts(1L).build()); | ||
| volume = store.getVolume(volumeName); | ||
| // The initial value should be 0 | ||
| Assert.assertEquals(0L, volume.getUsedNamespace()); | ||
| volume.createBucket(bucketName); | ||
| // Used namespace should be 1 | ||
| volume = store.getVolume(volumeName); | ||
| Assert.assertEquals(1L, volume.getUsedNamespace()); | ||
|
|
||
| try { | ||
| volume.createBucket(bucketName2); | ||
| } catch (IOException ex) { | ||
| GenericTestUtils.assertExceptionContains("QUOTA_EXCEEDED", ex); | ||
| } | ||
|
|
||
| // test linked bucket | ||
| String targetVolName = UUID.randomUUID().toString(); | ||
| store.createVolume(targetVolName); | ||
| OzoneVolume volumeWithLinkedBucket = store.getVolume(targetVolName); | ||
| String targetBucketName = UUID.randomUUID().toString(); | ||
| BucketArgs.Builder argsBuilder = new BucketArgs.Builder() | ||
| .setStorageType(StorageType.DEFAULT) | ||
| .setVersioning(false) | ||
| .setSourceVolume(volumeName) | ||
| .setSourceBucket(bucketName); | ||
| volumeWithLinkedBucket.createBucket(targetBucketName, argsBuilder.build()); | ||
| // Used namespace should be 0 because linked bucket does not consume | ||
| // namespace quota | ||
| Assert.assertEquals(0L, volumeWithLinkedBucket.getUsedNamespace()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not fully get this point, why this bucket create way will not increased the namespace quota? Just curious for this.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This comes from one of the comment above. I consider this is more like a decision that linked bucket should not consume quota. At least linked bucket should not consume space quota. I think to make consistent, do not apply namespace quota also makes sense. |
||
|
|
||
| volume.deleteBucket(bucketName); | ||
| // Used namespace should be 0 | ||
| volume = store.getVolume(volumeName); | ||
| Assert.assertEquals(0L, volume.getUsedNamespace()); | ||
| } | ||
|
|
||
| private void writeKey(OzoneBucket bucket, String keyName, | ||
| ReplicationFactor replication, String value, int valueLength) | ||
| throws IOException{ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -205,14 +205,22 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, | |
| // Add default acls from volume. | ||
| addDefaultAcls(omBucketInfo, omVolumeArgs); | ||
|
|
||
| // check namespace quota | ||
| checkQuotaInNamespace(omVolumeArgs, 1L); | ||
|
|
||
| // update used namespace for volume | ||
| omVolumeArgs.incrUsedNamespace(1L); | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before this update, we need to do the namespace quota check in checkQuotaBytesValid.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also updated the test to test quota exceed case. |
||
| // Update table cache. | ||
| metadataManager.getVolumeTable().addCacheEntry(new CacheKey<>(volumeKey), | ||
| new CacheValue<>(Optional.of(omVolumeArgs), transactionLogIndex)); | ||
| metadataManager.getBucketTable().addCacheEntry(new CacheKey<>(bucketKey), | ||
| new CacheValue<>(Optional.of(omBucketInfo), transactionLogIndex)); | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should also update the volume table cache like above, as omVolumeArgs be updated.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. O I see. it make senses. |
||
| omResponse.setCreateBucketResponse( | ||
| CreateBucketResponse.newBuilder().build()); | ||
| omClientResponse = new OMBucketCreateResponse(omResponse.build(), | ||
| omBucketInfo); | ||
| omBucketInfo, omVolumeArgs.copyObject()); | ||
| } catch (IOException ex) { | ||
| exception = ex; | ||
| omClientResponse = new OMBucketCreateResponse( | ||
|
|
@@ -301,6 +309,25 @@ private BucketEncryptionInfoProto getBeinfo( | |
| return bekb.build(); | ||
| } | ||
|
|
||
| /** | ||
| * Check namespace quota. | ||
| */ | ||
| private void checkQuotaInNamespace(OmVolumeArgs omVolumeArgs, | ||
| long allocatedNamespace) throws IOException { | ||
| if (omVolumeArgs.getQuotaInCounts() != OzoneConsts.QUOTA_RESET) { | ||
| long usedNamespace = omVolumeArgs.getUsedNamespace(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you use omVolumeArgs.getQuotaInCounts() != OzoneConsts.QUOTA_RESET to replace above condition check? That will be the better check in case maybe OzoneConsts.QUOTA_RESET value can be changed to the positive number.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make senses! Done! |
||
| long quotaInNamespace = omVolumeArgs.getQuotaInCounts(); | ||
| long toUseNamespaceInTotal = usedNamespace + allocatedNamespace; | ||
| if (quotaInNamespace < toUseNamespaceInTotal) { | ||
| throw new OMException("The namespace quota of Volume:" | ||
| + omVolumeArgs.getVolume() + " exceeded: quotaInNamespace: " | ||
| + quotaInNamespace + " but namespace consumed: " | ||
| + toUseNamespaceInTotal + ".", | ||
| OMException.ResultCodes.QUOTA_EXCEEDED); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public boolean checkQuotaBytesValid(OMMetadataManager metadataManager, | ||
| OmVolumeArgs omVolumeArgs, OmBucketInfo omBucketInfo, String volumeKey) | ||
| throws IOException { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ | |
| import java.util.Map; | ||
|
|
||
| import com.google.common.base.Optional; | ||
| import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs; | ||
| import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper; | ||
| import org.apache.hadoop.ozone.om.request.util.OmResponseUtil; | ||
| import org.slf4j.Logger; | ||
|
|
@@ -134,9 +135,23 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, | |
| omResponse.setDeleteBucketResponse( | ||
| DeleteBucketResponse.newBuilder().build()); | ||
|
|
||
| // update used namespace for volume | ||
| String volumeKey = omMetadataManager.getVolumeKey(volumeName); | ||
| OmVolumeArgs omVolumeArgs = | ||
| omMetadataManager.getVolumeTable().getReadCopy(volumeKey); | ||
| if (omVolumeArgs == null) { | ||
| throw new OMException("Volume " + volumeName + " is not found", | ||
| OMException.ResultCodes.VOLUME_NOT_FOUND); | ||
| } | ||
| omVolumeArgs.incrUsedNamespace(-1L); | ||
| // Update table cache. | ||
| omMetadataManager.getVolumeTable().addCacheEntry( | ||
| new CacheKey<>(volumeKey), | ||
| new CacheValue<>(Optional.of(omVolumeArgs), transactionLogIndex)); | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Volume table cache also need to be updated here as we update table cache in OMBucketCreateRequest.java |
||
| // Add to double buffer. | ||
| omClientResponse = new OMBucketDeleteResponse(omResponse.build(), | ||
| volumeName, bucketName); | ||
| volumeName, bucketName, omVolumeArgs.copyObject()); | ||
| } catch (IOException ex) { | ||
| success = false; | ||
| exception = ex; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.