示例说明
缓存客户端最常见的线上问题是网络抖动后的雪崩式重连与故障转移期间的命令堆积。ioredis 的 retryStrategy 控制底层连接重连间隔并封顶,sentinelRetryStrategy 单独控制询问哨兵的节奏;maxRetriesPerRequest 与 commandTimeout 让单个命令快速失败,避免请求挂死在不可用的连接上。
技术要点
- retryStrategy 与 sentinelRetryStrategy 分层控制重连
- maxRetriesPerRequest 让命令快速失败而非排队
- enableOfflineQueue 关闭离线命令缓冲
代码解读
客户端以哨兵地址列表构造,ioredis 通过哨兵发现当前主节点;主节点切换时自动重连到新主。set 命令带 EX 选项设置 900 秒过期,演示会话缓存的典型写法。reconnecting 事件输出延迟值,便于观测重连风暴。
使用建议
commandTimeout 要大于最慢合法命令的耗时,否则会误杀慢查询。密码等敏感信息从环境变量读取,不要硬编码。哨兵数量至少三台并跨机架部署,避免脑裂。
代码示例
import Redis from 'ioredis';
const client = new Redis({
sentinels: [
{ host: '10.0.0.11', port: 26379 },
{ host: '10.0.0.12', port: 26379 },
],
name: 'mymaster',
password: process.env.REDIS_PASSWORD,
sentinelRetryStrategy: (times) => Math.min(times * 200, 5000),
retryStrategy: (times) => Math.min(times * 100, 3000),
maxRetriesPerRequest: 2,
commandTimeout: 1500,
enableOfflineQueue: false,
});
client.on('error', (err) => console.error('redis error:', err.message));
client.on('reconnecting', (delay) => console.log('reconnecting in', delay, 'ms'));
await client.set('session:42', 'active', 'EX', 900);
const state = await client.get('session:42');