- Updated skill documentation files to include structured metadata for better organization. - Enhanced bilingual descriptions and guidelines for clarity in both English and Vietnamese. - Refined sections on usage, best practices, and related skills to ensure consistency across all documentation. - Improved formatting and removed outdated references to streamline the documentation experience. - Added best practices checklists to relevant skills for better usability and adherence to standards.
12 KiB
Các Pattern Caching
Caching strategies and patterns for GoodGo microservices including multi-layer cache, Redis caching, cache key naming, TTL strategies, cache invalidation, and cache-aside patterns.
Các strategies và patterns về caching cho GoodGo microservices bao gồm multi-layer cache, Redis caching, cache key naming, TTL strategies, cache invalidation, và cache-aside patterns.
Tổng Quan
Caching is a critical performance optimization technique that stores frequently accessed data in fast-access storage. This guide covers multi-layer caching strategies, cache key naming conventions, TTL (Time To Live) strategies, cache invalidation patterns, and best practices for implementing effective caching in GoodGo microservices.
Caching là kỹ thuật tối ưu hiệu suất quan trọng lưu trữ dữ liệu thường xuyên truy cập trong storage có tốc độ truy cập nhanh. Hướng dẫn này bao gồm các strategies multi-layer caching, conventions đặt tên cache keys, TTL strategies, patterns cache invalidation, và best practices để implement caching hiệu quả trong GoodGo microservices.
Khi Nào Sử Dụng
Use caching patterns when:
- Implementing caching for frequently accessed data
- Optimizing database queries with caching
- Designing cache key naming conventions
- Setting TTL (Time To Live) strategies
- Implementing cache invalidation patterns
- Using multi-layer cache (L1: Memory, L2: Redis)
- Handling cache failures gracefully
- Improving application performance
Sử dụng caching patterns khi:
- Implement caching cho dữ liệu thường xuyên truy cập
- Optimize database queries với caching
- Thiết kế cache key naming conventions
- Thiết lập TTL strategies
- Implement cache invalidation patterns
- Sử dụng multi-layer cache (L1: Memory, L2: Redis)
- Xử lý cache failures một cách graceful
- Cải thiện hiệu suất ứng dụng
Khái Niệm Chính
Chiến Lược Cache Đa Tầng
The platform uses a two-layer cache architecture to balance speed and capacity.
Nền tảng sử dụng kiến trúc cache hai tầng để cân bằng tốc độ và dung lượng.
Cache Bộ Nhớ:
- Storage: NodeCache in-memory cache
- Tốc Độ: Very fast (< 1ms access time)
- Dung Lượng: Limited (10k keys default)
- TTL: Short (60 seconds default, max 5 minutes)
- Phạm Vi: Per-instance (not shared across instances)
- Trường Hợp Sử Dụng: Ultra-fast access for hot data
Cache Redis:
- Storage: Distributed Redis cache
- Tốc Độ: Fast (< 5ms access time)
- Dung Lượng: Large
- TTL: Longer (configurable)
- Phạm Vi: Shared across all service instances
- Trường Hợp Sử Dụng: Distributed caching, larger datasets
Luồng Cache
Request → L1 Cache → Hit? Return
↓ Miss
L2 Cache → Hit? Return + Warm L1
↓ Miss
Data Source (DB/API) → Store in L1 & L2 → Return
The cache lookup follows this flow: Check L1 first, if miss check L2, if miss fetch from source and populate both layers.
Luồng lookup cache theo trình tự: Kiểm tra L1 trước, nếu miss thì kiểm tra L2, nếu miss thì fetch từ nguồn và populate cả hai tầng.
Tham Khảo: services/iam-service/src/core/cache/multi-layer-cache.ts
Patterns
Sử Dụng Cache Service
Use the cache service wrapper for all cache operations.
Sử dụng cache service wrapper cho tất cả các thao tác cache.
import { cacheService } from '../core/cache';
// Get/set đơn giản
const cached = await cacheService.get<User>('user:123');
await cacheService.set('user:123', userData, 300); // 5 minutes TTL
// Pattern get or set (cache-aside)
const user = await cacheService.getOrSet(
'user:123',
async () => {
return await userRepository.findById('123');
},
300 // TTL in seconds
);
Tham Khảo: services/iam-service/src/core/cache/cache.service.ts
Quy Ước Đặt Tên Cache Key
Use consistent naming patterns to avoid collisions and enable pattern-based invalidation.
Sử dụng patterns đặt tên nhất quán để tránh collisions và cho phép invalidation dựa trên pattern.
Các Patterns:
// Pattern: {entity}:{identifier}
'user:123'
'user:email:user@example.com'
'user:123:permissions'
'user:123:roles'
// Pattern: {entity}:{identifier}:{sub-resource}
'session:abc123'
'permission:perm_123'
'role:role_123'
Bộ Tạo Key:
cacheService.keys = {
user: (userId: string) => `user:${userId}`,
userPermissions: (userId: string) => `user:${userId}:permissions`,
userRoles: (userId: string) => `user:${userId}:roles`,
token: (token: string) => `token:${token}`,
session: (sessionId: string) => `session:${sessionId}`,
};
Pattern Cache-Aside
The most common caching pattern - check cache first, fetch if miss, store in cache.
Pattern caching phổ biến nhất - kiểm tra cache trước, fetch nếu miss, lưu vào cache.
async getUserPermissions(userId: string): Promise<string[]> {
const cacheKey = cacheService.keys.userPermissions(userId);
// Thử cache trước
const cached = await cacheService.get<string[]>(cacheKey);
if (cached) {
return cached;
}
// Cache miss - fetch từ nguồn
const permissions = await calculatePermissions(userId);
// Lưu vào cache
await cacheService.set(cacheKey, permissions, 300); // 5 min TTL
return permissions;
}
Tham Khảo: services/iam-service/src/modules/rbac/rbac.service.ts
Pattern Get hoặc Set
Simplified cache-aside pattern that automatically handles cache miss scenarios.
Pattern cache-aside đơn giản hóa tự động xử lý các trường hợp cache miss.
const permissions = await cacheService.getOrSet(
cacheService.keys.userPermissions(userId),
async () => {
// Function này chỉ chạy khi cache miss
return await calculatePermissions(userId);
},
300 // TTL
);
Chiến Lược TTL
Choose TTL (Time To Live) based on data characteristics and change frequency.
Chọn TTL (Time To Live) dựa trên đặc điểm dữ liệu và tần suất thay đổi.
Short TTL (60-300s) / TTL Ngắn: Frequently changing data / Dữ liệu thay đổi thường xuyên
- User permissions (300s)
- Session data (varies)
- Real-time statistics / Thống kê thời gian thực
Medium TTL (300-1800s) / TTL Trung Bình: Moderately changing data / Dữ liệu thay đổi vừa phải
- User profiles (600s)
- Organization data (900s)
- Configuration (1800s)
Long TTL (1800-3600s) / TTL Dài: Rarely changing data / Dữ liệu hiếm khi thay đổi
- Static configurations (3600s)
- Reference data (7200s)
No TTL / Không TTL: Very stable data (use with caution) / Dữ liệu rất ổn định (sử dụng cẩn thận)
- Rarely use - prefer long TTL instead / Hiếm khi sử dụng - nên dùng TTL dài
Làm Mất Hiệu Lực Cache
Invalidate cache when data changes to prevent serving stale data.
Làm mất hiệu lực cache khi dữ liệu thay đổi để tránh phục vụ dữ liệu cũ.
// Làm mất hiệu lực key đơn
await cacheService.del(cacheService.keys.user(userId));
await cacheService.del(cacheService.keys.userPermissions(userId));
// Làm mất hiệu lực dựa trên pattern
await cacheService.invalidatePattern('user:123:*');
// Nhiều keys
await cacheService.delMany([
cacheService.keys.user(userId),
cacheService.keys.userPermissions(userId),
cacheService.keys.userRoles(userId),
]);
Làm Nóng Cache
Pre-populate cache with frequently accessed data to improve initial performance.
Pre-populate cache với dữ liệu thường xuyên truy cập để cải thiện hiệu suất ban đầu.
async warmCache() {
const activeUsers = await userRepository.findActiveUsers();
for (const user of activeUsers) {
// Pre-cache dữ liệu user
await cacheService.set(
cacheService.keys.user(user.id),
user,
600
);
// Pre-cache permissions
const permissions = await calculatePermissions(user.id);
await cacheService.set(
cacheService.keys.userPermissions(user.id),
permissions,
300
);
}
}
Xử Lý Lỗi
Cache failures should not break the application - always fallback to data source.
Cache failures không nên làm hỏng ứng dụng - luôn fallback về data source.
async getWithCache(key: string): Promise<Data | null> {
try {
// Thử cache trước
const cached = await cacheService.get<Data>(key);
if (cached) return cached;
} catch (error) {
// Log nhưng tiếp tục - fallback về nguồn
logger.warn('Cache get failed, falling back to source', { key, error });
}
// Fallback về data source
return await fetchFromSource();
}
Thực Hành Tốt Nhất
- Cache Keys / Cache Keys: Sử dụng naming conventions nhất quán
- TTL Selection / Chọn TTL: Chọn TTL dựa trên tần suất thay đổi dữ liệu
- Invalidation / Làm Mất Hiệu Lực: Làm mất hiệu lực cache khi dữ liệu thay đổi
- Error Handling / Xử Lý Lỗi: Không để cache failures làm hỏng ứng dụng
- Cache-Aside / Cache-Aside: Sử dụng cache-aside pattern cho hầu hết các trường hợp
- Avoid Over-Caching / Tránh Cache Quá Nhiều: Không cache dữ liệu thay đổi quá thường xuyên
- Monitor Hit Rates / Giám Sát Tỷ Lệ Hit: Theo dõi cache hit rates để optimize TTL
- Warm Cache / Làm Nóng Cache: Pre-populate cache cho critical data
- Use Multi-Layer / Sử Dụng Đa Tầng: Tận dụng cả L1 và L2 cache
- Serialize Properly / Serialize Đúng Cách: Đảm bảo dữ liệu có thể JSON serialize
Lỗi Thường Gặp
- Cache Key Collisions / Va Chạm Cache Key: Sử dụng keys chung chung dẫn đến va chạm
- Stale Data / Dữ Liệu Cũ: Không invalidate cache khi dữ liệu thay đổi
- Too Short TTL / TTL Quá Ngắn: Đặt TTL quá ngắn, làm mất lợi ích của cache
- Too Long TTL / TTL Quá Dài: Đặt TTL quá dài, phục vụ dữ liệu cũ
- No Error Handling / Không Xử Lý Lỗi: Để cache errors làm hỏng ứng dụng
- Caching Everything / Cache Tất Cả: Cache dữ liệu không có lợi từ caching
- Not Warming Cache / Không Làm Nóng Cache: Không pre-populate critical cache data
- Ignoring Hit Rates / Bỏ Qua Tỷ Lệ Hit: Không monitor cache performance
Xử Lý Sự Cố
Tỷ Lệ Hit Thấp
Problem / Vấn Đề: Cache hit rate thấp, cache không hiệu quả
Solution / Giải Pháp:
- Review TTL values - có thể quá ngắn
- Check cache key patterns - đảm bảo sử dụng nhất quán
- Verify cache invalidation không quá aggressive
- Monitor dữ liệu nào đang được cache
Vấn Đề Dữ Liệu Cũ
Problem / Vấn Đề: Phục vụ dữ liệu cũ từ cache
Solution / Giải Pháp:
- Review TTL values - có thể quá dài
- Đảm bảo cache invalidation khi dữ liệu cập nhật
- Sử dụng TTL ngắn hơn cho dữ liệu thay đổi thường xuyên
- Implement cache versioning nếu cần
Vấn Đề Hiệu Suất Cache
Problem / Vấn Đề: Cache operations chậm
Solution / Giải Pháp:
- Kiểm tra Redis connection và network latency
- Monitor Redis memory usage
- Review cache key patterns để hiệu quả
- Xem xét L1 cache hit rate (nên cao)
Tài Nguyên
- Multi-Layer Cache - Multi-layer cache implementation
- Cache Service - Cache service wrapper
- Cache Usage Example - Real-world cache usage example
- Redis Configuration - Redis configuration