Basket Service Caching
The Basket service implements a sophisticated caching strategy using Redis and the decorator pattern to achieve high performance while maintaining data consistency.Architecture
Decorator Pattern
The service uses the decorator pattern to add caching functionality without modifying the base repository implementation:- Separation of Concerns: Caching logic is separate from data access logic
- Flexibility: Easy to enable/disable caching by removing the decorator
- Testability: Each component can be tested independently
- Single Responsibility: Each class has one clear purpose
Redis Configuration
Service Registration
Redis is configured using StackExchange.Redis inProgram.cs:30-34:
Connection String
Docker Compose Configuration
In production, Redis is typically configured via Docker Compose:Repository Implementations
Base Repository
BasketRepository.cs provides the core data access logic using Marten/PostgreSQL:
Cached Repository Decorator
CachedBasketRepository.cs wraps the base repository with caching logic:
Caching Strategies
Cache-Aside Pattern (Read)
TheGetBasket operation implements the cache-aside pattern (CachedBasketRepository.cs:10-19):
- Check Cache: First attempts to retrieve from Redis
- Deserialize: If found, deserializes and returns immediately
- Database Query: If not cached, queries PostgreSQL
- Update Cache: Serializes and stores in Redis for future requests
- Return Data: Returns the basket to the caller
- First request: Full database query
- Subsequent requests: Fast Redis lookups
- Typical latency reduction: 10-100x
Write-Through Pattern (Update)
TheStoreBasket operation implements write-through caching (CachedBasketRepository.cs:21-28):
- Write to Database: First updates PostgreSQL
- Update Cache: Immediately updates Redis cache
- Return Success: Returns the stored basket
- Cache is always consistent with database
- Next read request will be fast (cached)
- No cache warm-up needed
Cache Invalidation (Delete)
TheDeleteBasket operation ensures cache consistency (CachedBasketRepository.cs:30-37):
- Delete from Database: Removes from PostgreSQL
- Invalidate Cache: Removes from Redis
- Return Success: Confirms deletion
- Always invalidate on delete operations
- Prevents serving stale data
- Maintains data consistency
Cache Key Strategy
Key Format
The service uses a simple key format:"swn"- Basket for user “swn”"john.doe"- Basket for user “john.doe”"customer123"- Basket for user “customer123”
Key Benefits
- Simple: Easy to understand and debug
- Unique: Username is unique identifier
- Direct Access: O(1) lookup complexity
- Human Readable: Easy to inspect in Redis CLI
Alternative Approaches
For more complex scenarios, consider:Serialization
JSON Serialization
The service usesSystem.Text.Json for serialization:
Serialization Considerations
Advantages of JSON:- Human-readable in Redis
- Easy to debug
- Platform-independent
- Compatible with Redis CLI tools
Cache Expiration
Current Implementation
The current implementation does not set explicit cache expiration:- Cache entries persist until explicitly deleted
- Checkout operation deletes the cache entry
- No automatic cleanup of abandoned carts
Recommended Improvements
Add sliding or absolute expiration for better cache management:Health Checks
Redis health is monitored via health checks (Program.cs:58-60):
Monitoring and Debugging
Redis CLI Commands
Useful commands for monitoring cache:Cache Hit Rate
Monitor cache effectiveness:Performance Considerations
Latency Comparison
| Operation | Database (PostgreSQL) | Cache (Redis) | Improvement |
|---|---|---|---|
| Get Basket | 10-50ms | 1-5ms | 10-50x faster |
| Store Basket | 20-100ms | 15-95ms | Slightly slower (write-through) |
| Delete Basket | 10-30ms | 8-28ms | Slightly slower (dual delete) |
Best Practices
- Cache Warm Baskets: Most accessed baskets stay in cache
- Short Serialization: Keep basket size reasonable
- Connection Pooling: Redis connections are pooled automatically
- Async Operations: All operations are fully asynchronous
- Cancellation Support: All methods support cancellation tokens
Failure Scenarios
Redis Unavailable
If Redis is down:- Health check reports unhealthy
- Cache operations throw exceptions
- Application fails to start (current implementation)
Related Topics
- Features - Basket service features
- API Reference - Complete API documentation
- Overview - Service architecture
