【问题标题】:Pitfalls with local in memory cache invalidated using RabbitMQ使用 RabbitMQ 使本地内存缓存失效的陷阱
【发布时间】:2014-02-01 14:59:28
【问题描述】:

我有一个 java web 服务器,目前正在使用 Guava 库来处理我大量使用的内存缓存。我现在需要扩展到多台服务器(2+)以进行故障转移和负载平衡。在此过程中,我改为从进程内缓存切换到 Memcache(外部服务)。但是,结果并没有给我留下太深刻的印象,因为现在几乎每次调用,我都必须对另一台服务器进行外部调用,这比内存缓存慢得多。

我想代替从 Memcache 获取数据,我可以继续在每台服务器上使用本地缓存,并在需要更新缓存时使用 RabbitMQ 通知其他服务器。因此,如果一个服务器对底层数据进行了更改,它也会向所有其他服务器广播一条消息,告诉他们他们的缓存现在无效。每个服务器都在广播和监听缓存失效消息。

有人知道这种方法的任何潜在缺陷吗?我有点紧张,因为我找不到其他人在生产中这样做。我看到的唯一问题是每个服务器都需要更多内存(内存缓存),并且任何给定的服务器可能需要更长的时间才能获取更新的数据。还有什么?

【问题讨论】:

  • 我发现 DZone 上的这个 article 很有帮助,但它没有解决向其他系统发送消息以保持缓存一致的问题。
  • 请详细说明您的设置。如果您看到响应时间为 250-350 毫秒,则说明您的缓存/服务器配置存在问题。

标签: web-services memcached rabbitmq guava memorycache


【解决方案1】:

我对你的问题有点困惑,所以我将以一种对我有意义的方式重申,然后回答我对你问题的版本。如果我与您的想法不一致,请随时发表评论。

您有一个使用进程本地内存缓存来存储数据的 Web 应用程序。您希望扩展到多个节点并为您的程序保持相同的结构,而不是依赖具有内置缓存复制的 3rd 方工具(memcached、Couchbase、Redis)。因此,您正在考虑使用 RabbitMQ 自行滚动,将更改发布到各个节点,以便它们可以相应地更新本地缓存。

我最初的反应是,最好通过滚动到上述工具之一来完成您想要做的事情。除了涉及到明显的开发和严格的测试之外,Couchbase、Memcached 和 Redis 都旨在解决您遇到的问题。

此外,理论上,当您水平扩展时,您的应用程序节点中的可用内存会用完,然后您将真的一团糟。一旦到了这一限制使您的应用程序不可行的地步,您最终还是会使用其中一种工具,此时您为设计自定义解决方案所做的所有努力都将付诸东流。

我能想到的唯一例外情况是,如果您的应用程序是计算密集型的并且不使用太多内存。在这种情况下,我认为基于 RabbitMQ 的解决方案很简单,但是如果 RMQ 中丢失消息,您有时需要制定某种程序来同步服务器之间的缓存。您还需要一种处理节点启动和关闭的方法。

编辑

考虑到您在 cmets 中的声明,即您看到访问时间在数百毫秒内,我建议您首先检查您的设置。来自 Memcached(或 Couchbase 或 Redis 等)实例的缓存中单个项目的典型读取时间是亚毫秒(如果我没记错的话,大约是 0.1 毫秒),所以你的缓存服务器的“问题孩子”就性能而言,它比它应该达到的水平高出几个数量级。从那里开始,然后看看你是否还有同样的问题。

【讨论】:

  • 有道理,但这不完全是我的问题。我的原始缓存是进程本地(将 Guava 缓存视为地图或字典)。它没有任何内置机制来扩展到多个节点。 Memcache 确实有这个功能,这就是我切换到它的原因,但是现在缓存不是我的 Web 服务器本地的,它位于另一台机器上,这会减慢速度。
  • 有什么原因你不能在 web 服务器上运行 memcached 吗?
  • 一些 memcached 客户端保持与服务器的连接打开以优化响应时间;我正在为您的用例苦苦挣扎,即十分之几毫秒足以导致性能明显下降。你能详细说明一下吗?
  • @ChrisJohnson 我真的很喜欢你在同一台服务器上运行 memcached 的建议,我会试试的。
  • @rmayer06 每次调用 memcache 大约需要 150 到 200 毫秒(几乎所有时间都花在了网络请求上)。由于我现在只将模型存储在缓存中,因此某些请求需要 2 次调用(序列化),因为我需要第一个模型来确定第二次调用要获取什么模型。
【解决方案2】:

我们对只读数据使用类似的东西,不需要每次都更新。我怀疑,这对你来说是个好计划。试想一下,您应该在每个实例上再添加一项服务,该服务将监控队列并处理对内存存储的更改。这很难测试。

您确定大部分时间都花在了服务器之间的通信上吗?也许你打了多个电话?

【讨论】:

    猜你喜欢
    • 2019-07-01
    • 2010-12-03
    • 1970-01-01
    • 2011-12-15
    • 2017-09-08
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多