Project Icon

node-redis

Node.js Redis 客户端 现代化功能与自动管道支持

Node-Redis 是一款面向 Node.js 的现代化 Redis 客户端。它全面支持 Redis 命令,包括事务、阻塞命令和发布/订阅功能。此客户端具备自动管道、异步迭代器和 Lua 脚本支持,可连接 Redis 集群。凭借其易用性和卓越性能,Node-Redis 成为开发 Node.js Redis 应用的优选工具。

Node-Redis

测试 覆盖率 许可证

Discord Twitch YouTube Twitter

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

如何使用 Redis?

在 Redis 大学免费学习

使用 Redis Launchpad 加速构建

尝试 Redis Cloud

深入开发者教程

加入 Redis 社区

在 Redis 工作

软件包

:warning: 在 4.1.0 版本中,我们将子包从 @node-redis 移动到了 @redis。如果你只是使用 npm install redis,你不需要做任何改变——它会自动升级。如果你直接使用子包,你需要指向新的作用域(例如使用 @redis/client 而不是 @node-redis/client)。

安装

通过 docker 启动 redis:

docker run -p 6379:6379 -it redis/redis-stack-server:latest

要安装 node-redis,只需:

npm install redis

:warning: 新接口简洁酷炫,但如果你有现有的代码库,你可能需要阅读迁移指南

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

用法

基本示例

import { createClient } from 'redis';

const client = await createClient()
  .on('error', err => console.log('Redis 客户端错误', err))
  .connect();

await client.set('key', 'value');
const value = await client.get('key');
await client.disconnect();

上述代码连接到本地主机的 6379 端口。要连接到不同的主机或端口,请使用格式为 redis[s]://[[username][:password]@][host][:port][/db-number] 的连接字符串:

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

你还可以使用离散参数、UNIX 套接字,甚至 TLS 来连接。详细信息可以在客户端配置指南中找到。

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

Redis 命令

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

// 原始 Redis 命令
await client.HSET('key', 'field', 'value');
await client.HGETALL('key');

// 友好的 JavaScript 命令
await client.hSet('key', 'field', 'value');
await client.hGetAll('key');

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

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

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

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

也支持 Buffer

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

不支持的 Redis 命令

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

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

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

事务(Multi/Exec)

通过调用 .multi() 开始一个事务,然后链式调用你的命令。完成后,调用 .exec() 你将得到一个包含结果的数组:

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

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

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

要深入了解事务,请查看隔离执行指南

阻塞命令

通过指定 isolated 选项,可以在新连接上运行任何命令。当命令的 Promise 被履行时,新创建的连接将被关闭。

这种模式特别适用于阻塞命令——比如 BLPOPBLMOVE:

import { commandOptions } from 'redis';

const blPopPromise = client.blPop(
  commandOptions({ isolated: true }),
  'key',
  0
);

await client.lPush('key', ['1', '2']);

await blPopPromise; // '2'

要了解更多关于隔离执行的信息,请查看指南

发布/订阅

请参阅发布/订阅概述

扫描迭代器

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

for await (const key of client.scanIterator()) {
  // 使用 key!
  await client.get(key);
}

这也适用于 HSCANSSCANZSCAN:

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')) {}

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

client.scanIterator({
  TYPE: 'string', // 仅适用于 `SCAN`
  MATCH: 'patter*',
  COUNT: 100
});

可编程性

Redis 提供了一个编程接口,允许在 redis 服务器上执行代码。

函数

以下示例从 redis 中检索一个键,返回该键的值加上一个整数。例如,如果你的键 foo 的值为 17,我们运行 add('foo', 25),它会返回生命、宇宙和万物的答案。

#!lua name=library

redis.register_function {
  function_name = 'add',
  callback = function(keys, args) return redis.call('GET', keys[1]) + args[1] end,
  flags = { 'no-writes' }
}

这是相同的示例,但格式可以粘贴到 redis-cli 中。

FUNCTION LOAD "#!lua name=library\nredis.register_function{function_name=\"add\", callback=function(keys, args) return redis.call('GET', keys[1])+args[1] end, flags={\"no-writes\"}}"

在运行以下示例之前,先在 redis 服务器 上加载上述 redis 函数。

import { createClient } from 'redis';

const client = createClient({
  functions: {
    library: {
      add: {
        NUMBER_OF_KEYS: 1,
        transformArguments(key: string, toAdd: number): Array<string> {
          return [key, toAdd.toString()];
        },
        transformReply(reply: number): number {
          return reply;
        }
      }
    }
  }
});

await client.connect();

await client.set('key', '1');
await client.library.add('key', 2); // 3

Lua 脚本

以下是上述概念的端到端示例。

import { createClient, defineScript } from 'redis';

const client = createClient({
  scripts: {
    add: defineScript({
      NUMBER_OF_KEYS: 1,
      SCRIPT:
        'return redis.call("GET", KEYS[1]) + ARGV[1];',
      transformArguments(key: string, toAdd: number): Array<string> {
        return [key, toAdd.toString()];
      },
      transformReply(reply: number): number {
        return reply;
      }
    })
  }
});

await client.connect();

await client.set('key', '1');
await client.add('key', 2); // 3

断开连接

有两个函数可以断开客户端与 Redis 服务器的连接。在大多数情况下,你应该使用 .quit() 以确保在关闭连接之前将待处理的命令发送到 Redis。

.QUIT()/.quit()

通过向服务器发送 QUIT 命令,优雅地关闭客户端与 Redis 的连接。在退出之前,客户端会执行其队列中的任何剩余命令,并将从 Redis 收到每个命令的回复。

const [ping, get, quit] = await Promise.all([
  client.ping(),
  client.get('key'),
  client.quit()
]); // ['PONG', null, 'OK']

try {
  await client.get('key');
} catch (err) {
  // ClosedClient 错误
}

.disconnect()

立即强制关闭客户端与 Redis 的连接。调用 disconnect 不会向 Redis 服务器发送进一步的待处理命令,也不会等待或解析未完成的响应。

await client.disconnect();

自动流水线

Node Redis 会自动将同一"tick"期间发出的请求组成流水线。

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

当然,如果你不处理你的 Promise,你肯定会得到未处理的 Promise 异常。要利用自动流水线并处理你的 Promise,请使用 Promise.all()

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

集群

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

事件

Node Redis 客户端类是一个 Node.js EventEmitter,每当网络状态发生变化时它都会发出一个事件:

名称何时监听器参数
connect正在初始化与服务器的连接无参数
ready客户端准备就绪可以使用无参数
end连接已关闭(通过 .quit().disconnect()无参数
error发生错误—通常是网络问题,如"Socket closed unexpectedly"(error: Error)
reconnecting客户端正在尝试重新连接到服务器无参数
sharded-channel-moved参见这里参见这里

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

客户端不会发出任何其他事件,除了上面列出的那些。

支持的 Redis 版本

Node Redis 支持以下版本的 Redis:

版本支持
7.0.z:heavy_check_mark:
6.2.z:heavy_check_mark:
6.0.z:heavy_check_mark:
5.0.z:heavy_check_mark:
< 5.0:x:

Node Redis 应该可以与旧版本的 Redis 一起工作,但它没有经过全面测试,我们无法提供支持。

贡献

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

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

贡献者

许可证

本仓库采用"MIT"许可证。参见LICENSE

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

白日梦AI

白日梦AI提供专注于AI视频生成的多样化功能,包括文生视频、动态画面和形象生成等,帮助用户快速上手,创造专业级内容。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

讯飞绘镜

讯飞绘镜是一个支持从创意到完整视频创作的智能平台,用户可以快速生成视频素材并创作独特的音乐视频和故事。平台提供多样化的主题和精选作品,帮助用户探索创意灵感。

Project Cover

讯飞文书

讯飞文书依托讯飞星火大模型,为文书写作者提供从素材筹备到稿件撰写及审稿的全程支持。通过录音智记和以稿写稿等功能,满足事务性工作的高频需求,帮助撰稿人节省精力,提高效率,优化工作与生活。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号