12

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

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

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

4

2 回答 2

6

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

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

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

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

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

编辑

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

于 2014-01-18T05:07:27.190 回答
1

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

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

于 2014-01-18T00:51:55.230 回答