|
| 1 | +# Databend Common Meta Cache |
| 2 | + |
| 3 | +A distributed cache implementation based on meta-service, providing reliable resource management and data synchronization across distributed systems. |
| 4 | + |
| 5 | + |
| 6 | +## Features |
| 7 | + |
| 8 | +- **Automatic Synchronization**: Background watcher task keeps local cache in sync with meta-service |
| 9 | +- **Concurrency Control**: Two-level concurrency control mechanism for safe access |
| 10 | +- **Event-based Updates**: Real-time updates through meta-service watch API |
| 11 | +- **Safe Reconnection**: Automatic recovery from connection failures with state consistency |
| 12 | + |
| 13 | +## Key Components |
| 14 | + |
| 15 | +### Cache Structure |
| 16 | + |
| 17 | +```text |
| 18 | +<prefix>/foo |
| 19 | +<prefix>/.. |
| 20 | +<prefix>/.. |
| 21 | +``` |
| 22 | + |
| 23 | +- `<prefix>`: User-defined string to identify a cache instance |
| 24 | + |
| 25 | +### Main Types |
| 26 | + |
| 27 | +- `Cache`: The main entry point for cache operations |
| 28 | + - Provides safe access to cached data |
| 29 | +- `CacheData`: Internal data structure holding the cached values |
| 30 | +- `EventWatcher`: Background task that watches for changes in meta-service |
| 31 | + - Handles synchronization with meta-service |
| 32 | + |
| 33 | +## Usage |
| 34 | + |
| 35 | +```rust |
| 36 | +let client = MetaGrpcClient::try_create(/*..*/); |
| 37 | +let cache = Cache::new( |
| 38 | + client, |
| 39 | + "your/cache/key/space/in/meta/service", |
| 40 | + "your-app-name-for-logging", |
| 41 | +).await; |
| 42 | + |
| 43 | +// Access cached data |
| 44 | +cache.try_access(|c: &CacheData| { |
| 45 | + println!("last-seq:{}", c.last_seq); |
| 46 | + println!("all data: {:?}", c.data); |
| 47 | +}).await?; |
| 48 | + |
| 49 | +// Get a specific value |
| 50 | +let value = cache.try_get("key").await?; |
| 51 | + |
| 52 | +// List all entries under a prefix |
| 53 | +let entries = cache.try_list_dir("prefix").await?; |
| 54 | +``` |
| 55 | + |
| 56 | +## Concurrency Control |
| 57 | + |
| 58 | +The cache employs a two-level concurrency control mechanism: |
| 59 | + |
| 60 | +1. **Internal Lock (Mutex)**: Protects concurrent access between user operations and the background cache updater. This lock is held briefly during each operation. |
| 61 | + |
| 62 | +2. **External Lock (Method Design)**: Public methods require `&mut self` even for read-only operations. This prevents concurrent access to the cache instance from multiple call sites. External synchronization should be implemented by the caller if needed. |
| 63 | + |
| 64 | +This design intentionally separates concerns: |
| 65 | +- The internal lock handles short-term, fine-grained synchronization with the updater |
| 66 | +- The external lock requirement (`&mut self`) enables longer-duration access patterns without blocking the background updater unnecessarily |
| 67 | + |
| 68 | +Note that despite requiring `&mut self`, all operations are logically read-only with respect to the cache's public API. |
| 69 | + |
| 70 | +## Initialization Process |
| 71 | + |
| 72 | +When a `Cache` is created, it goes through the following steps: |
| 73 | + |
| 74 | +1. Creates a new instance with specified prefix and context |
| 75 | +2. Spawns a background task to watch for key-value changes |
| 76 | +3. Establishes a watch stream to meta-service |
| 77 | +4. Fetches and processes initial data |
| 78 | +5. Waits for the cache to be fully initialized before returning |
| 79 | +6. Maintains continuous synchronization |
| 80 | + |
| 81 | +The initialization is complete only when the cache has received a full copy of the data from meta-service, ensuring users see a consistent view of the data. |
| 82 | + |
| 83 | +## Error Handling |
| 84 | + |
| 85 | +The cache implements robust error handling: |
| 86 | + |
| 87 | +- Connection failures are automatically retried in the background |
| 88 | +- Background watcher task automatically recovers from errors |
| 89 | +- Users are shielded from transient errors through the abstraction |
| 90 | +- The cache ensures data consistency by tracking sequence numbers |
| 91 | + |
| 92 | +## License |
| 93 | + |
| 94 | +This project is licensed under the Apache License 2.0 - see the LICENSE file for details. |
0 commit comments