安装 Redis 与第一个 Node-Redis 示例

本章分别安装 Redis 服务端和 Node-Redis 客户端。两者不是同一个东西:

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()

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。