Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Redis 1+;对包含15个较大JSON对象的列表的最小查询时间(总计20MB)_Redis - Fatal编程技术网

Redis 1+;对包含15个较大JSON对象的列表的最小查询时间(总计20MB)

Redis 1+;对包含15个较大JSON对象的列表的最小查询时间(总计20MB),redis,Redis,我使用Redis缓存数据库插入。为此,我创建了一个列表缓存,将序列化的JSON列表推送到其中。在伪代码中: let entries = [{a}, {b}, {c}, ...]; redis.rpush("CACHE", JSON.stringify(entries)); 我们的想法是运行这段代码一个小时,然后稍后再执行一次测试 let all = redis.lrange("CACHE", 0, LIMIT); processAndInsert(all); redis.ltrim("CACH

我使用Redis缓存数据库插入。为此,我创建了一个列表
缓存
,将序列化的JSON列表推送到其中。在伪代码中:

let entries = [{a}, {b}, {c}, ...];
redis.rpush("CACHE", JSON.stringify(entries));
我们的想法是运行这段代码一个小时,然后稍后再执行一次测试

let all = redis.lrange("CACHE", 0, LIMIT);
processAndInsert(all);
redis.ltrim("CACHE", 0, all.length);
现在的问题是,每个
条目可以相对较大(但远低于512MB/我读到的Redis限制)。
a,b,c
中的每一个都是一个大约20字节的对象,而
条目本身可以轻松地拥有100k+对象/2MB

我现在的问题是,即使是非常短的
缓存
只列出了15个条目,一个简单的
lrange
也可能需要很多分钟(!),即使是从
redis cli
(我的
node.js
实际上会因“致命错误:调用和重试上次分配失败-内存不足”而死亡,但这只是一个旁注)

列表的调试输出如下所示:

127.0.0.1:6379> debug object "CACHE"
Value at:00007FF202F4E330 refcount:1 encoding:linkedlist serializedlength:18104464 lru:12984004 lru_seconds_idle:1078
发生了什么事?为什么这么慢,我能做些什么?这似乎不是一个正常的缓慢,似乎是根本错误的东西


顺便说一句,我正在一台相对硬核的Windows 10游戏机(i5、16GB RAM、840 EVO SSD等)上使用本地Redis 2.8.2101(x64)、ioredis 1.6.1、node.js 0.12。

Redis擅长做很多小操作, 但不太擅长做少量“非常大”的业务

我认为您应该重新评估您的算法,并尝试将数据分成更小的块。不仅可以节省带宽,而且不会长时间锁定redis实例。 Redis提供了许多数据结构,您应该能够使用它们对数据进行更精细的控制

不过,在这种情况下,由于您在本地运行redis,并且假设您只运行此代码,那么我怀疑带宽和redis是否是问题所在。我更倾向于这样想:

JSON.stringify()
是你看到执行缓慢的罪魁祸首

20MB字符串的JSON序列化并不简单, 该过程需要分配许多小字符串,还必须遍历所有数组并逐个检查每个项目。对于像这样的大物体来说,所有这些都需要很长时间


同样,如果您正在分解数据,并使用redis执行较小的操作,则根本不需要JSON序列化程序

您是否考虑过使用redis的
Hash
数据类型,而不是使用
JSON.stringify()
?您可以使用MULTI命令单独保存所有哈希,然后将这些哈希的键存储在列表中。(多重指挥将在一次往返中完成)。嗯,这会带来什么好处?难道我不应该在RPUSH中使用MULTI吗?这就是我的意思,抱歉,首先使用MULTI命令保存散列,然后将它们的键添加到列表中。但是,我不得不问,是否有理由将整个缓存存储在一个密钥中,然后每次都检索整个缓存?传输非常大的数据可能会带来巨大的性能成本。也许可以在这里添加
SLOWLOG GET
的输出。我刚刚测试了它,结果如下(在我5岁的旧笔记本上):
创建(107毫秒),大小:2097152个元素
字符串化(2043毫秒),大小:228589569字节
转换回(3527毫秒),大小:2097152个元素
。(
guid()。我刚刚意识到这些时间是200MB,而不是20MB。好吧,200MB可能会把你推到Redis的极限。不过,您需要重新构建算法。保存所有内容和恢复所有内容是不可扩展的。