Skip to content

Commit fea6b19

Browse files
committed
cachedb_perf: new high-performance local cache backend (perf://)
A from-scratch cachedb backend for large, high-churn local caches, selected by URL scheme (perf://), as a drop-in alternative to cachedb_local. It implements the same cachedb_funcs vtable, so any module taking a cachedb_url works unchanged. Motivation: cachedb_local sizes its hash table once from cache_collections and never resizes, so a large cache degrades to long lock-held chain walks (measured while benchmarking topology_hiding's th_store backend). This module keeps lookups flat as the cache grows. Core design: - 64-byte, one-cache-line buckets with 1-byte per-slot tags (SWAR scan) and a per-bucket seqlock: readers take no locks, snapshot optimistically and re-check, with a bounded retry and a lock fallback. Legal because shm is mapped once before fork and never unmapped, so a stale pointer read is bounded garbage the version re-check discards. - Slab arena: entries live in fixed-size cells in class-bound chunks that are never returned to shm; per-process bump allocation with no atomics on the fast path (byte 0 of every cell is the immutable class id). - Runtime growth: a segmented directory + linear hashing splits one bucket at a time from the single maintenance timer - buckets never move, the routing word is re-checked on a miss, and the load-factor cliff cannot form (growth_load_factor). - Native int64 counters (add/sub) accumulated under the bucket lock; a versionless TTL bump that refreshes expiry with one atomic store; an overflow side table for full buckets. - No allocator call ever happens under a bucket lock. This is also the first backend to implement the allocation-free read added in the previous commit. The two entry points share one implementation, so they cannot diverge over which record they return: the optimistic loop, the lock fallback, the re-route retry, the overflow leg and the expiry check all live in one function, which copies into the caller's buffer, and the allocating entry point is a thin wrapper that passes the per-process scratch and then copies into pkg. get() and get_counter() keep the documented cachedb behaviour byte for byte - in particular get_counter() still returns only {-2,-1,0} and never the new too-small code. Measured with the cachedb-vtable benchmark, 50 000 entries, 200-byte values, 100% reads, one worker, alternating runs: 397.7 ns/op via get() against 290.1 ns/op via get_buf() at the median, the new path faster in every pair. Operability and durability: - Per-collection expiry sweep (min-expires hints), per-process sharded statistics, and a huge-page arena (hugetlb -> THP -> MADV_COLLAPSE -> 4K, detected by trying; arena_hugepage_mb), measured +7-13%. - Introspection MI (all lock-free): perf_keys, perf_scan (cursored, Redis SCAN semantics), perf_dump, perf_get, perf_set, perf_ttl, perf_del, plus perf_stats and perf_stats_reset; glob script functions perf_del/ perf_mget/perf_mget_json. perf_stats reports hit rate, expired and destroyed counts, and when each collection last synced. - Observability events: E_CACHEDB_PERF_EXPIRED / NOMEM / GROWN / MEM_DEGRADED, each gated by evi_probe_event so a subscriber-less cluster pays nothing, none on the hot path. - DB persistence: whole-collection save/load to any db_* backend (perf_save/perf_load, db_mode startup-load / shutdown-save), TTLs kept as absolute wall-clock time so they survive a restart. A save/load is a full blocking snapshot written in one transaction - a maintenance/bootstrap operation, not per-request - and rows that no longer exist in memory are dropped at load rather than resurrected. - Cluster sync: perf_sync saves a collection then signals peers over clusterer to reload it from the shared DB (one message per sync, not per operation), raising E_CACHEDB_PERF_SYNCED. A pull-from-DB refresh for single-writer/read-replica topologies - deliberately not per-operation replication, which would tax the lock-free path this module exists for. v1 is single-node in-memory with optional db_* persistence and the DB- backed cluster refresh; per-operation replication is out of scope.
1 parent 3232f3f commit fea6b19

31 files changed

Lines changed: 9889 additions & 0 deletions

‎modules/cachedb_perf/Makefile‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# cachedb_perf module
2+
#
3+
# WARNING: do not run this directly, it should be run by the master Makefile
4+
5+
include ../../Makefile.defs
6+
auto_gen=
7+
NAME=cachedb_perf.so
8+
9+
include ../../Makefile.modules

0 commit comments

Comments
 (0)