2012-04-06 116 views
3

如果redis获取超载,我可以配置它以放弃设置请求吗?我有一个应用程序,实时更新大量项目的数据(每个项目每秒10-15次)。这些值很快就过时了,我不需要任何形式的一致性。当redis重载时会发生什么?

我也想计算实时写入的值的并行总和。这里最好的选择是什么? LUA在redis中执行?使用UNIX套接字与redis位于同一个盒子中的小应用程序?

回答

1

当Redis变得过载时,它只会减慢其客户端速度。对于大多数命令,协议本身是同步的。

尽管Redis支持流水线,但客户端无法取消仍在流水线中的流量,但尚未被服务器确认。 Redis本身并不真正排队传入的流量,TCP堆栈就是这样做的。

因此,无法配置Redis服务器以放弃设置的请求。但是,它可以实现对客户端的最后一个值队列:

  • 队列实际上是一个由2张地图由您的项目(每个项目只存储一个值)索引表示。主要地图将被应用程序使用。辅映射将被特定的线程使用。 2个地图内容可以以原子方式交换。

  • 当主映射为空时,特定线程将被阻塞。如果不是,则交换两个映射的内容,使用主动流水线和可变参数命令将辅助映射的内容异步发送到Redis。它也收到Redis的确认。

  • 当线程与辅助地图一起工作时,应用程序仍然可以填充主地图。如果Redis速度太慢,应用程序将只会累积主映射中的最后一个值。

这个策略可以在C中用hiredis和你选择的事件循环来实现。

然而,这不是微不足道的实施,所以我会首先检查Redis对全部的性能是否不足以达到我的目的。这些日子里Redis以超过500K的操作系统(使用单核)进行基准测试并不罕见。如果需要,没有什么能阻止你在多个Redis实例上分割你的数据。

您可能会在Redis服务器的CPU之前饱和网络链接。这就是为什么最好在客户端而不是服务器端实现最后一个值队列(如果需要的话)。

关于总和计算,我会尽量计算和实时维护它。例如,GETSET命令可用于在返回前一个值时设置新值。

而不是只需设置你的价值观,你可以这样做:

[old value] = GETSET item <new value> 
INCRBY mysum [new value] - [old value] 

的mysum键将包含值的总和在任何时候的所有项目。使用Redis 2.6,您可以使用Lua来安装此计算以节省往返时间。

运行一个大批量计算现有数据的统计数据(这是我理解你的“并行”总和)并不真的适合Redis。它不是为计算映射/减少而设计的。

+0

是的,它不是我担心的CPU,而是网络链接。我将在云托管环境中运行这个应用程序,销售代表告诉我他们的云实例只有100MB/s,这似乎可怜。 – jz87 2012-04-07 02:41:57

+0

对于同步协议,我认为客户端的最后一个值队列是您建议的最佳选项。我担心这个协议会是异步的,在这种情况下这会更困难。 – jz87 2012-04-07 02:43:32

相关问题