redis中pipeline详解

1. 什么是Redis pipeline

Redis是一款高速内存缓存数据库,在应用场景里经常使用到它的pipeline技术。所谓redis pipeline就是将多条命令一次性通过网络发送到redis服务器上,减少网络往返所需的时间。

1.1 pipeline的优点

Redis一般使用一条一条命令执行,当需要执行大量短时间内请求时,通常使用pipeline技术,它的优点主要有:

减少网络往返所需时间

有效降低Redis的QPS(Questions Per Second)

减少Redis服务端的压力,提高并发能力

1.2 pipeline的缺点

虽然pipeline提供了快速执行多个命令的方法,但同时也存在缺点

同一条消息中的命令不能有返回结果(除了订阅和退订命令)

服务器需要等待客户端所有的指令请求都发送过来后才能处理请求,如果指令太多可能会一定程度降低整个系统的并发能力

2. Redis开启pipeline方法

Redis的pipeline有两种方式开启

2.1 使用redis的管道对象

const { promisify } = require("util");

const redis = require("redis");

const client = redis.createClient();

const pipeline = client.pipeline(); // 创建pipeline对象

pipeline.incr("incr1");

pipeline.incr("incr2");

const execPromisified = promisify(pipeline.exec).bind(pipeline); // promisify

execPromisified().then((results) => {

console.log(results);

client.quit(); // 执行完毕退出redis

});

2.2 使用node_redis库的send_command方法

const { promisify } = require("util"); // 使用promisify

const redis = require("redis");

const client = redis.createClient();

const execMultiCommands = async (cmds) => {

const { sendCommand } = client;

const multi = client.multi(); // multi一次性发送多条命令

cmds.forEach(({ cmd, args }, index) => {

const method = multi[cmd];

if (method) {

method.apply(multi, args);

} else {

sendCommand.apply(client, [{ name: cmd, args }]); // 直接sendCommand

}

});

console.time("exec");

const result = await promisify(multi.exec).call(multi); // 返回结果

console.timeEnd("exec");

console.log("[execMultiCommands result]:", result);

return result;

};

execMultiCommands([

{ cmd: "incr", args: ["incr1"] },

{ cmd: "incr", args: ["incr2"] },

]);

3. pipeline的使用场景

Redis中的pipeline技术通常在以下场景被广泛应用:

3.1 批量插入数据

Redis的插入速度非常快,但是在批量大量数据插入的时候,pipeline是提高效率的绝佳选择

const pip = redisClient.pipeline();

for (let index = 0; index < 5000; index++) {

const keyName = "myKey" + index;

const valueName = "myValue" + index;

pip.set(keyName, valueName);

}

pip.exec((err, result) => {

// 插入完毕

});

3.2 多个命令串行执行

Redis支持事务处理,为了保证一组命令的原子性可以使用pipeline技术。

 

const script = new RedisScript('

redis.call('set', KEYS[1], ARGV[1]);

redis.call('set', KEYS[2], ARGV[2]);

return "OK";

');

const pip = redisClient.pipeline();

script.pip(pip, [ 'key1', 'key2' ], [ 'value1', 'value2' ]);

pip.exec();

4. 总结

4.1 pipeline的优点

pipeline是在减少redis压力的同时同时提高redis的处理速度的非常不错的方法

4.2 pipeline的缺点

Redis pipeline同时存在一定的缺点,比如同一条消息中的命令不能有返回结果(除了订阅和退订命令),而且服务器需要等待客户端所有的指令请求都发送过来后才能处理请求,如果指令太多可能会一定程度降低整个系统的并发能力。

4.3 pipeline的使用场景

Redis中的pipeline技术通常在以下场景被广泛应用:批量插入数据;多个命令串行执行等等。

数据库标签