Node Redis文档

原文链接 Node Redis

Node Redis

安装

npm i redis

例子

	const redis = require("redis");
    const client = redis.createClient();
    client.on("error", function(error) {
    	console.error(error);
    });
    client.set("key", "value", redis.print);
    client.get("key", redis.print);

Note that the API is entirely asynchronous. To get data back from the server, you’ll need to use a callback.
注意,所有的API都是异步的,从服务器获取数据时,需要使用回调的方式

通过Promise的方式使用

Node Redis目前尚未支持原生的Promise写法(Promise的支持会在v4版本更新),如果你依然想要这种写法的,你也可以通过Node.js中的util.promisify方法来支持Promise的写法。

const { promisify } = require("util");
const getAsync = promisify(client.get).bind(client);

getAsync.then(console.log).catch(console.error);

通过指令使用

Node Redis库是与Redis中的命令一一对应的。
每一个Redis命令都作为一个函数被暴露在了client对象上。所有的方法都采用了数组输入参数后加一个callback回调,或者是前面可变数量的参数后加一个callback回调的格式进行传参。示例代码如下:

client.hmset(["key", "foo", "bar"], function(err, res) {
  // ...
});

// Works the same as
client.hmset("key", ["foo", "bar"], function(err, res) {
  // ...
});

// Or
client.hmset("key", "foo", "bar", function(err, res) {
  // ...
});

如果可以使用数组(通过主体解析器、查询字符串或其他方法),则应特别注意入参,因为单个参数可能会无意中被解释为多个参数。
注意,无论采用哪种传参方式,callback回调选项都是可选的。

client.set("foo", "bar");
client.set(["hello", "world"]);

如果Redis中某个key允许为null时,如果不传key,会直接使用null代替。

client.get("missing_key", function(err, reply) {
  // reply is null when the key is missing
  console.log(reply);
});

Node Redis会对返回的结果进行最小化的解析。调用函数在返回数据时,整数和数组与JavaScript中的整数和数组并无差别;HGETALL会返回一个使用hash keys作为键的对象。所有的字符串会根据你的设置,作为JavaScript中的字符串或者一个buffer返回。请注意,当参数或返回值为空值、undefined或者布尔值时,会被强制转换为字符串。

事件

数据库连接与其他事件
当连接到数据库服务器时,client会根据状态触发一些特定的事件。

"ready"

一旦建立了连接,客户端将发出ready。在就绪事件之前发出的命令被排队,然后在发出此事件之前重放。
在连接准备就绪时client会触发一次ready事件。所有的在ready事件触发前的命令都会被排成一个队列,然后在ready事件触发前被以此调用。

"connect"

当连接上数据库服务时,client会尽可能快地触发一个connect事件

"reconnecting"

client会触发reconnecting事件当应用尝试重新连接到Redis服务器时。监听器会回传一个对象,该对象包含delay(前一次try的毫秒数)和attempt属性。

"error"

当应用在连接Redis服务时遇到错误或者Node Redis中发生任何其他错误时,client都会触发error事件。如果你使用不带回调的命令时遇到了ReplyError,那么这个错误会被发送到监听器上。因此,需要对监听器上的错误进行处理。

"end"

当一个可用的Redis服务连接被关闭时,client会触发一个end事件

"warning"

当设置了密码但不需要密码,或者使用了不推荐的option / function / similar项时,client会触发一个warning事件。

API

redis.createClient()

If you have redis-server running on the same machine as node, then the defaults for port and host are probably fine and you don’t need to supply any arguments. createClient() returns a RedisClient object. Otherwise, createClient() accepts these arguments:
如果你的redis服务和你的node服务器运行在同一台机器上,那么port和host使用默认值即可,你不需要提供任何参数。createClient返回一个RedisClient对象。接收参数如下:

  • redis.createClient([options])
  • redis.createClient(unix_socket[, options])
  • redis.createClient(redis_url[, options])
  • redis.createClient(port[, host][, options])

Tip:如果Redis服务器与客户机运行在同一台机器上,请考虑尽可能使用unix sockets来提高吞吐量。
注意:使用rediss://...作为redis_url时,将启用TLS socket来进行连接。另外,如果需要的话你还可以在options中设置其他TLS选项。

options选项
参数默认值说明
host127.0.0.1redis服务ip地址
port6379redis服务端口
pathnullredis服务UNIX socket串
urlnullredis服务url,接收格式为[redis[s]:]//[[user][:password@]][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]
string_numbersnull当是指为true时,Node Redis会将数据库中的数字转换成字符串。
return_buffersfalse如果设置为true时所有的callback中拿到的数据都会转换成Buffers
detect_buffersfalse如果设置为true时callback中拿到的数据都会转换成Buffers,不同于return_buffers作用在所有命令上,该选项可以让你在命令执行前切换返回格式。注意,这个选项在pubsub模式下不起作用,订阅还是会返回原先固定的String格式或者Buffers
socket_keepalivetrue当设置为true时,底层socket会启用keep-alive。
socket_initial_delay0单位为ms,这个选项也表示向redis发送信息的事件间隔。
no_ready_checkfalse当与Redis服务器建立连接时,服务器可能仍在从磁盘加载数据库。加载时,服务器不会响应任何命令。为了解决这个问题,Node Redis有一个“ready check”的机制,它向服务器发送INFO命令。INFO命令的响应指示服务器是否准备好接收更多命令。准备就绪后,Node Redis将发出ready事件。设置为true来禁止此检查。
enable_offline_queuetrue默认情况下,如果没有到Redis服务器的活动连接,则会将命令添加到队列中,并在建立连接后执行。设置为false将禁用此功能,回调将立即执行并抛出错误,如果未指定回调,则会发出错误。
retry_unfulfilled_commandsfalse如果设置成true,所有未执行的指令都会在连接重连时进行重试。如果使用状态状态更改命令(e.g. incr)时,请谨慎使用;如果使用了阻塞命令时这个选项尤其有用。
passwordnull如果设置了密码,客户端会在连接时自动运行auth命令。该选项也可以使用别名auth_pass,注意当Node Redis版本低于2.5时,该选项必须使用auth_pass
usernullACL用户,只有当password设置时才有用
dbnull如果不为空,则客户端在连接时会自动执行select命令
familyIPv4可设置为’IPv6’。
disable_resubscribingfalse如果设置为true,客户端会在连接中断时停止订阅
rename_commandsnull可以传入一个对象用于对命令进行重命名。例如你想重命名KEYS命令为DO-NOT-USE,你需要传入{ KEYS : “DO-NOT-USE” },详情请参考Redis security topics
tlsnull包含需要传给tls.connect选项的对象,用于创建Redis的TLS连接
prefixnull用于修改所有keys的前缀
retry_strategyfunction一个用于接收一个options对象作为参数的函数,options中包括attempt(重试次数)、total_retry_time(自上一次连接以来经过的重试总时间)、times_connected(连接的总次数)、error(连接断开的原因)。如果该函数返回一个Number类型,则重试将在该时间(单位ms)之后发生。如果返回的不是数字类型,则不会进行重试,所有未执行的命令都会抛出错误。
connect_timeout3600000单位ms,仅作为连接到redis服务的超时时间,但如果同时在retry_strategy中返回了一个Number,那么connect_timeout设置则会让retry_strategy中的设置失效。
参数示例代码

detect_buffers example:

  const redis = require("redis");
const client = redis.createClient({ detect_buffers: true });

client.set("foo_rand000000000000", "OK");

// This will return a JavaScript String
client.get("foo_rand000000000000", function(err, reply) {
  console.log(reply.toString()); // Will print `OK`
});

// This will return a Buffer since original key is specified as a Buffer
client.get(new Buffer("foo_rand000000000000"), function(err, reply) {
  console.log(reply.toString()); // Will print `<Buffer 4f 4b>`
});

retry_strategy example:

const client = redis.createClient({
  retry_strategy: function(options) {
    if (options.error && options.error.code === "ECONNREFUSED") {
      // End reconnecting on a specific error and flush all commands with
      // a individual error
      return new Error("The server refused the connection");
    }
    if (options.total_retry_time > 1000 * 60 * 60) {
      // End reconnecting after a specific timeout and flush all commands
      // with a individual error
      return new Error("Retry time exhausted");
    }
    if (options.attempt > 10) {
      // End reconnecting with built in error
      return undefined;
    }
    // reconnect after
    return Math.min(options.attempt * 100, 3000);
  },
});
client.auth(password[, callback])

当应用连接到redis服务时需要提供认证密码,auth命令必须在连接后第一时间调用。因为重连以及就绪监测难以协调,所以auth命令会保存密码然后再每一次连接及重连后发送密码到redis服务。callback函数只会调用一次,触发的时机在首次auth命令发送到服务器并返回结果时。注意,你不能在ready监听钩子中调用clien.auth否则会抛出一个错误Error: Ready check failed: ERR operation not permitted.

client.quit(callback)

向redis服务发送断开连接命令,在正确处理所有正在运行的所有命令之后平滑地断开连接。如果该命令在重连时被调用(重连时不存在redis连接),这个命令会立即停止连接,而不是导致再一次的重连,在这种情况下所有未被执行的指令都将抛出错误。

client.end(flush)

强行断开与redis服务的连接。注意,这个命令不会等待未返回的命令执行完毕。如果你想平滑地断开连接请使用client.quit。当你不是百分比确定其他的命令是否重要时,你可以把flush设置为true。如果flush被设置为false,那么正在执行的命令会立即抛出错误。

强行断开连接的例子,你特喵不会想这么做的。

const redis = require("redis");
const client = redis.createClient();

client.set("hello", "world", function(err) {
  // This will either result in an error (flush parameter is set to true)
  // or will silently fail and this callback will not be called at all (flush set to false)
  console.error(err);
});

// No further commands will be processed
client.end(true);

client.get("hello", function(err) {
  console.error(err); // => 'The connection has already been closed.'
});

client.end()不传flush参数时flush会被设置成true,在生产环境下需慎用。

错误类型

错误子类型如下:

  • RedisError:所有错误的父类
  • ReplyError:RedisError的子类,redis本身的错误
  • AbortError:RedisError的子类,当命令因某些因素未完成时抛出
  • ParserError:RedisError的子类,当发生解析错误时抛出
  • AggregateError:AbortError的子类,当命令回调中发生多个错误时抛出,这时不会抛出多个AbortError
例子
const assert = require("assert");

const redis = require("redis");
const { AbortError, AggregateError, ReplyError } = require("redis");

const client = redis.createClient();

client.on("error", function(err) {
  assert(err instanceof Error);
  assert(err instanceof AbortError);
  assert(err instanceof AggregateError);

  // The set and get are aggregated in here
  assert.strictEqual(err.errors.length, 2);
  assert.strictEqual(err.code, "NR_CLOSED");
});

client.set("foo", "bar", "baz", function(err, res) {
  // Too many arguments
  assert(err instanceof ReplyError); // => true
  assert.strictEqual(err.command, "SET");
  assert.deepStrictEqual(err.args, ["foo", 123, "bar"]);

  redis.debug_mode = true;

  client.set("foo", "bar");
  client.get("foo");

  process.nextTick(function() {
    // Force closing the connection while the command did not yet return
    client.end(true);
    redis.debug_mode = false;
  });
});

所有的ReplyError在抛出时都会带有命令名词以及参数

错误码

当客户端连接故障时,Node Redis 会返回一个NR_CLOSED错误码。当一个命令未被正确执行时会返回一个UNCERTAIN_STATE的状态码。CONNECTION_BROKEN错误码代表着Node Redis放弃重连。

client.unref()

调用client.unref()可以使程序在不挂起命令的情况下退出。
这是一个试验中的特性,并且只支持Redis协议的一个子集。一些需要保持客户端状态的命令,例如*SUBSCRIBE又或者一些带有阻塞的命令如BL*会在执行.unref()后停止工作

const redis = require("redis");
const client = redis.createClient();

/*
 * Calling unref() will allow this program to exit immediately after the get
 * command finishes. Otherwise the client would hang as long as the
 * client-server connection is alive.
 */
client.unref();

client.get("foo", function(err, value) {
  if (err) throw err;
  console.log(value);
});
Hash命令

很多的Redis命令使用单个字符或者是字符串作为参数或者是返回。在下面的这些api中处理hash值时有几个有用的方法。

client.hgetall(hash, callback)

HGETALL命令的返回中会被转换为一个对象,在这种情况下你可以使用JavaScript的语法

例如:

client.hmset("key", "foo", "bar", "hello", "world");

client.hgetall("key", function(err, value) {
  console.log(value.foo); // > "bar"
  console.log(value.hello); // > "world"
});
client.hmset(hash, key1, val1, ...keyN, valN, [callback])

可以通过多种方式设置多重值
例如:

//  key
//    1) foo   => bar
//    2) hello => world
client.HMSET("key", "foo", "bar", "hello", "world");

未完待续…

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值