-
Notifications
You must be signed in to change notification settings - Fork 626
HDDS-10527. Rewrite key atomically #6385
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 18 commits
5fe2ff7
aa3bd32
9799ba5
5040d2b
6f45e67
0635134
c151122
908f9cd
3c9c0e2
17b5ff1
0fe12c5
ae4044c
7bb59e9
8890ed8
a360d45
3f3a49d
736740a
525685c
112e2e1
bcd1a28
4e6a97c
247620a
c6bc7e7
b91a051
9dc6d31
80e1802
bb7b74f
a87e092
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 | ||||
|---|---|---|---|---|---|---|
|
|
@@ -469,6 +469,30 @@ public OzoneOutputStream createKey(String key, long size, | |||||
| .createKey(volumeName, name, key, size, replicationConfig, keyMetadata); | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Overwrite an existing key using optimistic locking. The existingKey must exist in Ozone to allow | ||||||
| * the new key to be created with the same name. Additionally, the existing Key must not have been | ||||||
| * modified since the time it's details were read. This is controlled by the updateID | ||||||
| * field in the existing Key. If the key is replaced or updated the updateID will change. If the | ||||||
| * updateID has changed since the existing Key was read, either the initial key create will fail, | ||||||
| * or the key will fail to commit after the data has been written as the checks are carried out | ||||||
| * both a key open and commit time. | ||||||
| * | ||||||
| * For now this feature only works on Object Store Buckets. FSO support will be added a later. | ||||||
| * | ||||||
| * @param existingKey Name of the key to be created. | ||||||
| * @param replicationConfig Replication configuration. | ||||||
| * @return OzoneOutputStream to which the data has to be written. | ||||||
| * @throws IOException | ||||||
| */ | ||||||
| public OzoneOutputStream overwriteKey(OzoneKeyDetails existingKey, ReplicationConfig replicationConfig) | ||||||
|
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.
Suggested change
|
||||||
| throws IOException { | ||||||
| if (this.bucketLayout != BucketLayout.OBJECT_STORE) { | ||||||
| throw new IllegalArgumentException("Optimistic locking is only supported on Object Store Buckets"); | ||||||
|
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. This validation should move into OM to allow older clients to be able to update keys when OM supports it.
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. We are going to do this on a branch now and plan to immediately work on the FSO implementation so I will remove this check entirely. |
||||||
| } | ||||||
| return proxy.overwriteKey(existingKey, replicationConfig); | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Creates a new key in the bucket, with default replication type RATIS and | ||||||
| * with replication factor THREE. | ||||||
|
|
@@ -1779,7 +1803,7 @@ private void addKeyPrefixInfoToResultList(String keyPrefix, | |||||
| keyInfo.getDataSize(), keyInfo.getCreationTime(), | ||||||
| keyInfo.getModificationTime(), | ||||||
| keyInfo.getReplicationConfig(), | ||||||
| keyInfo.isFile()); | ||||||
| keyInfo.isFile(), keyInfo.getUpdateID()); | ||||||
| keysResultList.add(ozoneKey); | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,11 +70,19 @@ public class OzoneKey { | |
| * Constructs OzoneKey from OmKeyInfo. | ||
| * | ||
| */ | ||
|
adoroszlai marked this conversation as resolved.
Outdated
|
||
|
|
||
| /** | ||
| * The update ID of an existing key. This will be null if this OzoneKey | ||
| * object has not been created from an existing key read from OM, as OM allocates | ||
| * the update ID on commit of the key. | ||
| */ | ||
| private final Long updateID; | ||
|
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 are leaking internal names into public APIs. For public facing API, I would model it how google APIs have documented theirs : https://cloud.google.com/storage/docs/metadata#generation-number For now, I would change this to |
||
|
|
||
| @SuppressWarnings("parameternumber") | ||
| public OzoneKey(String volumeName, String bucketName, | ||
| String keyName, long size, long creationTime, | ||
| long modificationTime, ReplicationConfig replicationConfig, | ||
| boolean isFile) { | ||
| boolean isFile, Long updateID) { | ||
| this.volumeName = volumeName; | ||
| this.bucketName = bucketName; | ||
| this.name = keyName; | ||
|
|
@@ -83,6 +91,16 @@ public OzoneKey(String volumeName, String bucketName, | |
| this.modificationTime = Instant.ofEpochMilli(modificationTime); | ||
| this.replicationConfig = replicationConfig; | ||
| this.isFile = isFile; | ||
| this.updateID = updateID; | ||
| } | ||
|
|
||
| @SuppressWarnings("parameternumber") | ||
| public OzoneKey(String volumeName, String bucketName, | ||
| String keyName, long size, long creationTime, | ||
| long modificationTime, ReplicationConfig replicationConfig, | ||
| boolean isFile) { | ||
| this(volumeName, bucketName, keyName, size, creationTime, modificationTime, replicationConfig, | ||
| isFile, null); | ||
| } | ||
|
|
||
| @SuppressWarnings("parameternumber") | ||
|
|
@@ -91,10 +109,19 @@ public OzoneKey(String volumeName, String bucketName, | |
| long modificationTime, ReplicationConfig replicationConfig, | ||
| Map<String, String> metadata, boolean isFile) { | ||
| this(volumeName, bucketName, keyName, size, creationTime, | ||
| modificationTime, replicationConfig, isFile); | ||
| modificationTime, replicationConfig, isFile, null); | ||
| this.metadata.putAll(metadata); | ||
| } | ||
|
|
||
| @SuppressWarnings("parameternumber") | ||
| public OzoneKey(String volumeName, String bucketName, | ||
| String keyName, long size, long creationTime, | ||
| long modificationTime, ReplicationConfig replicationConfig, | ||
| Map<String, String> metadata, boolean isFile, Long updateID) { | ||
| this(volumeName, bucketName, keyName, size, creationTime, | ||
| modificationTime, replicationConfig, isFile, updateID); | ||
| this.metadata.putAll(metadata); | ||
| } | ||
| /** | ||
| * Returns Volume Name associated with the Key. | ||
| * | ||
|
|
@@ -179,6 +206,11 @@ public ReplicationConfig getReplicationConfig() { | |
| return replicationConfig; | ||
| } | ||
|
|
||
| @JsonIgnore | ||
| public Long getUpdateID() { | ||
| return updateID; | ||
| } | ||
|
|
||
| /** | ||
| * Returns indicator if key is a file. | ||
| * @return file | ||
|
|
@@ -191,7 +223,7 @@ public static OzoneKey fromKeyInfo(OmKeyInfo keyInfo) { | |
| return new OzoneKey(keyInfo.getVolumeName(), keyInfo.getBucketName(), | ||
| keyInfo.getKeyName(), keyInfo.getDataSize(), keyInfo.getCreationTime(), | ||
| keyInfo.getModificationTime(), keyInfo.getReplicationConfig(), | ||
| keyInfo.getMetadata(), keyInfo.isFile()); | ||
| keyInfo.getMetadata(), keyInfo.isFile(), keyInfo.getUpdateID()); | ||
| } | ||
|
|
||
| } | ||
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.