|
| 1 | +Idle/background work classes design doc: |
| 2 | + |
| 3 | +Right now, our behaviour at idle isn't ideal, it was designed for servers that |
| 4 | +would be under sustained load, to keep pending work at a "medium" level, to |
| 5 | +let work build up so we can process it in more efficient batches, while also |
| 6 | +giving headroom for bursts in load. |
| 7 | + |
| 8 | +But for desktops or mobile - scenarios where work is less sustained and power |
| 9 | +usage is more important - we want to operate differently, with a "rush to |
| 10 | +idle" so the system can go to sleep. We don't want to be dribbling out |
| 11 | +background work while the system should be idle. |
| 12 | + |
| 13 | +The complicating factor is that there are a number of background tasks, which |
| 14 | +form a heirarchy (or a digraph, depending on how you divide it up) - one |
| 15 | +background task may generate work for another. |
| 16 | + |
| 17 | +Thus proper idle detection needs to model this heirarchy. |
| 18 | + |
| 19 | +- Foreground writes |
| 20 | +- Page cache writeback |
| 21 | +- Copygc, rebalance |
| 22 | +- Journal reclaim |
| 23 | + |
| 24 | +When we implement idle detection and rush to idle, we need to be careful not |
| 25 | +to disturb too much the existing behaviour that works reasonably well when the |
| 26 | +system is under sustained load (or perhaps improve it in the case of |
| 27 | +rebalance, which currently does not actively attempt to let work batch up). |
| 28 | + |
| 29 | +SUSTAINED LOAD REGIME |
| 30 | +--------------------- |
| 31 | + |
| 32 | +When the system is under continuous load, we want these jobs to run |
| 33 | +continuously - this is perhaps best modelled with a P/D controller, where |
| 34 | +they'll be trying to keep a target value (i.e. fragmented disk space, |
| 35 | +available journal space) roughly in the middle of some range. |
| 36 | + |
| 37 | +The goal under sustained load is to balance our ability to handle load spikes |
| 38 | +without running out of x resource (free disk space, free space in the |
| 39 | +journal), while also letting some work accumululate to be batched (or become |
| 40 | +unnecessary). |
| 41 | + |
| 42 | +For example, we don't want to run copygc too aggressively, because then it |
| 43 | +will be evacuating buckets that would have become empty (been overwritten or |
| 44 | +deleted) anyways, and we don't want to wait until we're almost out of free |
| 45 | +space because then the system will behave unpredicably - suddenly we're doing |
| 46 | +a lot more work to service each write and the system becomes much slower. |
| 47 | + |
| 48 | +IDLE REGIME |
| 49 | +----------- |
| 50 | + |
| 51 | +When the system becomes idle, we should start flushing our pending work |
| 52 | +quicker so the system can go to sleep. |
| 53 | + |
| 54 | +Note that the definition of "idle" depends on where in the heirarchy a task |
| 55 | +is - a task should start flushing work more quickly when the task above it has |
| 56 | +stopped generating new work. |
| 57 | + |
| 58 | +e.g. rebalance should start flushing more quickly when page cache writeback is |
| 59 | +idle, and journal reclaim should only start flushing more quickly when both |
| 60 | +copygc and rebalance are idle. |
| 61 | + |
| 62 | +It's important to let work accumulate when more work is still incoming and we |
| 63 | +still have room, because flushing is always more efficient if we let it batch |
| 64 | +up. New writes may overwrite data before rebalance moves it, and tasks may be |
| 65 | +generating more updates for the btree nodes that journal reclaim needs to flush. |
| 66 | + |
| 67 | +On idle, how much work we do at each interval should be proportional to the |
| 68 | +length of time we have been idle for. If we're idle only for a short duration, |
| 69 | +we shouldn't flush everything right away; the system might wake up and start |
| 70 | +generating new work soon, and flushing immediately might end up doing a lot of |
| 71 | +work that would have been unnecessary if we'd allowed things to batch more. |
| 72 | + |
| 73 | +To summarize, we will need: |
| 74 | + |
| 75 | + - A list of classes for background tasks that generate work, which will |
| 76 | + include one "foreground" class. |
| 77 | + - Tracking for each class - "Am I doing work, or have I gone to sleep?" |
| 78 | + - And each class should check the class above it when deciding how much work to issue. |
0 commit comments