使用RabbitMQ使本地内存缓存中的陷阱失效

时间:2014-01-13 18:19:58

标签: web-services memcached rabbitmq guava memorycache

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

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

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

2 个答案:

答案 0 :(得分:6)

我对你的问题有点困惑,所以我会以对我有意义的方式重述,然后​​回答我的问题版本。如果我不符合您的想法,请随时发表评论。

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

我最初的反应是,你想要做的最好是通过滚动到上面提到的工具之一。除了明显的开发和严格的测试外,Couchbase,Memcached和Redis都旨在解决您遇到的问题。

另外,从理论上讲,当你水平扩展时,你的应用程序节点中的可用内存会耗尽,然后你真的会弄得一团糟。一旦你达到这个限制使你的应用程序不可行的程度,你最终将使用其中一个工具,此时你所有努力设计自定义解决方案都是徒劳的。

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

修改

考虑到您在评论中声明您看到数百毫秒的访问时间,我建议您首先检查您的设置。从Memcached(或Couchbase或Redis等)实例缓存中的单个项目的典型读取时间是亚毫秒(如果我没记错的话,大约.1毫秒),因此缓存服务器的“问题子”在性能方面应该是几个数量级。从那里开始,看看你是否还有同样的问题。

答案 1 :(得分:1)

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

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