安装 Redis 与第一个 Node-Redis 示例
本章分别安装 Redis 服务端和 Node-Redis 客户端。两者不是同一个东西:
- Redis 服务端负责保存和处理数据。
redisnpm 包负责让 Node.js 程序连接服务端。
1. 启动 Redis 服务端
使用 Docker 是跨平台且容易清理的学习方式:
docker run --name nloop-redis -p 6379:6379 -d redis:8
确认容器正在运行:
docker ps
测试 Redis:
docker exec -it nloop-redis redis-cli PING
输出 PONG 代表 Redis 服务端可以正常响应。
官方首页可能展示候选版镜像标签。学习项目建议使用明确的稳定主版本,不要无意间依赖 RC 版本。
2. 安装 Node-Redis
在当前项目中安装:
npm install redis
redis 包包含基础客户端和 Redis Stack 相关模块。初学阶段直接安装它最简单;只有在明确追求更小依赖范围时,才考虑单独安装 @redis/client。
3. 编写第一个示例
新建一个临时学习文件,例如 redis-basic.ts:
import { createClient } from "redis";
async function main(): Promise<void> {
const client = createClient();
client.on("error", (error: Error) => {
console.error("Redis 客户端错误:", error);
});
await client.connect();
try {
await client.set("tutorial:greeting", "hello redis");
const greeting: string | null = await client.get("tutorial:greeting");
console.log(greeting);
} finally {
await client.close();
}
}
main().catch((error: unknown) => {
console.error("程序执行失败:", error);
process.exitCode = 1;
});
运行:
ts-node redis-basic.ts
预期输出:
hello redis
4. 逐行理解
createClient()
创建客户端对象,但此时不等于已经可以执行命令。默认连接 localhost:6379。
client.on("error", ...)
Node-Redis 客户端是 EventEmitter。官方明确要求监听 error 事件,否则连接类错误可能作为未处理的 error 事件导致进程退出。
await client.connect()
建立 TCP 连接,并等待客户端就绪。不要在每个 HTTP 请求中重新连接。
get() 的返回类型
键不存在时,Redis 返回空结果,因此 TypeScript 类型是 string | null。这个类型提醒我们必须处理缓存未命中。
close() 与 destroy()
await client.close():停止接收新命令,等待已排队命令完成后关闭。client.destroy():立即销毁连接,适合无法继续等待或连接已经异常的情况。
Redis 7.2 已弃用 QUIT 命令,现代 Node-Redis 文档也建议使用关闭网络连接的方式。
5. 查看真实数据
进入 CLI:
docker exec -it nloop-redis redis-cli
执行:
GET tutorial:greeting
TYPE tutorial:greeting
TTL tutorial:greeting
TTL 返回 -1 表示该键没有过期时间。这也是为什么缓存章节会强调 TTL。
6. 连接远程 Redis
Node-Redis 支持连接 URL:
const client = createClient({
url: "redis://username:password@redis.example.com:6379/0",
});
启用 TLS 时使用 rediss://。生产环境不要把密码硬编码进源码,应从环境变量读取。
常见问题
ECONNREFUSED 127.0.0.1:6379
通常代表 Redis 没有启动、端口映射错误,或程序与 Redis 不在同一网络环境。
程序一直不退出
Redis 连接仍保持打开。确保正常路径和异常路径最终都执行 close() 或 destroy()。
为什么本项目能使用 import
因为 ts-node 读取 tsconfig.json,将 TypeScript 的 import 转成 CommonJS 后执行。当前项目并不需要为了 Node-Redis 修改为原生 ESM。