完全驱逐密钥时Redis的速度有多慢? (LRU算法)

时间:2013-12-11 15:38:50

标签: caching redis

我在Java应用程序中使用Redis,我正在读取日志文件,在Redis中为每个日志存储/检索一些信息。密钥是我的日志文件中的IP地址,这意味着它们始终是新闻密钥,即使它们经常出现。

在某些时候,Redis达到了它的最大大小(在我的情况下为3gb),并开始驱逐一些键。我使用“allkeys-lru”设置,因为我想保留最年轻的密钥。

然后整个应用程序放慢了很多,比开始时长5倍。 所以我有三个问题:

  • 如此急剧减速(5倍以上)是正常的吗?有人经历过这样的放缓吗?如果没有,我的代码可能会有另一个问题(因为当Redis达到极限时,减速就会出现,这是不可能的)
  • 我可以改善配置吗?我试图改变maxmemory-samples设置但没有太大成功
  • 我应该考虑替代我的特定问题吗?是否有内存数据库可以处理具有更好性能的驱逐键?我可能会考虑一个纯Java对象(HashMap ...),即使它看起来不像一个好的设计。

编辑1: 我们在Redis中使用2个数据库

编辑2: 我们使用redis 2.2.12(ubuntu 12.04 LTS)。进一步的调查解释了这个问题:我们在redis中使用db0和db1。 db1的使用远小于db0,键完全不同。当Redis达到max-memory(并且LRU algo开始驱逐密钥)时,redis会删除几乎所有db1密钥,这会大大减慢所有调用。这是一种奇怪的行为,可能不常见,可能与我们的应用程序有关。我们通过转移到db1中加载的密钥的另一个(更好的)内存机制来修复该问题。

谢谢!

2 个答案:

答案 0 :(得分:9)

我不相信Redis是您用例的最佳选择。

Redis“LRU”只是一种尽力而为的算法(即距离精确的LRU相当远)。 Redis跟踪内存分配并知道何时必须释放一些内存。在执行每个命令之前检查这一点。在“allkeys-lru”模式中驱逐密钥的机制在于选择maxmemory-samples随机密钥,比较它们的空闲时间,并选择最多空闲密钥。 Redis重复这些操作,直到使用的内存低于maxmemory。

maxmemory-samples越高,CPU消耗越多,但结果越准确。

如果您没有明确使用EXPIRE命令,则没有其他开销与密钥驱逐相关联。

在我的机器上使用Redis基准测试运行快速测试会产生以下吞吐量:

  • 未发生驱逐时的145 Kops / s
  • 当发生50%的驱逐时,
  • 125 Kops / s(即逐出2的1键)。

我无法重现您经历的5倍因素。

减少驱逐开销的明显建议是减少maxmemory样本,但这也意味着准确性的显着降低。

我的建议是尝试memcached。 LRU机制不同。它仍然不准确(它只适用于每个平板),但它可能会给Redis带来更好的结果。

答案 1 :(得分:0)

您使用的是哪个版本的Redis? 2.8版本(最新版本)改进了到期算法,如果你使用的是2.6,你可以尝试一下。

http://download.redis.io/redis-stable/00-RELEASENOTES