zhuxiangyi opened a new pull request, #67063:
URL: https://github.com/apache/doris/pull/67063

   ### What problem does this PR solve?
   
   Issue Number: close #67062
   
   Problem Summary:
   
   On a backend with several spill disks, every spill file created within a 
two-second window lands on the same disk while the others stay idle. Spill 
throughput is capped at one disk's bandwidth and that disk reaches its capacity 
limit first.
   
   The selection is deterministic *and* the input it sorts on is stale:
   
   - `_get_stores_for_spill()` sorts candidates by usage ascending, and 
`create_spill_file()` always takes `data_dirs.front()`.
   - The usage comes from `SpillDataDir::_get_disk_usage()`, which reads 
`_available_bytes`.
   - `_available_bytes` is only refreshed by `SpillDataDir::update_capacity()`, 
called from the GC thread once per `config::spill_gc_interval_ms` (2s by 
default).
   - `_spill_data_bytes`, which *is* updated on every write, does not feed into 
`_get_disk_usage()`.
   
   So nothing the manager hands out during those two seconds changes the 
ordering: every caller computes the same usage vector, sorts it the same way, 
and picks the same winner. A single spilling query creates one spill file per 
partition per pipeline task, so hundreds of calls easily fall inside one 
refresh window.
   
   This PR shuffles the head of the sorted list. Disks whose usage is within 
`USAGE_EQUIVALENCE_BAND` (2% of capacity) of the emptiest one are treated as 
equally empty and drawn from at random; a disk that is genuinely emptier by 
more than the band still wins outright, so the existing "prefer the emptiest 
disk" intent is preserved. Only ties that a stale snapshot cannot distinguish 
get spread out. The generator is `thread_local`, so concurrent callers draw 
independent permutations without contending on a shared generator.
   
   StarRocks addresses the same problem by picking a random start index and 
walking the directory list from there 
(`be/src/compute_env/spill/dir_manager.cpp`); randomizing only within the 
near-equal band keeps Doris's usage-aware preference rather than replacing it 
with plain round-robin.
   
   ### Release note
   
   Fix spill files all landing on a single disk when multiple spill disks are 
configured.
   
   ### Check List (For Author)
   
   - Test
       - [x] Unit Test
   
         Two tests in `spill_file_test.cpp`:
         - `EquallyEmptyDisksAreSelectedInVaryingOrder` — with four equally 
empty disks, 200
           draws must reach all four. The previous deterministic policy yields 
exactly one
           distinct winner, so this fails before the change. With a uniform 
draw the odds of
           missing a disk are ~1e-25, so it cannot flake.
         - `ClearlyEmptiestDiskAlwaysWins` — with one disk far emptier than the 
rest (well
           beyond the band), it must win all 50 draws. This guards the 
preference that the
           shuffle must not destroy.
   
   - Behavior changed:
       - [x] Yes.
   
         Which spill disk a given spill file lands on is no longer 
deterministic when several
         disks are equally empty. Disk preference is unchanged whenever one 
disk is more than
         2% of capacity emptier than the others. No configuration, format or 
interface change.
   
   - Does this need documentation?
       - [x] No.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to