为什么使用ioredis从redis查询相对较大的字符串时会有越来越长的时间延迟?

fnvucqvd  于 12个月前  发布在  Redis
关注(0)|答案(1)|浏览(98)

在node中使用ioredis,我从redis中获得了一个大约100kb的值,这是一个相当大的次数(由于使用,在生产中)。我看到的是,每次后续的get都比前一次的get稍微长一点。
我正试图了解这是什么原因,以便我可以决定如何处理这个问题。
我有一个脚本来复制我在底部看到的内容。获得200次值的结果如下所示:

0: time: 43ms
1: time: 45ms
2: time: 50ms
...
199: time: 234ms

字符串
你可以看到它在200次获取后就变成了6倍。我甚至发现第一次延迟出奇的长,43毫秒,我在redis主机上运行脚本,所以没有延迟。
脚本(当然需要更新redis连接细节):

import Redis from "ioredis";

const con = await new Redis({
  port: 6379,
  host: "somehost",
  family: 4,
  password:
    "somepassword",
  db: 5,
});

con.on("ready", function () {
  console.log("REDIS is ready for action");
});

// sleep for 1 sec to be sure redis is ready for action
await new Promise((resolve) => setTimeout(resolve, 1000));

// store a 100k value in redis
const key = "some:test:key";
const value = "a".repeat(100000);
await con.set(key, value);

// get the value asynchronously 200 times, log the time it took
for (let i = 0; i < 200; i++) {
  let t1 = Date.now();
  con.get(key).then((value) => {
    let t2 = Date.now();
    console.log(`${i}: time: ${t2 - t1}ms`);
  });
}

yzuktlbb

yzuktlbb1#

我认为这是因为你的循环中的Promises和JavaScript是单线程的事实。
实际上,你并不是调用一次Redis,记录一次响应,然后重复200次。相反,你向Redis调用了200次,然后在它们返回时记录。由于JavaScript是单线程的,它一次只能返回其中一个。
查看您的日志,看起来第一次调用需要一点时间-这似乎是合理的-但随后的调用只需要几毫秒。
你可以使用Redis benchmark tool来确认这不是Redis。我在本地机器上运行了一个14 MB的镜像文件,得到了以下结果:

$ redis-cli -x set test-key < really-big-image.png 
OK

$ redis-benchmark -n 200 -q script load "redis.call('get','test-key')"
script load redis.call('get','test-key'): 12500.00 requests per second, p50=1.303 msec

字符串
它立即返回,没有明显的延迟。

相关问题