- CACHE_KV_IMPLEMENTATION.md: 구현 상세 문서 - docs/cache-kv-usage.md: 사용 가이드 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
175 lines
4.3 KiB
Markdown
175 lines
4.3 KiB
Markdown
# Cache Service - KV Index Usage Guide
|
|
|
|
## Quick Start
|
|
|
|
### Initialization
|
|
|
|
**With KV Index (Recommended):**
|
|
```typescript
|
|
import { CacheService } from './services/cache';
|
|
import { CACHE_TTL } from './constants';
|
|
|
|
const cache = new CacheService(CACHE_TTL.INSTANCES, env.RATE_LIMIT_KV);
|
|
```
|
|
|
|
**Without KV Index (Backward Compatible):**
|
|
```typescript
|
|
const cache = new CacheService(CACHE_TTL.INSTANCES);
|
|
```
|
|
|
|
## Common Operations
|
|
|
|
### Pattern-Based Invalidation
|
|
|
|
```typescript
|
|
// Invalidate all instance caches
|
|
const count = await cache.invalidatePattern('*instances*');
|
|
console.log(`Invalidated ${count} entries`);
|
|
|
|
// Invalidate specific provider caches
|
|
await cache.invalidatePattern('*provider=linode*');
|
|
|
|
// Invalidate pricing caches
|
|
await cache.invalidatePattern('*pricing*');
|
|
|
|
// Invalidate with exact pattern
|
|
await cache.invalidatePattern('https://cache.internal/instances?provider=vultr*');
|
|
```
|
|
|
|
### Clear All Caches
|
|
|
|
```typescript
|
|
// Clear all cache entries
|
|
const totalCleared = await cache.clearAll();
|
|
|
|
// Clear with prefix filter
|
|
const instancesCleared = await cache.clearAll('https://cache.internal/instances');
|
|
```
|
|
|
|
### Cache Statistics
|
|
|
|
```typescript
|
|
const stats = await cache.getStats();
|
|
|
|
if (stats.supported) {
|
|
console.log(`Cache has ${stats.indexed_keys} entries`);
|
|
} else {
|
|
console.log('KV index not available');
|
|
}
|
|
```
|
|
|
|
## Use Cases
|
|
|
|
### After Data Sync
|
|
|
|
```typescript
|
|
// Clear all cached instance data after sync
|
|
const invalidated = await cache.invalidatePattern('*instances*');
|
|
logger.info(`Invalidated ${invalidated} instance cache entries after sync`);
|
|
```
|
|
|
|
### Provider-Specific Updates
|
|
|
|
```typescript
|
|
// Update only Linode data, invalidate Linode caches
|
|
await syncLinodeData();
|
|
await cache.invalidatePattern('*provider=linode*');
|
|
```
|
|
|
|
### Cache Cleanup
|
|
|
|
```typescript
|
|
// Daily cache cleanup (optional, caches auto-expire)
|
|
const cleared = await cache.clearAll();
|
|
logger.info(`Cache cleanup: ${cleared} entries cleared`);
|
|
```
|
|
|
|
## Pattern Syntax
|
|
|
|
**Wildcards:**
|
|
- `*` - Matches any characters
|
|
- Case-insensitive by default
|
|
|
|
**Examples:**
|
|
```typescript
|
|
// Match all
|
|
'*'
|
|
|
|
// Match endpoint
|
|
'*instances*'
|
|
'*pricing*'
|
|
|
|
// Match specific parameter
|
|
'*provider=linode*'
|
|
'*region_code=us-east*'
|
|
|
|
// Match exact URL
|
|
'https://cache.internal/instances?provider=linode'
|
|
|
|
// Match with prefix
|
|
'https://cache.internal/instances*'
|
|
```
|
|
|
|
## Performance
|
|
|
|
**Operation Costs:**
|
|
- `invalidatePattern()`: 1 KV list + N cache deletes + N KV deletes
|
|
- `clearAll()`: 1 KV list + N cache deletes + N KV deletes
|
|
- `getStats()`: 1 KV list
|
|
|
|
**KV List Performance:**
|
|
- ~100ms for <1000 keys
|
|
- Pagination handled automatically
|
|
- Results cached during operation
|
|
|
|
## Error Handling
|
|
|
|
All KV operations use graceful degradation:
|
|
|
|
```typescript
|
|
// KV failures don't break cache operations
|
|
await cache.set(key, data); // Succeeds even if KV registration fails
|
|
await cache.delete(key); // Succeeds even if KV unregistration fails
|
|
|
|
// Pattern operations return 0 on KV failures
|
|
const count = await cache.invalidatePattern('*pattern*');
|
|
// Returns 0 if KV list fails, logs error
|
|
```
|
|
|
|
## Monitoring
|
|
|
|
**Log Levels:**
|
|
- `DEBUG`: Cache hits/misses, KV operations
|
|
- `INFO`: Pattern invalidation results, clear operations
|
|
- `WARN`: KV not available, unsupported operations
|
|
- `ERROR`: KV failures (non-blocking)
|
|
|
|
**Key Metrics:**
|
|
```typescript
|
|
const stats = await cache.getStats();
|
|
// { supported: true, indexed_keys: 42 }
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Enable KV Index in Production**: Pass `env.RATE_LIMIT_KV` for full functionality
|
|
2. **Use Pattern Invalidation**: Prefer `invalidatePattern()` over individual `delete()` calls
|
|
3. **Monitor Stats**: Use `getStats()` to track cache size
|
|
4. **Prefix Organization**: Use consistent URL prefixes for easy filtering
|
|
5. **Handle Failures**: Always check return values from invalidation operations
|
|
|
|
## Limitations
|
|
|
|
- **KV Eventual Consistency**: Recent writes may not appear immediately in list operations
|
|
- **Pattern Matching**: Done in-memory after KV list (not server-side)
|
|
- **Large Caches**: >1000 keys may have higher latency for pattern operations
|
|
- **No Dedicated Namespace**: Currently reuses RATE_LIMIT_KV (future: add CACHE_INDEX_KV)
|
|
|
|
## Future Enhancements
|
|
|
|
- Dedicated `CACHE_INDEX_KV` namespace
|
|
- Server-side pattern filtering
|
|
- Batch invalidation optimization
|
|
- Cache warming strategies
|
|
- Advanced statistics (hit rate, size, etc.)
|