3

如果 redis 过载,我可以将其配置为丢弃集合请求吗?我有一个应用程序可以实时更新大量项目的数据(每个项目每秒 10-15 次)。这些值很快就过时了,我不需要任何一致性。

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

4

1 回答 1

1

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

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

所以不可能配置 Redis 服务器来丢弃集合请求。但是,可以在客户端实现最后一个值队列:

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

  • 当主映射为空时,特定线程正在阻塞。如果不是,它会交换两个映射的内容,使用激进的流水线和可变参数命令将辅助映射的内容异步发送到 Redis。它还接收来自 Redis 的 ack。

  • 当线程正在使用辅助地图时,应用程序仍然可以填充主地图。如果 Redis 太慢,应用程序只会在主映射中累积最后的值。

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

但是,实现起来并非易事,所以我会首先检查 Redis 对所有流量的性能是否不足以达到我的目的。如今,以超过 500K op/s 的速度对 Redis 进行基准测试并不少见(使用单核)。如果需要,没有什么可以阻止您将数据分片到多个 Redis 实例上。

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

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

您可以执行以下操作,而不仅仅是设置您的值:

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

mysum 键将随时包含所有项目的值的总和。使用 Redis 2.6,您可以使用 Lua 封装此计算以节省往返。

运行大批量来计算现有数据的统计信息(这就是我理解您的“并行”总和的方式)并不适合 Redis。它不是为类似 map/reduce 的计算而设计的。

于 2012-04-06T09:22:49.587 回答