Skip to content

node-redis 是 Node.js 的现代、高性能 Redis 客户端。

¥node-redis is a modern, high performance Redis client for Node.js.

安装

¥Installation

通过 docker 启动 redis:

¥Start a redis via docker:

bash
docker run -p 6379:6379 -d redis:8.0-rc1

要安装 node-redis,只需:

¥To install node-redis, simply:

bash
npm install redis

"redis" 是包含所有其他软件包的 "一应俱全" 软件包。如果你只需要命令的子集,则可以安装单独的软件包。请参阅下面的列表。

¥"redis" is the "whole in one" package that includes all the other packages. If you only need a subset of the commands, you can install the individual packages. See the list below.

¥Packages

名称描述
redis包含所有 "redis-stack" 模块的客户端
@redis/client基本客户端(即 RedisClientRedisCluster 等)
@redis/bloomRedis Bloom 命令
@redis/jsonRedis JSON 命令
@redis/searchRediSearch 命令
@redis/time-seriesRedis 时间序列 命令
@redis/entraid使用 Microsoft Entra ID 对 Redis 客户端进行基于令牌的安全身份验证

正在寻找处理对象映射的高级库?参见 redis-om-node

¥Looking for a high-level library to handle object mapping? See redis-om-node!

用法

¥Usage

基本示例

¥Basic Example

typescript
import { createClient } from "redis";

const client = await createClient()
  .on("error", (err) => console.log("Redis Client Error", err))
  .connect();

await client.set("key", "value");
const value = await client.get("key");
client.destroy();

以上代码连接到 localhost 的 6379 端口。要连接到其他主机或端口,请使用 redis[s]://[[username][:password]@][host][:port][/db-number] 格式的连接字符串:

¥The above code connects to localhost on port 6379. To connect to a different host or port, use a connection string in the format redis[s]://[[username][:password]@][host][:port][/db-number]:

typescript
createClient({
  url: "redis://alice:foobared@awesome.redis.server:6380",
});

你还可以使用离散参数、UNIX 套接字甚至 TLS 进行连接。详情请参阅 客户端配置指南

¥You can also use discrete parameters, UNIX sockets, and even TLS to connect. Details can be found in the client configuration guide.

要检查客户端是否已连接并准备好发送命令,请使用返回布尔值的 client.isReadyclient.isOpen 也可用。当客户端的底层套接字打开时,返回 true;当客户端的底层套接字未打开时(例如,客户端仍在连接中或在网络错误后重新连接),返回 false

¥To check if the the client is connected and ready to send commands, use client.isReady which returns a boolean. client.isOpen is also available. This returns true when the client's underlying socket is open, and false when it isn't (for example when the client is still connecting or reconnecting after a network error).

Redis 命令

¥Redis Commands

内置支持所有 开箱即用的 Redis 命令。它们使用原始的 Redis 命令名称(HSETHGETALL 等)以及更友好的驼峰式版本(hSethGetAll 等)来暴露:

¥There is built-in support for all of the out-of-the-box Redis commands. They are exposed using the raw Redis command names (HSET, HGETALL, etc.) and a friendlier camel-cased version (hSet, hGetAll, etc.):

typescript
// raw Redis commands
await client.HSET("key", "field", "value");
await client.HGETALL("key");

// friendly JavaScript commands
await client.hSet("key", "field", "value");
await client.hGetAll("key");

命令修饰符使用 JavaScript 对象指定:

¥Modifiers to commands are specified using a JavaScript object:

typescript
await client.set("key", "value", {
  EX: 10,
  NX: true,
});

回复将被转换为有用的数据结构:

¥Replies will be transformed into useful data structures:

typescript
await client.hGetAll("key"); // { field1: 'value1', field2: 'value2' }
await client.hVals("key"); // ['value1', 'value2']

Buffer 也受支持:

¥Buffers are supported as well:

typescript
const client = createClient().withTypeMapping({
  [RESP_TYPES.BLOB_STRING]: Buffer
});

await client.hSet("key", "field", Buffer.from("value")); // 'OK'
await client.hGet("key", "field"); // { field: <Buffer 76 61 6c 75 65> }

不支持的 Redis 命令

¥Unsupported Redis Commands

如果你想运行 Node Redis 尚不知道的命令和/或参数(目前!),请使用 .sendCommand()

¥If you want to run commands and/or use arguments that Node Redis doesn't know about (yet!) use .sendCommand():

typescript
await client.sendCommand(["SET", "key", "value", "NX"]); // 'OK'

await client.sendCommand(["HGETALL", "key"]); // ['key1', 'field1', 'key2', 'field2']

注意:使用集群时 API 会有所不同

¥Note: the API is different when using a cluster.

事务 (Multi/Exec)

¥Transactions (Multi/Exec)

通过调用 .multi() 启动 transaction,然后链接命令。完成后,调用 .exec(),你将收到一个包含结果的数组:

¥Start a transaction by calling .multi(), then chaining your commands. When you're done, call .exec() and you'll get an array back with your results:

typescript
await client.set("another-key", "another-value");

const [setKeyReply, otherKeyValue] = await client
  .multi()
  .set("key", "value")
  .get("another-key")
  .exec(); // ['OK', 'another-value']

你也可以通过调用 .watch() 来对键进行 watch 操作。如果任何被监视的键​​发生变化,你的事务将中止。

¥You can also watch keys by calling .watch(). Your transaction will abort if any of the watched keys change.

阻塞命令

¥Blocking Commands

在 v4 中,RedisClient 能够在 "main" 连接之上使用 "隔离池" 创建连接池。但是,如果没有 "main" 连接,则无法使用连接池:

¥In v4, RedisClient had the ability to create a pool of connections using an "Isolation Pool" on top of the "main" connection. However, there was no way to use the pool without a "main" connection:

javascript
const client = await createClient()
  .on("error", (err) => console.error(err))
  .connect();

await client.ping(client.commandOptions({ isolated: true }));

在 v5 中,我们将此池逻辑提取到其自己的类 RedisClientPool 中:

¥In v5 we've extracted this pool logic into its own class—RedisClientPool:

javascript
const pool = await createClientPool()
  .on("error", (err) => console.error(err))
  .connect();

await pool.ping();

发布/订阅

¥Pub/Sub

请参阅 发布/订阅概述

¥See the Pub/Sub overview.

扫描迭代器

¥Scan Iterator

SCAN 的结果可以使用 异步迭代器 循环遍历:

¥SCAN results can be looped over using async iterators:

typescript
for await (const keys of client.scanIterator()) {
  console.log(keys, await client.mGet(keys));
}

这也适用于 HSCANSSCANZSCAN

¥This works with HSCAN, SSCAN, and ZSCAN too:

typescript
for await (const { field, value } of client.hScanIterator("hash")) {
}
for await (const member of client.sScanIterator("set")) {
}
for await (const { score, value } of client.zScanIterator("sorted-set")) {
}

你可以通过提供配置对象来覆盖默认选项:

¥You can override the default options by providing a configuration object:

typescript
client.scanIterator({
  TYPE: "string", // `SCAN` only
  MATCH: "patter*",
  COUNT: 100,
});

断开连接

¥Disconnecting

QUIT 命令在 Redis 7.2 中已弃用,现在在 Node-Redis 中也应视为弃用。客户端无需向服务器发送 QUIT 命令,只需关闭网络连接即可。

¥The QUIT command has been deprecated in Redis 7.2 and should now also be considered deprecated in Node-Redis. Instead of sending a QUIT command to the server, the client can simply close the network connection.

client.QUIT/quit() 将被 client.close() 取代。为了避免混淆,client.disconnect() 已重命名为 client.destroy()

¥client.QUIT/quit() is replaced by client.close(). and, to avoid confusion, client.disconnect() has been renamed to client.destroy().

typescript
client.destroy();

客户端缓存

¥Client Side Caching

Node Redis v5 增加了对 客户端缓存 的支持,这使得客户端能够在本地缓存查询结果。当缓存结果不再有效时,Redis 服务器会通知客户端。

¥Node Redis v5 adds support for Client Side Caching, which enables clients to cache query results locally. The Redis server will notify the client when cached results are no longer valid.

typescript
// Enable client side caching with RESP3
const client = createClient({
  RESP: 3,
  clientSideCache: {
    ttl: 0,             // Time-to-live (0 = no expiration)
    maxEntries: 0,      // Maximum entries (0 = unlimited)
    evictPolicy: "LRU"  // Eviction policy: "LRU" or "FIFO"
  }
});

查看 V5 文档 了解更多详情和高级用法。

¥See the V5 documentation for more details and advanced usage.

自动流水线

¥Auto-Pipelining

Node Redis 会自动将在同一 "tick" 期间发出的请求进行流水线处理。

¥Node Redis will automatically pipeline requests that are made during the same "tick".

typescript
client.set("Tm9kZSBSZWRpcw==", "users:1");
client.sAdd("users:1:tokens", "Tm9kZSBSZWRpcw==");

当然,如果你不对 Promise 执行任何操作,你肯定会收到 未处理的 Promise 异常。要利用自动流水线功能并处理你的 Promise,请使用 Promise.all()

¥Of course, if you don't do something with your Promises you're certain to get unhandled Promise exceptions. To take advantage of auto-pipelining and handle your Promises, use Promise.all().

typescript
await Promise.all([
  client.set("Tm9kZSBSZWRpcw==", "users:1"),
  client.sAdd("users:1:tokens", "Tm9kZSBSZWRpcw=="),
]);

可编程性

¥Programmability

请参阅 可编程性概述

¥See the Programmability overview.

集群

¥Clustering

使用 Node Redis 连接到 Redis 集群时,请查看 集群指南

¥Check out the Clustering Guide when using Node Redis to connect to a Redis Cluster.

事件

¥Events

Node Redis 客户端类是一个 Nodejs EventEmitter,它会在网络状态每次发生变化时触发事件:

¥The Node Redis client class is an Nodejs EventEmitter and it emits an event each time the network status changes:

名称何时监听器参数
connect发起与服务器的连接无参数
ready客户端已准备就绪无参数
end连接已关闭(通过 .disconnect()无参数
error发生错误 - 通常是网络问题,例如 "套接字意外关闭"(error: Error)
reconnecting客户端正在尝试重新连接到服务器无参数
sharded-channel-moved参见 此处参见 此处
invalidateemitInvalidate 启用了客户端跟踪,但某个键已失效(key: RedisItem | null)

⚠️你必须监听 error 事件。如果客户端没有注册至少一个 error 监听器,并且发生了 error 错误,则会抛出该错误,Node.js 进程将退出。有关更多详细信息,请参阅 EventEmitter 文档

¥⚠️ You MUST listen to error events. If a client doesn't have at least one error listener registered and an error occurs, that error will be thrown and the Node.js process will exit. See the > EventEmitter docs for more details.

客户端不会发出除上述列出的 其他事件 之外的 其他事件

¥The client will not emit any other events beyond those listed above.

支持的 Redis 版本

¥Supported Redis versions

以下版本的 Redis 支持 Node Redis:

¥Node Redis is supported with the following versions of Redis:

参见 支持的 Redis 版本

¥See Supported Redis Versions.

迁移

¥Migration

贡献

¥Contributing

如果你想做出贡献,请查看 贡献指南

¥If you'd like to contribute, check out the contributing guide.

感谢所有为 Node Redis 做出贡献的人!

¥Thank you to all the people who already contributed to Node Redis!

许可证

¥License

此存储库根据 "MIT" 许可证获得许可。参见 LICENSE

¥This repository is licensed under the "MIT" license. See LICENSE.