Files
pos-system/docs/vi/skills/caching-patterns.md
Ho Ngoc Hai 9b6c585f57 Enhance documentation structure and improve bilingual support across skills
- 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.
2026-01-01 07:35:44 +07:00

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

  1. Cache Keys / Cache Keys: Sử dụng naming conventions nhất quán
  2. TTL Selection / Chọn TTL: Chọn TTL dựa trên tần suất thay đổi dữ liệu
  3. Invalidation / Làm Mất Hiệu Lực: Làm mất hiệu lực cache khi dữ liệu thay đổi
  4. Error Handling / Xử Lý Lỗi: Không để cache failures làm hỏng ứng dụng
  5. Cache-Aside / Cache-Aside: Sử dụng cache-aside pattern cho hầu hết các trường hợp
  6. Avoid Over-Caching / Tránh Cache Quá Nhiều: Không cache dữ liệu thay đổi quá thường xuyên
  7. Monitor Hit Rates / Giám Sát Tỷ Lệ Hit: Theo dõi cache hit rates để optimize TTL
  8. Warm Cache / Làm Nóng Cache: Pre-populate cache cho critical data
  9. Use Multi-Layer / Sử Dụng Đa Tầng: Tận dụng cả L1 và L2 cache
  10. Serialize Properly / Serialize Đúng Cách: Đảm bảo dữ liệu có thể JSON serialize

Lỗi Thường Gặp

  1. Cache Key Collisions / Va Chạm Cache Key: Sử dụng keys chung chung dẫn đến va chạm
  2. Stale Data / Dữ Liệu Cũ: Không invalidate cache khi dữ liệu thay đổi
  3. Too Short TTL / TTL Quá Ngắn: Đặt TTL quá ngắn, làm mất lợi ích của cache
  4. Too Long TTL / TTL Quá Dài: Đặt TTL quá dài, phục vụ dữ liệu cũ
  5. No Error Handling / Không Xử Lý Lỗi: Để cache errors làm hỏng ứng dụng
  6. Caching Everything / Cache Tất Cả: Cache dữ liệu không có lợi từ caching
  7. Not Warming Cache / Không Làm Nóng Cache: Không pre-populate critical cache data
  8. 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