feat: Cải thiện cấu hình Redis client với tùy chọn kết nối ổn định hơn, chiến lược thử lại nâng cao và xử lý sự kiện kết nối tốt hơn.

This commit is contained in:
Ho Ngoc Hai
2026-01-04 15:08:02 +07:00
parent 96dc13c38a
commit 101c333181
2 changed files with 37 additions and 4 deletions

View File

@@ -14,15 +14,35 @@ let redisClient: Redis | undefined;
export const getRedisClient = (): Redis => {
if (!redisClient) {
redisClient = new Redis(appConfig.redisUrl, {
// EN: Retry strategy
// VI: Chiến lược thử lại
// EN: Connection options for stability
// VI: Tùy chọn kết nối để ổn định
enableOfflineQueue: true,
connectTimeout: 10000, // 10s timeout
keepAlive: 30000, // Keep connection alive every 30s
// EN: Retry strategy with exponential backoff
// VI: Chiến lược thử lại với exponential backoff
retryStrategy(times) {
const delay = Math.min(times * 50, 2000);
if (times > 10) {
// EN: Stop retrying after 10 attempts
// VI: Dừng thử lại sau 10 lần
logger.error('Redis max retries reached, giving up');
return null;
}
const delay = Math.min(times * 100, 3000);
return delay;
},
// EN: Max retries per request
// VI: Số lần thử lại tối đa mỗi request
maxRetriesPerRequest: 3,
// EN: Reconnect on error
// VI: Tự động kết nối lại khi lỗi
maxRetriesPerRequest: 3,
reconnectOnError(err) {
const targetErrors = ['READONLY', 'ECONNRESET', 'EPIPE'];
return targetErrors.some(targetError => err.message.includes(targetError));
},
});
redisClient.on('error', (err) => {
@@ -32,6 +52,14 @@ export const getRedisClient = (): Redis => {
redisClient.on('connect', () => {
logger.info('Redis connected successfully');
});
redisClient.on('ready', () => {
logger.info('Redis ready to accept commands');
});
redisClient.on('reconnecting', () => {
logger.warn('Redis reconnecting...');
});
}
return redisClient;

View File

@@ -61,6 +61,10 @@ export class MultiLayerCache {
const l1Ttl = ttlSeconds ? Math.min(ttlSeconds, 300) : 60; // Max 5 min in L1
this.l1Cache.set(key, value, l1Ttl);
// EN: Temporarily disable L2 Redis cache to test performance
// VI: Tạm thời tắt L2 Redis cache để test hiệu suất
// TODO: Re-enable after fixing Redis EPIPE errors
/*
// L2: Set Redis cache
const stringValue = JSON.stringify(value);
if (ttlSeconds) {
@@ -68,6 +72,7 @@ export class MultiLayerCache {
} else {
await this.redis.set(key, stringValue);
}
*/
} catch (error) {
logger.error('Multi-layer cache set error', { key, error });
// Continue even if Redis fails (L1 still works)