all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Christian Ebner <c.ebner@proxmox.com>
To: "Fabian Grünbichler" <f.gruenbichler@proxmox.com>,
	"Proxmox Backup Server development discussion"
	<pbs-devel@lists.proxmox.com>
Subject: Re: [pbs-devel] [PATCH proxmox-backup 3/5] garbage collection: add structure for optimized image iteration
Date: Fri, 7 Mar 2025 09:59:33 +0100	[thread overview]
Message-ID: <fb8cfa0b-12d9-4aae-822b-a5fe1debaac9@proxmox.com> (raw)
In-Reply-To: <1702251428.6181.1741337595091@webmail.proxmox.com>

On 3/7/25 09:53, Fabian Grünbichler wrote:
> 
>> Christian Ebner <c.ebner@proxmox.com> hat am 07.03.2025 09:24 CET geschrieben:
>>
>>   
>> On 3/5/25 14:47, Fabian Grünbichler wrote:
>>> On February 21, 2025 3:01 pm, Christian Ebner wrote:
>>>> Implements the GroupedImageList struct and methods, which groups
>>>> index files (image) paths by a hierarchy for optimized iteration
>>>> during phase 1 of garbage collection.
>>>>
>>>> Currently, phase 1 of garbage collection iterates over all folders in
>>>> the datastore, without considering any logical organization. This is
>>>> to avoid missing image indices which might have unexpected paths,
>>>> thereby deleting chunks which are still in use by these indices in GC
>>>> phase 2.
>>>>
>>>> The new structure helps to iterate over the index files in a more
>>>> logical way, without missing strange paths. The hierarchical
>>>> organization helps to avoid touching shared chunks of incremental
>>>> snapshot backups in a backup group multiple times, by allowing
>>>> tracking of these without excessive memory requirements.
>>>>
>>>> Since deduplication happens on a per image basis for subsequent
>>>> snapshots, the hierarchy is chosen as follows:
>>>> - ns/group
>>>> - image filename
>>>> - snapshot timestamp
>>>>
>>>> This allows to iterate over consecutive snapshots for the same images
>>>> in the same backup namespace and group.
>>>>
>>>> Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
>>>> ---
>>>>    pbs-datastore/src/datastore.rs | 63 ++++++++++++++++++++++++++++++++++
>>>>    1 file changed, 63 insertions(+)
>>>>
>>>> diff --git a/pbs-datastore/src/datastore.rs b/pbs-datastore/src/datastore.rs
>>>> index eda78193d..520f54548 100644
>>>> --- a/pbs-datastore/src/datastore.rs
>>>> +++ b/pbs-datastore/src/datastore.rs
>>>> @@ -1,4 +1,5 @@
>>>>    use std::collections::{HashMap, HashSet};
>>>> +use std::ffi::OsString;
>>>>    use std::io::{self, Write};
>>>>    use std::os::unix::ffi::OsStrExt;
>>>>    use std::os::unix::io::AsRawFd;
>>>> @@ -1573,3 +1574,65 @@ impl DataStore {
>>>>            Ok(())
>>>>        }
>>>>    }
>>>> +
>>>> +struct GroupedImageList {
>>>> +    groups: HashMap<String, HashMap<OsString, Vec<(i64, PathBuf)>>>,
>>>
>>> this seems very complicated, couldn't we make it a lot simpler by doing
>>>
>>> key: NS + Group (as tuple, using the actual types)
>>> value: (snapshot => index paths)
>>>
>>> or even a nested mapping of
>>>
>>> NS -> Group -> Snapshot -> Images
>>>
>>> and then simply reset when proceeding from one snapshot to the next? the
>>> scope of "in-memory chunk digests" would still be bounded (in a way that
>>> is in line with how we do it in many other parts, like when doing backup
>>> + restore), and the structure of this helper entity and the way it is
>>> iterated over would feel much more natural.
>>
>> The type signature looks more complex than what it is in the end, but I
>> do agree that this can be reduced/optimized.
> 
> it's not so much the type itself, but the elements (too much String-like
> types where we could have proper ones) and the way of grouping things ;)
> 
> in the end, it is either a nested map or one with a complex key, no way
> around it (well, other than the alternate approach below :))
> 
>>>
>>> we could go one step further, but that might eat some of our performance
>>> gains here
>>>
>>> - list all images like we did before and store the result in a
>>>     collection that allows fast removal
>>> - iterate normally over the datastore in a structured fashion using the
>>>     existing helpers
>>> -- when proceeding from one snapshot to the next, use the new "don't
>>> retouch chunks" logic
>>> -- remove each visited image path from the list of images
>>> - if any images are left at the end in that list, mark those manually
>>>     (strange or vanished paths, should hopefully be empty or irrelevant)
>>>
>>> the main downside is that we'd have to iterate twice (well, not quite
>>> twice, since the hierarchical iterators skip parts outside of the
>>> "known" hierarchy), but we would save all this custom parse-back logic
>>> here. if we keep the parse-back logic, then I think we want to have a
>>> logical structure as well that follows how we normally do things.
>>>
>>> I think that the list_images part of GC is by far the least expensive
>>> though (for my test datastore where the GC runtime goes down from 52 to
>>> 17s with your patch series, listing images is 12ms of that ;)), so
>>> effectively doing it twice might not hurt that much in practice..
>>
>> I do like this approach more, as this will also detect snapshots as
>> "strange paths" when the helpers themself do fail to detect an index
>> file for some reason, not just the snapshot being off.
>>
>> So I will reiterate the patches using this approach, thanks!
> 
> perf numbers for bigger datastores and the usual pathological candidates
> (NFS/Samba, single spinning rust) would be nice in that case - I guess
> that with iterating twice we should still end up being faster, as the
> reduced chunk accesses should by far outweigh the metadata accesses for
> listing (unless you only have a single snapshot per group I guess), but
> hard numbers are better than gut feelings :) both duration and number of
> file operations might be interesting (maybe for stock, this version and
> the next one?)

Acked, will also look into how to get more representative performance 
statistics for this as well (maybe by setting up a datastore in tmpfs 
and using perf counters), as I noticed that just looking a the runtime 
for this on a regular datastore is not really telling. There are to much 
moving parts involved, leading to a huge spread in the observables.


_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel

  reply	other threads:[~2025-03-07  9:00 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-21 14:01 [pbs-devel] [PATCH proxmox-backup 0/5] GC: avoid multiple atime updates Christian Ebner
2025-02-21 14:01 ` [pbs-devel] [PATCH proxmox-backup 1/5] datastore: restrict datastores list_images method scope to module Christian Ebner
2025-02-21 14:01 ` [pbs-devel] [PATCH proxmox-backup 2/5] garbage collection: refactor archive type based chunk marking logic Christian Ebner
2025-02-21 14:01 ` [pbs-devel] [PATCH proxmox-backup 3/5] garbage collection: add structure for optimized image iteration Christian Ebner
2025-03-05 13:47   ` Fabian Grünbichler
2025-03-07  8:24     ` Christian Ebner
2025-03-07  8:53       ` Fabian Grünbichler
2025-03-07  8:59         ` Christian Ebner [this message]
2025-02-21 14:01 ` [pbs-devel] [PATCH proxmox-backup 4/5] garbage collection: allow to keep track of already touched chunks Christian Ebner
2025-02-21 14:01 ` [pbs-devel] [PATCH proxmox-backup 5/5] fix #5331: garbage collection: avoid multiple chunk atime updates Christian Ebner
2025-02-21 15:35 ` [pbs-devel] [PATCH proxmox-backup 0/5] GC: avoid multiple " Roland
2025-02-21 15:49   ` Christian Ebner
2025-02-22 17:50     ` Roland
2025-03-10 11:18 ` Christian Ebner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fb8cfa0b-12d9-4aae-822b-a5fe1debaac9@proxmox.com \
    --to=c.ebner@proxmox.com \
    --cc=f.gruenbichler@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal