rocksdb/cache
Peter Dillinger b34cef57b7 Support pro-actively erasing obsolete block cache entries (#12694)
Summary:
Currently, when files become obsolete, the block cache entries associated with them just age out naturally. With pure LRU, this is not too bad, as once you "use" enough cache entries to (re-)fill the cache, you are guranteed to have purged the obsolete entries. However, HyperClockCache is a counting clock cache with a somewhat longer memory, so could be more negatively impacted by previously-hot cache entries becoming obsolete, and taking longer to age out than newer single-hit entries.

Part of the reason we still have this natural aging-out is that there's almost no connection between block cache entries and the file they are associated with. Everything is hashed into the same pool(s) of entries with nothing like a secondary index based on file. Keeping track of such an index could be expensive.

This change adds a new, mutable CF option `uncache_aggressiveness` for erasing obsolete block cache entries. The process can be speculative, lossy, or unproductive because not all potential block cache entries associated with files will be resident in memory, and attempting to remove them all could be wasted CPU time. Rather than a simple on/off switch, `uncache_aggressiveness` basically tells RocksDB how much CPU you're willing to burn trying to purge obsolete block cache entries. When such efforts are not sufficiently productive for a file, we stop and move on.

The option is in ColumnFamilyOptions so that it is dynamically changeable for already-open files, and customizeable by CF.

Note that this block cache removal happens as part of the process of purging obsolete files, which is often in a background thread (depending on `background_purge_on_iterator_cleanup` and `avoid_unnecessary_blocking_io` options) rather than along CPU critical paths.

Notable auxiliary code details:
* Possibly fixing some issues with trivial moves with `only_delete_metadata`: unnecessary TableCache::Evict in that case and missing from the ObsoleteFileInfo move operator. (Not able to reproduce an current failure.)
* Remove suspicious TableCache::Erase() from VersionSet::AddObsoleteBlobFile() (TODO follow-up item)

Marked EXPERIMENTAL until more thorough validation is complete.

Direct stats of this functionality are omitted because they could be misleading. Block cache hit rate is a better indicator of benefit, and CPU profiling a better indicator of cost.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12694

Test Plan:
* Unit tests added, including refactoring an existing test to make better use of parameterized tests.
* Added to crash test.
* Performance, sample command:
```
for I in `seq 1 10`; do for UA in 300; do for CT in lru_cache fixed_hyper_clock_cache auto_hyper_clock_cache; do rm -rf /dev/shm/test3; TEST_TMPDIR=/dev/shm/test3 /usr/bin/time ./db_bench -benchmarks=readwhilewriting -num=13000000 -read_random_exp_range=6 -write_buffer_size=10000000 -bloom_bits=10 -cache_type=$CT -cache_size=390000000 -cache_index_and_filter_blocks=1 -disable_wal=1 -duration=60 -statistics -uncache_aggressiveness=$UA 2>&1 | grep -E 'micros/op|rocksdb.block.cache.data.(hit|miss)|rocksdb.number.keys.(read|written)|maxresident' | awk '/rocksdb.block.cache.data.miss/ { miss = $4 } /rocksdb.block.cache.data.hit/ { hit = $4 } { print } END { print "hit rate = " ((hit * 1.0) / (miss + hit)) }' | tee -a results-$CT-$UA; done; done; done
```

Averaging 10 runs each case, block cache data block hit rates

```
lru_cache
UA=0   -> hit rate = 0.327, ops/s = 87668, user CPU sec = 139.0
UA=300 -> hit rate = 0.336, ops/s = 87960, user CPU sec = 139.0

fixed_hyper_clock_cache
UA=0   -> hit rate = 0.336, ops/s = 100069, user CPU sec = 139.9
UA=300 -> hit rate = 0.343, ops/s = 100104, user CPU sec = 140.2

auto_hyper_clock_cache
UA=0   -> hit rate = 0.336, ops/s = 97580, user CPU sec = 140.5
UA=300 -> hit rate = 0.345, ops/s = 97972, user CPU sec = 139.8
```

Conclusion: up to roughly 1 percentage point of improved block cache hit rate, likely leading to overall improved efficiency (because the foreground CPU cost of cache misses likely outweighs the background CPU cost of erasure, let alone I/O savings).

Reviewed By: ajkr

Differential Revision: D57932442

Pulled By: pdillinger

fbshipit-source-id: 84a243ca5f965f731f346a4853009780a904af6c
2024-06-07 08:57:11 -07:00
..
cache.cc Support compressed and local flash secondary cache stacking (#11812) 2023-09-21 20:30:53 -07:00
cache_bench.cc Add (& fix) some simple source code checks (#8821) 2021-09-07 21:19:27 -07:00
cache_bench_tool.cc Run internal cpp modernizer on RocksDB repo (#12398) 2024-03-04 10:08:32 -08:00
cache_entry_roles.cc Major Cache refactoring, CPU efficiency improvement (#10975) 2023-01-11 14:20:40 -08:00
cache_entry_roles.h Major Cache refactoring, CPU efficiency improvement (#10975) 2023-01-11 14:20:40 -08:00
cache_entry_stats.h Simplify tracking entries already in SecondaryCache (#11299) 2023-03-15 17:51:44 -07:00
cache_helpers.cc Support compressed and local flash secondary cache stacking (#11812) 2023-09-21 20:30:53 -07:00
cache_helpers.h Put Cache and CacheWrapper in new public header (#11192) 2023-02-09 12:12:02 -08:00
cache_key.cc Put Cache and CacheWrapper in new public header (#11192) 2023-02-09 12:12:02 -08:00
cache_key.h Derive cache keys from SST unique IDs (#10394) 2022-08-12 13:49:49 -07:00
cache_reservation_manager.cc Simplify tracking entries already in SecondaryCache (#11299) 2023-03-15 17:51:44 -07:00
cache_reservation_manager.h Fix updating the capacity of a tiered cache (#11873) 2023-09-22 18:07:46 -07:00
cache_reservation_manager_test.cc Remove extra semi colon from icsp/lib/logging/IcspLogRpcMessage.cpp 2024-03-31 10:26:34 -07:00
cache_test.cc Support pro-actively erasing obsolete block cache entries (#12694) 2024-06-07 08:57:11 -07:00
charged_cache.cc Support compressed and local flash secondary cache stacking (#11812) 2023-09-21 20:30:53 -07:00
charged_cache.h Support compressed and local flash secondary cache stacking (#11812) 2023-09-21 20:30:53 -07:00
clock_cache.cc Prefer static_cast in place of most reinterpret_cast (#12308) 2024-02-07 10:44:11 -08:00
clock_cache.h Prefer static_cast in place of most reinterpret_cast (#12308) 2024-02-07 10:44:11 -08:00
compressed_secondary_cache.cc Run internal cpp modernizer on RocksDB repo (#12398) 2024-03-04 10:08:32 -08:00
compressed_secondary_cache.h Add some compressed and tiered secondary cache stats (#12150) 2023-12-15 11:34:08 -08:00
compressed_secondary_cache_test.cc Run internal cpp modernizer on RocksDB repo (#12398) 2024-03-04 10:08:32 -08:00
lru_cache.cc Fix a bug in LRUCacheShard::LRU_Insert (#12429) 2024-03-14 14:58:30 -07:00
lru_cache.h Prefer static_cast in place of most reinterpret_cast (#12308) 2024-02-07 10:44:11 -08:00
lru_cache_test.cc Fix a bug in LRUCacheShard::LRU_Insert (#12429) 2024-03-14 14:58:30 -07:00
secondary_cache.cc Support compressed and local flash secondary cache stacking (#11812) 2023-09-21 20:30:53 -07:00
secondary_cache_adapter.cc Implement secondary cache admission policy to allow all evicted blocks (#12599) 2024-05-02 11:23:35 -07:00
secondary_cache_adapter.h Make CacheWithSecondaryAdapter reservation accounting more robust (#12059) 2023-11-14 16:25:52 -08:00
sharded_cache.cc Add APIs to query secondary cache capacity and usage for TieredCache (#12011) 2023-10-25 16:54:50 -07:00
sharded_cache.h Prefer static_cast in place of most reinterpret_cast (#12308) 2024-02-07 10:44:11 -08:00
tiered_secondary_cache.cc Add some compressed and tiered secondary cache stats (#12150) 2023-12-15 11:34:08 -08:00
tiered_secondary_cache.h Remove 'virtual' when implied by 'override' (#12319) 2024-01-31 13:14:42 -08:00
tiered_secondary_cache_test.cc Fix stale memory access with FSBuffer and tiered sec cache (#12712) 2024-05-30 12:33:58 -07:00
typed_cache.h Prefer static_cast in place of most reinterpret_cast (#12308) 2024-02-07 10:44:11 -08:00