【问题标题】:How slow is Redis when full and evicting keys ? (LRU algorithm)Redis 在满和驱逐键时有多慢? (LRU算法)
【发布时间】:2013-12-29 16:13:05
【问题描述】:

我在 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 少得多,而且 key 完全不同。当 Redis 达到最大内存(并且 LRU 算法开始驱逐键)时,redis 确实删除了几乎所有 db1 键,这大大减慢了所有调用。这是一种奇怪的行为,可能不寻常,并且可能与我们的应用程序有关。我们通过为 db1 中加载的键移至另一种(更好的)内存机制来解决此问题。

谢谢!

【问题讨论】:

    标签: caching redis


    【解决方案1】:

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

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

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

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

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

    • 145 Kops/s 当没有驱逐发生时
    • 当 50% 驱逐发生时为 125 Kops/s(即 1 个密钥超过 2 个被驱逐)。

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

    减少驱逐开销的明显建议是减少 maxmemory-samples,但这也意味着准确度的急剧下降。

    我的建议是尝试一下 memcached。 LRU 机制不同。它仍然不准确(它仅适用于每个平板),但它可能会在这个用例上提供比 Redis 更好的结果。

    【讨论】:

    • 谢谢迪迪埃。我们仍在调查这个问题,但似乎还有其他原因导致了这种放缓。我们实际上在redis中使用了2个DB,当达到max memory时似乎有一个奇怪的行为。当我们有它时,我会发布更多细节。我将等待其他可能的答案并验证您的回复。
    • @Ashish 实际上,我们发现 LRU 机制适用于两个数据库,如果你有一个大数据库和一个小数据库,那么小数据库很快就会被LRU。例如,当 mamemory-sample 为 3 时,LRU 似乎从大 DB 中获取 2 个样本,从小 DB 中获取 1 个样本,即使它小了 10000 倍。因此,我们再次通过在我们的 redis 实例中只有一个数据库来解决这个问题。
    • @Pixou,是的,拥有一个数据库是有意义的。应用实例只需要一个连接,而且redis就像基于事件的单线程。
    • @Pixou,根据文档,LRU 约为。算法&如果你增加内存采样,它将花费更多的 CPU 周期。
    【解决方案2】:

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

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

    【讨论】:

    • 确实如此,但请注意密钥过期和驱逐是两件不同的事情。
    猜你喜欢
    • 1970-01-01
    • 2016-06-20
    • 2013-01-31
    • 2020-02-08
    • 1970-01-01
    • 2015-04-20
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多