嗨,大家好,
如何以编程方式在 node_redis 中启用流水线?
我看到文档说在大多数情况下它会自动发生 - 我想了解有没有办法在 node_redis 中以编程方式从应用程序代码中强制它
[ ec2-user@devops ~]$ redis-benchmark -n 100000 -t set,get -P 16 -q -h 10.0.1.10
SET:每秒 199600.80 个请求
GET:每秒 193050.19 个请求
[ ec2-user@devops ~]$ redis-benchmark -n 100000 -t set,get -q -h 10.0.1.12
SET:每秒 14098.41 个请求
GET:每秒 13743.82 个请求
它在 Redis 节点上相差 10 倍以上。
谢谢,
德米特里
是通过 client.multi 和 multi.exec 命令完成的吗?
嗨@saritasa - 流水线是自动的。 它总是发生在客户端内部。 您不需要使用 multi 或 exec 来启用它。
嗨,布莱斯,
谢谢,
德米特里
谢谢 Bryce,我了解http://redis.io/topics/pipelining 的工作原理。 在 node.js 应用程序中 - 应如何构建代码以便对请求进行流水线处理?
所以在下面的例子中
hgetall & expire - 是否流水线化? 其中一个调用是内部回调。
函数 getByID(table, id, next) {
if (!success) return setTimeout(function () {
getByID(table, id, next);
}, 2000);
var end = utils.getEndTime(),
base = getBase(),
client = getClient(PK2str(table, id)),
key = getHashID(table, id);
base.sismember(table, key, function (err, val) {
if (err || !val) return next();
client.hgetall(key, function (err, val) {
if (err || !val) return next(new Error('Expired'), id);
val = arrays_parse(table, val);
next(null, val);
client.expire(key, cfg.ttl.shards);
if (!exports.silent) {
profiler.log('cache', {
'table': table,
'id': key,
'method': 'getByID',
'data': val,
'time': end()
});
}
});
});
}
所有命令都是“流水线”发送的,但由于一两个原因,这些命令永远不会在同一个流水线写帧中发送:
base
和client
是不同的 Redis 客户端,它们可能_NEVER_共享相同的管道。命令需要从相同的上下文* 执行才能看到流水线的任何好处。 例如类似于 redis 流水线文档中的 PING 示例:
// These commands will all be pipelined together:
client.ping()
client.ping()
client.ping()
client.ping(function () {
// This would *NEVER* be in the same pipeline frame as the other four because it requires a reply to be received first
client.ping()
})
* 或者如果发送速度比 Redis 回复速度快,则从单独的上下文中发送,但从不回复相关上下文
现在知道了 - 谢谢! 这是非常有价值的评论!
我认为node_redis“自动流水线”不是redis官方提到的流水线。
这个时间称为RTT(往返时间)。 当客户端需要连续执行许多请求时(例如,将许多元素添加到同一个列表,或使用许多键填充数据库),很容易看出这会如何影响性能。 例如,如果 RTT 时间为 250 毫秒(在 Internet 上的链接非常慢的情况下),即使服务器能够每秒处理 10 万个请求,我们也将能够每秒最多处理四个请求。
如果使用的接口是环回接口,则RTT要短得多(例如我的主机报告ping 127.0.0.1 0,044毫秒),但如果您需要连续执行多次写入,它仍然很多。
官方redis的pipelining的意思是将多个命令组合起来,发送一次,以抵消RTT造成的延迟,node_redis没有解决这个问题。 而 node_redis 中的“自动流水线”实际上是通过使用 Node 的异步编程模型在同一时间发送尽可能多的命令。
这是一篇讨论这个问题的好文章。 http://informatikr.com/2012/redis-pipelining.html
@Vizwind @saritasa .multi和 .batch 都使用流水线作为从 2.2 版开始的想法。
最有用的评论
所有命令都是“流水线”发送的,但由于一两个原因,这些命令永远不会在同一个流水线写帧中发送:
base
和client
是不同的 Redis 客户端,它们可能_NEVER_共享相同的管道。命令需要从相同的上下文* 执行才能看到流水线的任何好处。 例如类似于 redis 流水线文档中的 PING 示例:
* 或者如果发送速度比 Redis 回复速度快,则从单独的上下文中发送,但从不回复相关上下文