2011-04-18 77 views
6

我试图在我的Redis上加载一些重负载用于测试目的,并找出任何上限。首先,我使用大小为32个字符的大小为32个字符的50,000和100,000个键来加载它。这两个密钥大小的时间不超过8-15秒。现在我试着把4kb的数据作为每个键的值。首先10000个按键需要800毫秒设置。但从这一点开始,它会逐渐减慢,并设置完整的50,000个按键需要40分钟。我正在使用带有node_redis (Mranney)的NodeJ加载数据库。我正在做什么错误,或者是Redis对于大小为4 KB的大值缓慢吗?Redis性能问题?

我现在发现的另外一件事情是,当我运行另一个客户端并行到当前的客户端并更新密钥时,第二个客户端在8秒钟内完成加载50000个密钥与4kb值,而第一个客户端仍然永远做它的事情。它是节点或Redis库中的错误吗?这是令人震惊的,并且不适合生产。

+0

您是否使用hiredis? – generalhenry 2011-04-18 23:16:15

+0

嗯..我安装hiredis,但我不知道它是否自动加载到程序中,当我需要('redis')。这是问题吗? – Lalith 2011-04-18 23:17:39

+0

要验证是否安装了hiredis模块,可以运行节点,然后执行'require(“hiredis”)'。 – 2011-06-30 19:23:37

回答

5

您需要为从节点到Redis的批量写入获得某种背压。默认情况下,节点将对所有写入进行排队,并且不对传出队列大小强制实施上限。

node_redis有一个“漏”事件,您可以监听以实现一些基本的背压。

+0

嗨马特,我试着查看client.command_queue.length并停止,直到我收到“漏”事件。 client.command_queue.length始终是0.所以我正在检查client.offline_queue.length,它给了我正确的数字,但漏失事件只被解雇了一次,我会再试一次,并回来与代码。谢谢。 – Lalith 2011-04-27 18:01:21

+0

我已附加代码在这里https://gist.github.com/945441。这似乎不是反压的正确方法? – Lalith 2011-04-27 23:11:23

+2

这里有几个不同的问题。首先是预连接命令排队。第二个是,一旦你有一个连接,另一个队列维护发送的命令,但尚未收到答复。我已经添加了一个处理这两种情况的一般方法的示例:https://github.com/mranney/node_redis/blob/master/examples/backpressure_drain.js – 2011-06-30 20:44:59

3

默认的redis配置没有针对这种用法进行优化。我怀疑你已经把它交换到32字节的页面大小的磁盘,这意味着每个添加的密钥必须找到128个连续的空闲页面,并且最终可能会使用系统虚拟机或需要扩展交换文件。

更新密钥时,空间已分配,因此您看不到任何性能问题。

+0

这只是为了测试目的,所以我不在乎。但是如果这种需求实时发生并且我的应用程序需要存储如此多的数据呢?有没有可以改变的配置以符合我的要求? – Lalith 2011-04-19 02:56:48

+0

甚至在第一个客户端创建所有50000个密钥之前如果我运行第二个客户端,它将继续并在第一个客户端之前完成。所以你所说的可能不是我所面临的问题。 – Lalith 2011-04-19 02:57:52

+3

页面大小和内存使用情况是可配置的 - 检查redis.conf中的注释。第二个客户端完成并不一定排除该情况 - 低内存条件和并发的组合可能变得相当复杂,特别是如果涉及超时和自动重试。例如,每次出现错误时是否可以重置所有以前的键? – 2011-04-19 04:37:28

0

因为我在NodeJs中做了很多set(Key value),这是异步完成的,所以很多套接字连接同时打开。 NodeJs套接字写入缓冲区可能会被重载,并且GC可能会来操作节点进程。

PS:我改变了redis内存的配置,Tom建议,但它仍然执行相同的操作。