hangc0276 opened a new pull request, #4732:
URL: https://github.com/apache/bookkeeper/pull/4732

   ### Motivation
   
     `EntryLocationIndex.getLastEntryInLedgerInternal()` calls 
`locationsDb.getFloor()` on every invocation, which is an expensive RocksDB 
seek operation. When a large number of ledgers query their last entry 
concurrently — for example, during a Pulsar broker failover where thousands of 
topics are loaded by another broker and send get-LAC requests — this causes 
severe CPU saturation on the bookie.
                                                                                
                                                                                
                                              
     In a production Pulsar cluster with 3000+ topics and a bookie configured 
with 1 CPU, a single broker OOM event triggered massive concurrent `getFloor()` 
calls that throttled the bookie CPU for over 1 hour.
                                                                                
                                                                                
                                              
     The existing `WriteCache` already caches last entry IDs for recent 
unflushed entries, but once entries are flushed to RocksDB, every 
`getLastEntryInLedger()` call falls through to the database with no caching 
layer.
                                                                                
                                                                                
                                              
    ### Changes                                                
   
     Add a bounded in-memory `ConcurrentLongLongHashMap` cache in 
`EntryLocationIndex` that maps `ledgerId → lastEntryId`:                        
                                                            
      
     - **Read path (`getLastEntryInLedgerInternal`)**: Check the cache before 
calling `getFloor()`. On cache hit, return immediately without touching 
RocksDB. On cache miss, populate the cache after a      
     successful `getFloor()` lookup.                           
     - **Write path (`addLocation`)**: Eagerly update the cache when a newer 
entry is added, so the cache stays current even with interleaved reads and 
writes.                                               
     - **Delete path (`delete`)**: Remove the ledger from the cache.            
                                                                                
                                              
     - **Bounded size**: Configurable via `dbStorage_lastEntryCacheMaxSize` 
(default: 10,000). When the cache exceeds this limit and a new ledger needs to 
be inserted, the cache is cleared and repopulates  
     naturally with hot ledgers.                                                
                                                                                
                                              
                                                                                
                                                                                
                                              
     Using `ConcurrentLongLongHashMap` (lock-striped open hash map with 
primitive long keys/values) ensures minimal overhead on the write-hot path — no 
boxing, no LRU bookkeeping, no timestamp computation  
     per update.                                               
                                                                                
                                                                                
                                              
    ### Test plan                                              
   
     - [x] Added `testGetLastEntryInLedgerCache` covering cache hit, update on 
new entry, and invalidation on delete                                           
                                               
     - [x] All existing `EntryLocationIndexTest` tests pass
   
   
   
   


-- 
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]

Reply via email to