ioredis

ioredis

Node.js的全功能Redis客户端

ioredis是一个功能全面的Node.js Redis客户端。它支持Redis集群、哨兵、流处理、管道操作和Lua脚本等特性。ioredis提供直观的API,支持回调和Promise,具备命令参数转换、键前缀等功能。此外,它还支持二进制数据处理、TLS加密和离线队列。ioredis使用TypeScript开发,提供类型声明,兼容Redis 2.6.12及更高版本。

ioredisRedisNode.js数据库高性能Github开源项目

ioredis

Build Status Coverage Status Commitizen friendly semantic-release

Discord Twitch YouTube Twitter

A robust, performance-focused and full-featured Redis client for Node.js.

Supports Redis >= 2.6.12. Completely compatible with Redis 7.x.

Features

ioredis is a robust, full-featured Redis client that is used in the world's biggest online commerce company Alibaba and many other awesome companies.

  1. Full-featured. It supports Cluster, Sentinel, Streams, Pipelining, and of course Lua scripting, Redis Functions, Pub/Sub (with the support of binary messages).
  2. High performance 🚀.
  3. Delightful API 😄. It works with Node callbacks and Native promises.
  4. Transformation of command arguments and replies.
  5. Transparent key prefixing.
  6. Abstraction for Lua scripting, allowing you to define custom commands.
  7. Supports binary data.
  8. Supports TLS 🔒.
  9. Supports offline queue and ready checking.
  10. Supports ES6 types, such as Map and Set.
  11. Supports GEO commands 📍.
  12. Supports Redis ACL.
  13. Sophisticated error handling strategy.
  14. Supports NAT mapping.
  15. Supports autopipelining.

100% written in TypeScript and official declarations are provided:

<img width="837" src="resources/ts-screenshot.png" alt="TypeScript Screenshot" />

Versions

VersionBranchNode.js VersionRedis Version
5.x.x (latest)main>= 122.6.12 ~ latest
4.x.xv4>= 62.6.12 ~ 7

Refer to CHANGELOG.md for features and bug fixes introduced in v5.

🚀 Upgrading from v4 to v5

Links

<hr>

Quick Start

Install

npm install ioredis

In a TypeScript project, you may want to add TypeScript declarations for Node.js:

npm install --save-dev @types/node

Basic Usage

// Import ioredis. // You can also use `import { Redis } from "ioredis"` // if your project is a TypeScript project, // Note that `import Redis from "ioredis"` is still supported, // but will be deprecated in the next major version. const Redis = require("ioredis"); // Create a Redis instance. // By default, it will connect to localhost:6379. // We are going to cover how to specify connection options soon. const redis = new Redis(); redis.set("mykey", "value"); // Returns a promise which resolves to "OK" when the command succeeds. // ioredis supports the node.js callback style redis.get("mykey", (err, result) => { if (err) { console.error(err); } else { console.log(result); // Prints "value" } }); // Or ioredis returns a promise if the last argument isn't a function redis.get("mykey").then((result) => { console.log(result); // Prints "value" }); redis.zadd("sortedSet", 1, "one", 2, "dos", 4, "quatro", 3, "three"); redis.zrange("sortedSet", 0, 2, "WITHSCORES").then((elements) => { // ["one", "1", "dos", "2", "three", "3"] as if the command was `redis> ZRANGE sortedSet 0 2 WITHSCORES` console.log(elements); }); // All arguments are passed directly to the redis server, // so technically ioredis supports all Redis commands. // The format is: redis[SOME_REDIS_COMMAND_IN_LOWERCASE](ARGUMENTS_ARE_JOINED_INTO_COMMAND_STRING) // so the following statement is equivalent to the CLI: `redis> SET mykey hello EX 10` redis.set("mykey", "hello", "EX", 10);

See the examples/ folder for more examples. For example:

All Redis commands are supported. See the documentation for details.

Connect to Redis

When a new Redis instance is created, a connection to Redis will be created at the same time. You can specify which Redis to connect to by:

new Redis(); // Connect to 127.0.0.1:6379 new Redis(6380); // 127.0.0.1:6380 new Redis(6379, "192.168.1.1"); // 192.168.1.1:6379 new Redis("/tmp/redis.sock"); new Redis({ port: 6379, // Redis port host: "127.0.0.1", // Redis host username: "default", // needs Redis >= 6 password: "my-top-secret", db: 0, // Defaults to 0 });

You can also specify connection options as a redis:// URL or rediss:// URL when using TLS encryption:

// Connect to 127.0.0.1:6380, db 4, using password "authpassword": new Redis("redis://:authpassword@127.0.0.1:6380/4"); // Username can also be passed via URI. new Redis("redis://username:authpassword@127.0.0.1:6380/4");

See API Documentation for all available options.

Pub/Sub

Redis provides several commands for developers to implement the Publish–subscribe pattern. There are two roles in this pattern: publisher and subscriber. Publishers are not programmed to send their messages to specific subscribers. Rather, published messages are characterized into channels, without knowledge of what (if any) subscribers there may be.

By leveraging Node.js's built-in events module, ioredis makes pub/sub very straightforward to use. Below is a simple example that consists of two files, one is publisher.js that publishes messages to a channel, the other is subscriber.js that listens for messages on specific channels.

// publisher.js const Redis = require("ioredis"); const redis = new Redis(); setInterval(() => { const message = { foo: Math.random() }; // Publish to my-channel-1 or my-channel-2 randomly. const channel = `my-channel-${1 + Math.round(Math.random())}`; // Message can be either a string or a buffer redis.publish(channel, JSON.stringify(message)); console.log("Published %s to %s", message, channel); }, 1000);
// subscriber.js const Redis = require("ioredis"); const redis = new Redis(); redis.subscribe("my-channel-1", "my-channel-2", (err, count) => { if (err) { // Just like other commands, subscribe() can fail for some reasons, // ex network issues. console.error("Failed to subscribe: %s", err.message); } else { // `count` represents the number of channels this client are currently subscribed to. console.log( `Subscribed successfully! This client is currently subscribed to ${count} channels.` ); } }); redis.on("message", (channel, message) => { console.log(`Received ${message} from ${channel}`); }); // There's also an event called 'messageBuffer', which is the same as 'message' except // it returns buffers instead of strings. // It's useful when the messages are binary data. redis.on("messageBuffer", (channel, message) => { // Both `channel` and `message` are buffers. console.log(channel, message); });

It's worth noticing that a connection (aka a Redis instance) can't play both roles at the same time. More specifically, when a client issues subscribe() or psubscribe(), it enters the "subscriber" mode. From that point, only commands that modify the subscription set are valid. Namely, they are: subscribe, psubscribe, unsubscribe, punsubscribe, ping, and quit. When the subscription set is empty (via unsubscribe/punsubscribe), the connection is put back into the regular mode.

If you want to do pub/sub in the same file/process, you should create a separate connection:

const Redis = require("ioredis"); const sub = new Redis(); const pub = new Redis(); sub.subscribe(/* ... */); // From now, `sub` enters the subscriber mode. sub.on("message" /* ... */); setInterval(() => { // `pub` can be used to publish messages, or send other regular commands (e.g. `hgetall`) // because it's not in the subscriber mode. pub.publish(/* ... */); }, 1000);

PSUBSCRIBE is also supported in a similar way when you want to subscribe all channels whose name matches a pattern:

redis.psubscribe("pat?ern", (err, count) => {}); // Event names are "pmessage"/"pmessageBuffer" instead of "message/messageBuffer". redis.on("pmessage", (pattern, channel, message) => {}); redis.on("pmessageBuffer", (pattern, channel, message) => {});

Streams

Redis v5 introduces a new data type called streams. It doubles as a communication channel for building streaming architectures and as a log-like data structure for persisting data. With ioredis, the usage can be pretty straightforward. Say we have a producer publishes messages to a stream with redis.xadd("mystream", "*", "randomValue", Math.random()) (You may find the official documentation of Streams as a starter to understand the parameters used), to consume the messages, we'll have a consumer with the following code:

const Redis = require("ioredis"); const redis = new Redis(); const processMessage = (message) => { console.log("Id: %s. Data: %O", message[0], message[1]); }; async function listenForMessage(lastId = "$") { // `results` is an array, each element of which corresponds to a key. // Because we only listen to one key (mystream) here, `results` only contains // a single element. See more: https://redis.io/commands/xread#return-value const results = await redis.xread("block", 0, "STREAMS", "mystream", lastId); const [key, messages] = results[0]; // `key` equals to "mystream" messages.forEach(processMessage); // Pass the last id of the results to the next round. await listenForMessage(messages[messages.length - 1][0]); } listenForMessage();

Expiration

Redis can set a timeout to expire your key, after the timeout has expired the key will be automatically deleted. (You can find the official Expire documentation to understand better the different parameters you can use), to set your key to expire in 60 seconds, we will have the following code:

redis.set("key", "data", "EX", 60); // Equivalent to redis command "SET key data EX 60", because on ioredis set method, // all arguments are passed directly to the redis server.

Handle Binary Data

Binary data support is out of the box. Pass buffers to send binary data:

redis.set("foo", Buffer.from([0x62, 0x75, 0x66]));

Every command that returns a bulk string has a variant command with a Buffer suffix. The variant command returns a buffer instead of a UTF-8 string:

const result = await redis.getBuffer("foo"); // result is `<Buffer 62 75 66>`

It's worth noticing that you don't need the Buffer suffix variant in order to send binary data. That means in most case you should just use redis.set() instead of redis.setBuffer() unless you want to get the old value with the GET parameter:

const result = await redis.setBuffer("foo", "new value", "GET"); // result is `<Buffer 62 75 66>` as `GET` indicates returning the old value.

Pipelining

If you want to send a batch of commands (e.g. > 5), you can use pipelining to queue the commands in memory and then send them to Redis all at once. This way the performance improves by 50%~300% (See benchmark section).

redis.pipeline() creates a Pipeline instance. You can call any Redis commands on it just like the Redis instance. The commands are queued in memory and flushed to Redis by calling the exec method:

const pipeline = redis.pipeline(); pipeline.set("foo", "bar"); pipeline.del("cc"); pipeline.exec((err, results) => { // `err` is always null, and `results` is an array of responses // corresponding to the sequence of queued commands. // Each response follows the format `[err, result]`. }); // You can even chain the commands: redis .pipeline() .set("foo", "bar") .del("cc") .exec((err, results) => {}); // `exec` also returns a Promise: const promise = redis.pipeline().set("foo", "bar").get("foo").exec(); promise.then((result) => { // result === [[null, 'OK'], [null, 'bar']] });

Each chained command can also have a callback, which will be invoked when the command gets a reply:

redis .pipeline() .set("foo", "bar") .get("foo", (err, result) => { // result === 'bar' }) .exec((err, result) => { // result[1][1] === 'bar' });

In addition to adding commands to the pipeline queue individually, you can also pass an array of commands and arguments to the constructor:

redis .pipeline([ ["set", "foo", "bar"], ["get", "foo"], ]) .exec(() => { /* ... */ });

#length property shows how many commands in the pipeline:

const length = redis.pipeline().set("foo", "bar").get("foo").length; // length === 2

Transaction

Most of the time, the transaction commands multi & exec are used together with pipeline. Therefore, when multi is called, a Pipeline instance is created automatically by default, so you can use multi just like pipeline:

redis .multi() .set("foo", "bar") .get("foo")

编辑推荐精选

Vora

Vora

免费创建高清无水印Sora视频

Vora是一个免费创建高清无水印Sora视频的AI工具

Refly.AI

Refly.AI

最适合小白的AI自动化工作流平台

无需编码,轻松生成可复用、可变现的AI自动化工作流

酷表ChatExcel

酷表ChatExcel

大模型驱动的Excel数据处理工具

基于大模型交互的表格处理系统,允许用户通过对话方式完成数据整理和可视化分析。系统采用机器学习算法解析用户指令,自动执行排序、公式计算和数据透视等操作,支持多种文件格式导入导出。数据处理响应速度保持在0.8秒以内,支持超过100万行数据的即时分析。

AI工具酷表ChatExcelAI智能客服AI营销产品使用教程
TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
AIWritePaper论文写作

AIWritePaper论文写作

AI论文写作指导平台

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

AI辅助写作AI工具AI论文工具论文写作智能生成大纲数据安全AI助手热门
博思AIPPT

博思AIPPT

AI一键生成PPT,就用博思AIPPT!

博思AIPPT,新一代的AI生成PPT平台,支持智能生成PPT、AI美化PPT、文本&链接生成PPT、导入Word/PDF/Markdown文档生成PPT等,内置海量精美PPT模板,涵盖商务、教育、科技等不同风格,同时针对每个页面提供多种版式,一键自适应切换,完美适配各种办公场景。

AI办公办公工具AI工具博思AIPPTAI生成PPT智能排版海量精品模板AI创作热门
潮际好麦

潮际好麦

AI赋能电商视觉革命,一站式智能商拍平台

潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。

iTerms

iTerms

企业专属的AI法律顾问

iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。

SimilarWeb流量提升

SimilarWeb流量提升

稳定高效的流量提升解决方案,助力品牌曝光

稳定高效的流量提升解决方案,助力品牌曝光

Sora2视频免费生成

Sora2视频免费生成

最新版Sora2模型免费使用,一键生成无水印视频

最新版Sora2模型免费使用,一键生成无水印视频

下拉加载更多