本文介绍使用 Node.js 客户端通过代理模式和直连模式连接腾讯云分布式缓存数据库实例的示例。
准备工作
环境要求
Node.js 14及以上版本。
npm 或 yarn 包管理器。
安装客户端
使用 npm 安装 node-redis 客户端(推荐 4.x 及以上版本):
npm install redis
或使用 ioredis 客户端:
npm install ioredis
获取连接信息
1. 登录 分布式缓存数据库控制台。
2. 在实例列表中,单击目标实例 ID,进入实例详情页。
3. 在网络信息区域,获取实例的连接地址和端口号。
代理模式:获取 VIP 地址和端口(默认6379)。
直连模式:获取各分片节点地址和端口(默认6379)。
4. 在配置信息区域,获取实例的连接密码。代理模式与直连模式的认证方式不同:
代理模式:默认账号使用
实例 ID:密码 格式,自定义账号使用 用户名@密码 格式;免密认证实例无需密码。直连模式:复用 Redis 原生 ACL 认证机制,不支持
用户名@密码 拼接格式,支持以下两种认证方式:默认账号:仅需密码,即
AUTH password。自定义账号:需同时指定账号名与密码,即
AUTH account password。代理模式连接示例
代理模式下,客户端通过 Proxy 代理层提供的统一 VIP 地址连接实例,Proxy 自动处理请求路由和故障转移,客户端无需感知后端拓扑变化。
node-redis 基础连接示例
const { createClient } = require('redis');async function main() {// 创建客户端连接const client = createClient({url: 'redis://192.xx.xx.2:6379', // 实例 VIP 地址password: 'crs-xxxx:密码', // 默认账号密码格式:实例ID:密码socket: {connectTimeout: 2000, // 连接超时(毫秒)reconnectStrategy: (retries) => {if (retries > 10) return new Error('Max retries reached');return Math.min(retries * 200, 3000); // 重连退避策略}}});// 错误处理client.on('error', (err) => console.error('Redis Client Error:', err));client.on('connect', () => console.log('Redis connected'));client.on('reconnecting', () => console.log('Redis reconnecting...'));// 建立连接await client.connect();// 写入数据await client.set('name', '腾讯云分布式缓存数据库');// 读取数据const value = await client.get('name');console.log('get name:', value);// 设置带过期时间的 Key(EX 单位为秒)await client.set('session:user123', 'session_data', { EX: 3600 });// 哈希操作await client.hSet('user:1001', { name: '张三', age: '28' });const userInfo = await client.hGetAll('user:1001');console.log('user info:', userInfo);// 列表操作await client.lPush('queue:tasks', ['task1', 'task2', 'task3']);const task = await client.rPop('queue:tasks');console.log('dequeued task:', task);// 关闭连接await client.quit();}main().catch(console.error);
node-redis 自定义账号连接示例
const { createClient } = require('redis');async function main() {const client = createClient({url: 'redis://192.xx.xx.2:6379',password: 'myuser@MyPassword', // 代理模式自定义账号:用户名@密码整体作为密码传入,不单独设置 username(区别于直连模式 ACL 的账号名/密码分离传参)socket: {connectTimeout: 2000}});client.on('error', (err) => console.error('Redis Client Error:', err));await client.connect();await client.set('key', 'value');console.log(await client.get('key'));await client.quit();}main().catch(console.error);
ioredis 连接示例
const Redis = require('ioredis');// 创建连接(ioredis 内置连接池和自动重连机制)const redis = new Redis({host: '192.xx.xx.2', // 实例 VIP 地址port: 6379, // 实例端口password: 'crs-xxxx:密码', // 默认账号密码格式:实例ID:密码db: 0, // 数据库编号connectTimeout: 2000, // 连接超时(毫秒)commandTimeout: 2000, // 命令超时(毫秒)retryStrategy: (times) => {if (times > 10) return null; // 超过重试次数停止重连return Math.min(times * 200, 3000);},maxRetriesPerRequest: 3, // 每个请求最大重试次数enableReadyCheck: true, // 连接就绪检查lazyConnect: false // 立即建立连接});redis.on('connect', () => console.log('Redis connected'));redis.on('error', (err) => console.error('Redis error:', err));async function main() {// 写入数据await redis.set('name', '腾讯云分布式缓存数据库');// 读取数据const value = await redis.get('name');console.log('get name:', value);// 设置带过期时间的 Keyawait redis.setex('session:user123', 3600, 'session_data');// Pipeline 批量操作const pipeline = redis.pipeline();pipeline.set('key1', 'value1');pipeline.set('key2', 'value2');pipeline.set('key3', 'value3');pipeline.get('key1');pipeline.get('key2');pipeline.get('key3');const results = await pipeline.exec();console.log('pipeline results:', results);// 关闭连接redis.disconnect();}main().catch(console.error);
SSL 加密连接示例
const { createClient } = require('redis');const fs = require('fs');async function main() {const client = createClient({url: 'rediss://192.xx.xx.2:6379', // 使用 rediss:// 协议启用 SSLpassword: 'crs-xxxx:密码',socket: {connectTimeout: 2000,tls: true,ca: fs.readFileSync('/path/to/ca.pem'), // CA 证书rejectUnauthorized: true}});client.on('error', (err) => console.error('Redis Client Error:', err));await client.connect();await client.set('ssl_test', 'encrypted_connection');console.log(await client.get('ssl_test'));await client.quit();}main().catch(console.error);
直连模式连接示例
直连模式下,客户端使用 Redis Cluster 协议直接连接各分片节点,本地处理 MOVED/ASK 重定向,可直接使用社区标准的 Redis Cluster 客户端接入。
说明:
直连模式仅适用于集群架构实例。
需使用支持 Redis Cluster 协议的客户端(node-redis 的 createCluster 或 ioredis 的 Redis.Cluster)。
需在控制台开启直连模式并获取各分片节点的连接地址。
认证方式复用 Redis 原生 ACL 机制:默认账号仅传密码,自定义账号需分别传入账号名与密码,不支持
用户名@密码 拼接格式。直连模式暂不支持 SSL 加密连接。
node-redis Cluster 连接示例
const { createCluster } = require('redis');async function main() {// 创建集群客户端const cluster = createCluster({rootNodes: [{ url: 'redis://192.xx.xx.2:6379' },{ url: 'redis://192.xx.xx.3:6379' },{ url: 'redis://192.xx.xx.4:6379' }],defaults: {password: 'password', // 直连模式默认账号仅传密码,不带实例 ID 前缀socket: {connectTimeout: 2000,reconnectStrategy: (retries) => {if (retries > 10) return new Error('Max retries reached');return Math.min(retries * 200, 3000);}}},maxCommandRedirections: 3 // 最大重定向次数});cluster.on('error', (err) => console.error('Cluster Error:', err));// 建立连接await cluster.connect();// 写入数据(客户端自动路由到正确的分片)await cluster.set('cluster:key1', 'value1');await cluster.set('cluster:key2', 'value2');await cluster.set('cluster:key3', 'value3');// 读取数据console.log('key1:', await cluster.get('cluster:key1'));console.log('key2:', await cluster.get('cluster:key2'));console.log('key3:', await cluster.get('cluster:key3'));// 哈希操作await cluster.hSet('user:{1001}', { name: '张三', age: '28' });const userInfo = await cluster.hGetAll('user:{1001}');console.log('user info:', userInfo);// 使用 Hash Tag 确保相关 Key 路由到同一分片await cluster.set('{order:1001}:status', 'paid');await cluster.set('{order:1001}:amount', '99.00');await cluster.set('{order:1001}:time', '2025-01-01 10:00:00');console.log('order status:', await cluster.get('{order:1001}:status'));// 关闭连接await cluster.quit();}main().catch(console.error);
ioredis Cluster 连接示例
const Redis = require('ioredis');// 创建集群连接const cluster = new Redis.Cluster([{ host: '192.xx.xx.2', port: 6379 },{ host: '192.xx.xx.3', port: 6379 },{ host: '192.xx.xx.4', port: 6379 }],{redisOptions: {password: 'password', // 直连模式默认账号仅传密码,不带实例 ID 前缀connectTimeout: 2000,commandTimeout: 2000},clusterRetryStrategy: (times) => {if (times > 10) return null;return Math.min(times * 200, 3000);},maxRedirections: 3, // 最大重定向次数retryDelayOnFailover: 300, // 故障转移重试延迟(毫秒)retryDelayOnClusterDown: 1000, // 集群不可用重试延迟(毫秒)scaleReads: 'master' // 读请求路由策略});cluster.on('connect', () => console.log('Cluster connected'));cluster.on('error', (err) => console.error('Cluster error:', err));async function main() {// 写入数据await cluster.set('cluster:key1', 'value1');await cluster.set('cluster:key2', 'value2');await cluster.set('cluster:key3', 'value3');// 读取数据console.log('key1:', await cluster.get('cluster:key1'));console.log('key2:', await cluster.get('cluster:key2'));console.log('key3:', await cluster.get('cluster:key3'));// 使用 Hash Tagawait cluster.set('{order:1001}:status', 'paid');await cluster.set('{order:1001}:amount', '99.00');console.log('order status:', await cluster.get('{order:1001}:status'));// Pipeline 批量操作const pipeline = cluster.pipeline();pipeline.set('{batch}:k1', 'v1');pipeline.set('{batch}:k2', 'v2');pipeline.set('{batch}:k3', 'v3');pipeline.get('{batch}:k1');pipeline.get('{batch}:k2');pipeline.get('{batch}:k3');const results = await pipeline.exec();console.log('pipeline results:', results);// 关闭连接cluster.disconnect();}main().catch(console.error);
自定义账号(ACL)连接示例
直连模式复用 Redis 原生 ACL 认证机制,使用自定义账号时需分别传入账号名与密码,不支持
用户名@密码 拼接格式。const { createCluster } = require('redis');async function main() {// ===== ACL 认证机制:账号名与密码是两个独立字段 =====// 直连模式的多账号能力基于 Redis 原生 ACL:控制台创建的每个自定义账号// 都是一个独立的 ACL user,认证时客户端向节点发送 AUTH <account> <password>。// 因此需将 username 与 password 分别传入(等价于执行 AUTH account password),// 不要写成代理模式的 "myuser@MyPassword" 拼接格式。const cluster = createCluster({rootNodes: [{ url: 'redis://192.xx.xx.2:6379' },{ url: 'redis://192.xx.xx.3:6379' },{ url: 'redis://192.xx.xx.4:6379' }],defaults: {username: 'myuser', // ACL 账号名 → AUTH accountpassword: 'MyPassword', // 账号密码 → AUTH password(纯密码,无需拼接)socket: {connectTimeout: 2000}},maxCommandRedirections: 3});cluster.on('error', (err) => console.error('Cluster Error:', err));await cluster.connect();await cluster.set('key', 'value');console.log(await cluster.get('key'));await cluster.quit();}main().catch(console.error);
连接参数说明
node-redis 参数
参数 | 说明 | 推荐值 |
url | 连接地址,格式: redis://host:port | - |
password | 认证密码 | 默认账号格式: 实例 ID:密码 |
socket.connectTimeout | 连接超时(毫秒) | 2000 |
socket.reconnectStrategy | 重连退避策略 | 指数退避,上限 3000ms |
maxCommandRedirections | 最大重定向次数(Cluster 模式) | 3 |
ioredis 参数
参数 | 说明 | 推荐值 |
host | 实例连接地址 | - |
port | 实例端口号 | 6379 |
password | 认证密码 | 默认账号格式: 实例 ID:密码 |
connectTimeout | 连接超时(毫秒) | 2000 |
commandTimeout | 命令超时(毫秒) | 2000 |
maxRetriesPerRequest | 每个请求最大重试次数 | 3 |
maxRedirections | 最大重定向次数(Cluster 模式) | 3 |
常见问题
连接超时
确认客户端所在 CVM 与分布式缓存数据库实例在同一 VPC 内。
确认安全组规则已放通对应端口。
确认连接地址和端口正确。
认证失败
代理模式:默认账号使用
实例 ID:密码,自定义账号使用 用户名@密码。直连模式:复用 Redis ACL 认证,默认账号仅传密码(
AUTH password),自定义账号需分别传入账号名与密码(AUTH account password),不支持 用户名@密码 拼接格式。确认密码中无特殊字符导致解析异常。
直连模式 MOVED 错误
确认使用
createCluster 或 Redis.Cluster 而非 createClient 或 new Redis()。确认已在控制台开启直连模式。
确认 rootNodes 地址为分片节点地址而非 VIP 地址。
连接中断后未自动重连
确认
reconnectStrategy 配置正确。确认网络环境稳定,安全组规则未变更。