Skip to content

Commit 4df08d6

Browse files
iwanbkLeeSmet
authored andcommitted
reuse metadata when rebuilding the data.
SweepObject already have the metadata of the data, we can reuse it for data rebuild instead of fetch the metadata again
1 parent 1532396 commit 4df08d6

File tree

3 files changed

+38
-11
lines changed

3 files changed

+38
-11
lines changed

zstor/src/actors/repairer.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ impl Handler<SweepObjects> for RepairActor {
125125
.send(Rebuild {
126126
file: None,
127127
key: Some(key),
128+
metadata: Some(metadata),
128129
})
129130
.await
130131
{

zstor/src/actors/zstor.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ pub struct Rebuild {
8989
/// for this key. If it exists, the data will be reconstructed according to the new policy,
9090
/// and the old metadata is replaced with the new metadata.
9191
pub key: Option<String>,
92+
93+
/// metadata of the file/key to rebuild
94+
pub metadata: Option<MetaData>,
9295
}
9396

9497
#[derive(Serialize, Deserialize, Debug, Message, Clone)]
@@ -285,6 +288,7 @@ impl Handler<Rebuild> for ZstorActor {
285288
let pipeline = self.pipeline.clone();
286289
let config = self.cfg.clone();
287290
let meta = self.meta.clone();
291+
288292
AtomicResponse::new(Box::pin(
289293
async move {
290294
let cfg = config.send(GetConfig).await?;
@@ -300,31 +304,41 @@ impl Handler<Rebuild> for ZstorActor {
300304
std::io::Error::from(std::io::ErrorKind::InvalidInput),
301305
));
302306
}
303-
let old_metadata = if let Some(ref file) = msg.file {
304-
meta.send(LoadMeta { path: file.clone() })
307+
308+
let old_metadata = match (msg.metadata, &msg.file, &msg.key) {
309+
(Some(metadata), _, _) => {
310+
debug!(
311+
"Using provided metadata for rebuild file:{:?} key: {:?}",
312+
&msg.file, &msg.key
313+
);
314+
metadata
315+
}
316+
(None, Some(file), _) => meta
317+
.send(LoadMeta { path: file.clone() })
305318
.await??
306319
.ok_or_else(|| {
307320
ZstorError::new_io(
308321
"no metadata found for file".to_string(),
309322
std::io::Error::from(std::io::ErrorKind::NotFound),
310323
)
311-
})?
312-
} else if let Some(ref key) = msg.key {
313-
// key is set so the unwrap is safe
314-
meta.send(LoadMetaByKey { key: key.clone() })
324+
})?,
325+
(None, None, Some(key)) => meta
326+
.send(LoadMetaByKey { key: key.clone() })
315327
.await??
316328
.ok_or_else(|| {
317329
ZstorError::new_io(
318330
"no metadata found for file".to_string(),
319331
std::io::Error::from(std::io::ErrorKind::NotFound),
320332
)
321-
})?
322-
} else {
323-
unreachable!();
333+
})?,
334+
_ => unreachable!(),
324335
};
325336

337+
// load the data from the storage backends
326338
let input = load_data(&old_metadata).await?;
327339
let existing_data = input.clone();
340+
341+
// rebuild the data (in memory only)
328342
let (mut metadata, shards) = pipeline
329343
.send(RebuildData {
330344
input,
@@ -333,7 +347,9 @@ impl Handler<Rebuild> for ZstorActor {
333347
})
334348
.await??;
335349

336-
// build a list of the key and the backend used for the shards
350+
// build a list of (key, backend used for the shards)
351+
// - if the shard still exists in the backend, we set the backend to the old backend
352+
// - if the shard is missing, we set the backend to None
337353
let mut used_backends = Vec::new();
338354
for (i, data) in existing_data.iter().enumerate() {
339355
let key = old_metadata.shards()[i].key().to_vec();
@@ -510,6 +526,8 @@ async fn check_backend_space(
510526
}
511527
}
512528

529+
// Find valid backends for the shards
530+
// if the backend is part of the skip_backends, we don't need to check it again
513531
async fn find_valid_backends(
514532
cfg: &mut Config,
515533
shard_len: usize,

zstor/src/main.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,15 @@ async fn real_main() -> ZstorResult<()> {
311311
handle_command(ZstorCommand::Retrieve(Retrieve { file }), opts.config).await?
312312
}
313313
Cmd::Rebuild { file, key } => {
314-
handle_command(ZstorCommand::Rebuild(Rebuild { file, key }), opts.config).await?
314+
handle_command(
315+
ZstorCommand::Rebuild(Rebuild {
316+
file,
317+
key,
318+
metadata: None,
319+
}),
320+
opts.config,
321+
)
322+
.await?
315323
}
316324
Cmd::Check { file } => {
317325
handle_command(ZstorCommand::Check(Check { path: file }), opts.config).await?

0 commit comments

Comments
 (0)