Skip to content

Commit c49aa6a

Browse files
thotzsoumyakoduri
authored andcommitted
cloud restore: completing read through
What are all supported : * It allows read-through for cloud-tiered objects via restore_obj_from_cloud * New tier config options user need to set allow_read_through to true and read_through_restore_days more than 1 for this feature to work, also objects with retain_head_object will be available for this feature. * First get request will fail with restoring in progress error, objects are downloaded asynchronously. * The objects restore are temporary. * Tested `aws s3api get-object`, `aws s3api head-object` and `aws s3 cp` In addition send timeout errors for first readthrough request Also addressed lint warning and other cleanup(review comments) Signed-off-by: Jiffin Tony Thottan <[email protected]>
1 parent 0e0222d commit c49aa6a

File tree

6 files changed

+202
-77
lines changed

6 files changed

+202
-77
lines changed

src/doc/rgw/cloud-restore.md

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
## Introduction
44

5-
[`cloud-transition`](https://docs.ceph.com/en/latest/radosgw/cloud-transition) feature enables data transition to a remote cloud service as part of Lifecycle Configuration via Storage Classes. However the transition is unidirectional; data cannot be transitioned back from the remote zone.
5+
[`cloud-transition`](https://docs.ceph.com/en/latest/radosgw/cloud-transition) feature enables data transition to a remote cloud service as part of Lifecycle Configuration via Storage Classes. However the transition is unidirectional; data cannot be transitioned back from the remote zone.
66

77
The `cloud-restore` feature enables restoration of those transitioned objects from the remote cloud S3 endpoints back into RGW.
88

99
The objects can be restored either by using S3 `restore-object` CLI or via `read-through`. The restored copies can be either temporary or permanent.
1010

1111
## S3 restore-object CLI
12+
1213
The goal here is to implement minimal functionality of [`S3RestoreObject`](https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html) API so that users can restore the cloud transitioned objects.
1314

1415
```sh
@@ -17,41 +18,43 @@ aws s3api restore-object \
1718
--key <value> ( can be object name or * for Bulk restore) \
1819
[--version-id <value>] \
1920
--restore-request (structure) {
20-
// for temporary restore
21+
// for temporary restore
2122
{ "Days": integer, }
2223
// if Days not provided, it will be considered as permanent copy
2324
}
2425
```
25-
This CLI may be extended in future to include custom parameters (like target-bucket/storage-class etc) specific to RGW.
2626
27+
This CLI may be extended in future to include custom parameters (like target-bucket/storage-class etc) specific to RGW.
2728
2829
## read-through
30+
2931
As per the cloud-transition feature functionality, the cloud-transitioned objects cannot be read. `GET` on those objects fails with ‘InvalidObjectState’ error.
3032
31-
But using this restore feature, transitioned objects can be restored and read. New tier-config options `allow_read_through` and `read_through_restore_days` are added for the same. Only when `allow_read_through` is enabled, `GET` on the transitioned objects will restore the objects from the S3 endpoint.
33+
But using this restore feature, transitioned objects can be restored and read. New tier-config options `allow_read_through` and `read_through_restore_days` are added for the same. Only when `allow_read_through` is enabled, `GET` on the transitioned objects will restore the objects from the S3 endpoint.
3234
3335
Note: The object copy restored via `readthrough` is temporary and is retained only for the duration of `read_through_restore_days`.
3436
3537
## Design
3638
37-
* Similar to cloud-transition feature, this feature currently works for **only s3 compatible cloud endpoint**.
39+
* Similar to cloud-transition feature, this feature currently works for **only s3 compatible cloud endpoint**.
3840
* This feature works for only **cloud-transitioned objects**. In order to validate this, `retain_head_object` option should be set to true so that the object’s `HEAD` object can be verified before restoring the object.
3941
4042
* **Request flow:**
41-
* Once the `HEAD` object is verified, its cloudtier storage class config details are fetched.
43+
* Once the `HEAD` object is verified, its cloudtier storage class config details are fetched.
4244
Note: Incase the cloudtier storage-class is deleted/updated, the object may not be restored.
43-
* RestoreStatus for the `HEAD` object is marked `RestoreAlreadyInProgress`
44-
* Object Restore is done asynchronously by issuing either S3 `GET` or S3 `RESTORE` request to the remote endpoint.
45-
* Once the object is restored, RestoreStaus is updated as `CloudRestored` and RestoreType is set to either `Temporary` or `Permanent`.
46-
* Incase the operation fails, RestoreStatus is marked as `RestoreFailed`.
47-
45+
* RestoreStatus for the `HEAD` object is marked `RestoreAlreadyInProgress`
46+
* Object Restore is done asynchronously by issuing either S3 `GET` or S3 `RESTORE` request to the remote endpoint.
47+
* Once the object is restored, RestoreStaus is updated as `CloudRestored` and RestoreType is set to either `Temporary` or `Permanent`.
48+
* Incase the operation fails, RestoreStatus is marked as `RestoreFailed`.
49+
4850
* **New attrs:** Below are the new attrs being added
49-
* `user.rgw.restore-status`: <Restore operation Status>
50-
* `user.rgw.restore-type`: <Type of Restore>
51-
* `user.rgw.restored-at`: <Restoration Time>
52-
* `user.rgw.restore-expiry-date`: <Expiration time incase of temporary copies>
53-
* `user.rgw.cloudtier_storage_class`: <CloudTier storage class used in case of temporarily restored copies>
54-
```sh
51+
* `user.rgw.restore-status`: <Restore operation Status>
52+
* `user.rgw.restore-type`: <Type of Restore>
53+
* `user.rgw.restored-at`: <Restoration Time>
54+
* `user.rgw.restore-expiry-date`: <Expiration time incase of temporary copies>
55+
* `user.rgw.cloudtier_storage_class`: <CloudTier storage class used in case of temporarily restored copies>
56+
57+
```cpp
5558
enum RGWRestoreStatus : uint8_t {
5659
None = 0,
5760
RestoreAlreadyInProgress = 1,
@@ -63,58 +66,56 @@ Note: Incase the cloudtier storage-class is deleted/updated, the object may not
6366
Temporary = 1,
6467
Permanent = 2
6568
};
66-
```
69+
```
6770
6871
* **Response:**
6972
* `S3 restore-object CLI` returns SUCCESS - either the 200 OK or 202 Accepted status code.
70-
* If the object is not previously restored, then RGW returns 202 Accepted in the response.
71-
* If the object is previously restored, RGW returns 200 OK in the response.
72-
* Special errors:
73+
* If the object is not previously restored, then RGW returns 202 Accepted in the response.
74+
* If the object is previously restored, RGW returns 200 OK in the response.
75+
* Special errors:
7376
Code: RestoreAlreadyInProgress ( Cause: Object restore is already in progress.)
7477
Code: ObjectNotFound (if Object is not found in cloud endpoint)
7578
Code: I/O error (for any other I/O errors during restore)
7679
* `GET request` continues to return an ‘InvalidObjectState’ error till the object is successfully restored.
77-
* S3 head-object can be used to verify if the restore is still in progress.
78-
* Once the object is restored, GET will return the object data.
79-
80+
* S3 head-object can be used to verify if the restore is still in progress.
81+
* Once the object is restored, GET will return the object data.
8082
8183
* **StorageClass**: By default, the objects are restored to `STANDARD` storage class. However, as per [AWS S3 Restore](https://docs.aws.amazon.com/cli/latest/reference/s3api/restore-object.html) the storage-class remains the same for restored objects. Hence for the temporary copies, the `x-amz-storage-class` returned contains original cloudtier storage-class.
82-
* Note: A new tier-config option may be added to select the storage-class to restore the objects to.
84+
* Note: A new tier-config option may be added to select the storage-class to restore the objects to.
8385
8486
* **mtime**: If the restored object is temporary, object is still marked `RGWObj::CloudTiered` and mtime is not changed i.e, still set to transition time. But in case the object is permanent copy, it is marked `RGWObj::Main` and mtime is updated to the restore time (now()).
8587
8688
* **Lifecycle**:
87-
* `Temporary` copies are not subjected to any further transition to the cloud. However (as is the case with cloud-transitioned objects) they can be deleted via regular LC expiration rules or via external S3 Delete request.
88-
* `Permanent` copies are treated as any regular objects and are subjected to any LC rules applicable.
89+
* `Temporary` copies are not subjected to any further transition to the cloud. However (as is the case with cloud-transitioned objects) they can be deleted via regular LC expiration rules or via external S3 Delete request.
90+
* `Permanent` copies are treated as any regular objects and are subjected to any LC rules applicable.
8991
9092
* **Replication**: The restored objects (both temporary and permanent) are also replicated like regular objects and will be deleted across the zones post expiration.
9193
9294
* **VersionedObjects** : In case of versioning, if any object is cloud-transitioned, it would have been non-current. Post restore too, the same non-current object will be updated with the downloaded data and its HEAD object will be updated accordingly as the case with regular objects.
9395
94-
* **Temporary Object Expiry**: This is done via Object Expirer
95-
* When the object is restored as temporary, `user.rgw.expiry-date` is set accordingly and `delete_at` attr is also updated with the same value.
96-
* This object is then added to the list used by `ObjectExpirer`.
97-
* `LC` worker thread is used to scan through that list and post expiry, resets the objects back to cloud-transitioned state i.e,
98-
* HEAD object with size=0
99-
* new attrs removed
100-
* `delete_at` reset
101-
* Note: A new RGW option `rgw_restore_debug_interval` is added, which when set will be considered as `Days` value (similar to `rgw_lc_debug_interval`).
102-
103-
* **FAILED Restore**: In case the restore operation fails,
104-
* The HEAD object will be updated accordingly.. i.e, Storage-class is reset to the original cloud-tier storage class
105-
* All the new attrs added will be removed , except for `user.rgw.restore-status` which will be updated as `RestoreFailed`
96+
* **Temporary Object Expiry**: This is done via Object Expirer
97+
* When the object is restored as temporary, `user.rgw.expiry-date` is set accordingly and `delete_at` attr is also updated with the same value.
98+
* This object is then added to the list used by `ObjectExpirer`.
99+
* `LC` worker thread is used to scan through that list and post expiry, resets the objects back to cloud-transitioned state i.e,
100+
* HEAD object with size=0
101+
* new attrs removed
102+
* `delete_at` reset
103+
* Note: A new RGW option `rgw_restore_debug_interval` is added, which when set will be considered as `Days` value (similar to `rgw_lc_debug_interval`).
104+
105+
* **FAILED Restore**: In case the restore operation fails,
106+
* The HEAD object will be updated accordingly.. i.e, Storage-class is reset to the original cloud-tier storage class
107+
* All the new attrs added will be removed , except for `user.rgw.restore-status` which will be updated as `RestoreFailed`
106108
107109
* **Check Restore Progress**: Users can issue S3 `head-object` request to check if the restore is done or still in progress for any object.
108110
109111
* **RGW down/restarts** - Since the restore operation is asynchronous, we need to keep track of the objects being restored. In case RGW is down/restarts, this data will be used to retrigger on-going restore requests or do appropriate cleanup for the failed requests.
110112
111-
* **Compression** - If the placement-target to which the objects are being restored to has compression enabled, the data will be compressed accordingly (bug2294512)
113+
* **Compression** - If the placement-target to which the objects are being restored to has compression enabled, the data will be compressed accordingly (bug2294512)
112114
113-
* **Encryption** - If the restored object is encrypted, the old sse-related xattrs/keys from the HEAD stub will be copied back into object metadata (bug2294512)
115+
* **Encryption** - If the restored object is encrypted, the old sse-related xattrs/keys from the HEAD stub will be copied back into object metadata (bug2294512)
114116
115117
* **Delete cloud object post restore** - Once the object is successfully restored, the object at the remote endpoint is still retained. However we could choose to delete it for permanent restored copies by adding new tier-config option.
116118
117-
118119
## Future work
119120
120121
* **Bulk Restore**: In the case of BulkRestore, some of the objects may not be restored. User needs to manually cross-check the objects to check the objects restored or InProgress.
@@ -124,4 +125,3 @@ Note: Incase the cloudtier storage-class is deleted/updated, the object may not
124125
* **Admin Ops**
125126
126127
* **Restore Notifications**
127-

src/rgw/driver/rados/rgw_rados.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5313,9 +5313,9 @@ int RGWRados::restore_obj_from_cloud(RGWLCCloudTierCtx& tier_ctx,
53135313
ret = processor.complete(accounted_size, etag, &mtime, set_mtime,
53145314
attrs, rgw::cksum::no_cksum, delete_at , nullptr, nullptr, nullptr,
53155315
(rgw_zone_set *)&zone_set, &canceled, rctx, log_op ? rgw::sal::FLAG_LOG_OP : 0);
5316-
if (ret < 0) {
5317-
return ret;
5318-
}
5316+
if (ret < 0) {
5317+
return ret;
5318+
}
53195319

53205320
// XXX: handle olh_epoch for versioned objects like in fetch_remote_obj
53215321
return ret;

src/rgw/driver/rados/rgw_zone.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,20 @@ int RGWZoneGroupPlacementTier::update_params(const JSONFormattable& config)
13551355
retain_head_object = false;
13561356
}
13571357
}
1358+
if (config.exists("allow_read_through")) {
1359+
string s = config["allow_read_through"];
1360+
if (s == "true") {
1361+
allow_read_through = true;
1362+
} else {
1363+
allow_read_through = false;
1364+
}
1365+
}
1366+
if (config.exists("read_through_restore_days")) {
1367+
r = conf_to_uint64(config, "read_through_restore_days", &read_through_restore_days);
1368+
if (r < 0) {
1369+
read_through_restore_days = DEFAULT_READ_THROUGH_RESTORE_DAYS;
1370+
}
1371+
}
13581372

13591373
if (tier_type == "cloud-s3") {
13601374
r = t.s3.update_params(config);
@@ -1368,6 +1382,12 @@ int RGWZoneGroupPlacementTier::clear_params(const JSONFormattable& config)
13681382
if (config.exists("retain_head_object")) {
13691383
retain_head_object = false;
13701384
}
1385+
if (config.exists("allow_read_through")) {
1386+
allow_read_through = false;
1387+
}
1388+
if (config.exists("read_through_restore_days")) {
1389+
read_through_restore_days = DEFAULT_READ_THROUGH_RESTORE_DAYS;
1390+
}
13711391

13721392
if (tier_type == "cloud-s3") {
13731393
t.s3.clear_params(config);

0 commit comments

Comments
 (0)