garethgeorge / backrest

Backrest is a web UI and orchestrator for restic backup.
GNU General Public License v3.0
1.29k stars 37 forks source link

Set nice/ionice levels for commands run by backrest #281

Closed ArthurusDent closed 4 months ago

ArthurusDent commented 5 months ago

Is your feature request related to a problem? Please describe. Longer backup operations can noticeably impact system performance, especially on desktop systems.

Once restic check will be supported, something like restic check --read-data can also hog system resources for quite a while.

Describe the solution you'd like The rough idea is inspired by the restic documentation.

One example they use there is $ ionice -c2 nice -n19 ./restic -r /media/gour/backup/ backup /home.

I have not completely thought this through, so this is just an idea that can probably be improved.

In the spirit of keeping things simple, I was thinking about implementing a switch somewhere (plan, repository) which would work as "run with normal process priority" or "run in background", where background would mean ionice -c2 nice -n19.

I'm unsure whether running in background would be a good idea under all circumstances because if the machine is currently running other tasks (e.g. encoding a video), could the backrest task essentially take a lot longer and then block other backup operations? How would this new feature need to be implemented to not cause additional problems?

Would it be better to have ionice and nice be configurable by the user?

garethgeorge commented 5 months ago

I think this sounds like a great idea -- this is something I had intended to do pretty early on and simply fell off my plate. Adding the capability should be fairly straightforward.

My leaning is the same of yours re: exposing a simple toggle to deprioritize backup operation IO. I wonder whether it even makes much sense to worry about nice on the CPU side of things. Perhaps an enum?

wdyt? Are there options I'm missing?

ArthurusDent commented 4 months ago

I wonder whether it even makes much sense to worry about nice on the CPU side of things.

I use a lot of old desktop machines and I hope that using nice would help those systems stay as responsive as possible during backup operations. But to be honest, someone would have to run tests and actually measure stuff to be able to draw some more objective conclusions.

Perhaps an enum?

Can't really help you there. My programming skills are almost zero.

When looking at the manpage of ionice I didn't really understand what the difference between the class "none" and "best-effort" is. It didn't make a lot of sense to me that a process would be assigned the class "none" per default. What's the impact then if it gets re-classed as "best-effort"? Will it get more or less I/O time?

Apart from that, "best-effort" and "realtime" support priority levels and the default priority level is 4 (highest=0, lowest=7). Maybe it would be a good idea to lower our priority level to 5. But then again: does it really matter?

aaronjamt commented 4 months ago

I think this sounds like a great idea -- this is something I had intended to do pretty early on and simply fell off my plate. Adding the capability should be fairly straightforward.

My leaning is the same of yours re: exposing a simple toggle to deprioritize backup operation IO. I wonder whether it even makes much sense to worry about nice on the CPU side of things. Perhaps an enum?

  • BACKGROUND_ONLY - e.g. ionice -c2 nice -n19 ...

  • LOW_PRIORITY_IO - e.g. ionice -c2 ...

  • DEFAULT - e.g. no special priority

wdyt? Are there options I'm missing?

Adding my $0.02 since I'm also interested in this functionality: I think a single enum could work, but might be a bit limiting. Maybe have a Disk I/O Priority enum with High Priority (1), Normal (2), and When Idle (3) options (since None=0 is the same as Best Effort=2 on modern systems), and a Compute Priority (probably needs a better name) enum with at least low/medium/high options? Alternatively, the niceness could be set to -19/0/20 based on the Disk I/O Priority when a checkbox is enabled (which would be default), then when unchecked, there could be a field to just enter the niceness value directly?

Edit to add:

When looking at the manpage of ionice I didn't really understand what the difference between the class "none" and "best-effort" is. It didn't make a lot of sense to me that a process would be assigned the class "none" per default. What's the impact then if it gets re-classed as "best-effort"? Will it get more or less I/O time?

From my understanding, None == Best Effort, i.e. they are both the same. I believe there may have been some difference in the past, but they're effectively the same option nowadays AFAIK.

Edit 2: One other option I just thought of that could be a stopgap while the details of this are worked out: an option (I'm thinking similar to the Backup Flags one, or maybe even integrated into the Hooks feature) to add some form of "wrapper script". Then, anyone trying to do this before a proper solution is ready could add a script like:

#!/bin/sh
ionice -c2 nice -n19 "$@"
exit $?
garethgeorge commented 4 months ago

Implemented a pair of enums in https://github.com/garethgeorge/backrest/pull/309 , it should also be a pretty easy extension to support a wrapper script in general (and I can see that this solves some generic problems! e.g. mount / unmount a volume before / after commands perhaps?). This is something that can perhaps be done in a followup.