gpt4 book ai didi

java - 在两台服务器之间同步缓存数据的最佳方式

转载 作者:行者123 更新时间:2023-12-03 12:50:27 25 4
gpt4 key购买 nike

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

5年前关闭。




Improve this question




想要在两台服务器之间同步缓存数据。两个数据库共享同一个数据库,但为了更好地执行数据,我在启动时将数据缓存到哈希映射中。
因此希望在不重新启动服务器的情况下同步缓存的数据。 (两台服务器同时启动)。

请建议我最好和最有效的方法。

最佳答案

与其尝试在两个服务器实例之间同步缓存数据,为什么不使用 memcached/couchbase 或 redis 之类的东西来集中缓存?将分布式缓存与 ehcache 之类的东西一起使用要复杂得多,而且容易出错 IMO 与使用提到的缓存服务器集中缓存数据相比。

作为我原始答案的附录,在决定使用哪种缓存方法(在内存中,集中式)时,需要考虑的一件事是正在缓存的数据的易变性。

如果数据存储在 DB 中,但在服务器加载后没有更改,那么您甚至不需要服务器之间的同步。只需让他们每个人从源代码将这些静态数据加载到内存中,然后就可以尽情享受他们所做的一切。数据不会改变,因此无需引入复杂的模式来保持服务器之间的数据同步。

如果数据中确实存在一定程度的波动性(例如说您正在缓存从数据库中查找的实体数据以将命中保存到数据库中),那么我仍然认为集中式缓存是比内存中分布式更好的方法,并且同步缓存。您只需要确保对缓存数据使用适当的过期时间,以允许不时自然刷新数据。此外,您可能只想在特定实体的更新路径中删除集中存储中的缓存数据,然后在下一次请求该数据时从缓存中重新加载它。这比尝试执行真正的直写缓存要好,在这种缓存中,您可以同时写入底层存储和缓存。 DB 本身可能会对数据进行调整(例如,通过默认未提供的值),并且在这种情况下您的缓存数据可能与 DB 中的数据不匹配。

编辑 :

在评论中提出了一个关于集中式缓存的优点的问题(我猜测类似于内存中的分布式缓存)。我会就此发表我的意见,但首先是标准的免责声明。集中缓存不是万能的。它旨在解决与 in-jvm-memory 缓存相关的特定问题。在评估是否切换到它之前,您应该先了解您的问题是什么,看看它们是否符合集中缓存的好处。集中缓存是一种架构变化,它可能会带来自己的问题/警告。不要因为有人说它比你正在做的更好而转向简单。确保原因适合问题。

好的,现在我对集中式缓存可以解决哪些类型的问题与 jvm 内存(以及可能的分布式)缓存有什么看法。我将列出两件事,尽管我确信还有更多。我的两个大的是:整体内存占用 数据同步问题 .

让我们从 开始整体内存占用 .假设您正在执行标准实体缓存以保护您的关系数据库免受过度压力。假设您有大量数据要缓存以真正保护您的数据库;说在许多 GB 的范围内。如果您正在进行 jvm 内存缓存,并且您说有 10 个应用程序服务器框,则需要为每个需要在 jvm 中进行缓存的框获得额外的内存 ($$$) 乘以 10内存。此外,您必须为 JVM 分配更大的堆以容纳缓存数据。我的观点是 JVM 堆应该小而精简,以减轻垃圾收集负担。如果您有大量的 Old Gen 无法收集,那么当它进入完整的 GC 并试图从膨胀的 Old Gen 空间中回收一些东西时,您将给垃圾收集器带来压力。你想避免长时间的 GC2 暂停时间,并且让你的 Old Gen 膨胀无济于事。另外,如果您的内存需求高于某个阈值,并且您的应用层碰巧运行 32 位机器,则您必须升级到 64 位机器,这可能是另一个令人望而却步的成本。

现在,如果您决定集中缓存数据(使用 Redis 或 Memcached 之类的东西),您可以显着减少缓存数据的整体内存占用,因为您可以将它放在几个盒子上,而不是将它放在所有应用服务器盒子上应用层。您可能希望使用集群方法(两种技术都支持它)和至少两台服务器来为您提供高可用性并避免缓存层中的单点故障(稍后会详细介绍)。通过拥有几台机器来支持缓存所需的内存要求,您可以节省一些可观的 $$。此外,您现在可以对应用程序框和缓存框进行不同的调整,因为它们服务于不同的目的。应用程序盒可以针对高吞吐量和低堆进行调整,缓存盒可以针对大内存进行调整。拥有更小的堆肯定有助于提高应用层框的整体吞吐量。

现在是集中式缓存的一个快速要点。您应该以这样一种方式设置您的应用程序,使其在没有缓存的情况下可以继续存在,以防它在一段时间内完全关闭。在传统的实体缓存中,这意味着当缓存完全不可用时,您只是直接针对每个请求访问数据库。不是很棒,但也不是世界末日。

好的,现在是 数据同步问题 .使用分布式 jvm 内存缓存,您需要保持缓存同步。一个节点中缓存数据的更改需要复制到其他节点并同步到它们的缓存数据中。这种方法有点可怕,因为如果由于某种原因(例如网络故障)其中一个节点不同步,那么当请求到达该节点时,用户看到的数据与当前在D B。更糟糕的是,如果他们发出另一个请求并命中不同的节点,他们将看到不同的数据,这会让用户感到困惑。通过集中数据,您可以消除这个问题。现在,人们可能会争辩说,集中式缓存需要对同一缓存数据键的更新进行并发控制。如果两个并发更新针对同一个 key ,您如何确保这两个更新不会相互干扰?我的想法是不要担心这个;当发生更新时,从缓存中删除该项目(并直接写入数据库)并让它在下次读取时重新加载。这种方式更安全、更容易。如果您不想这样做,那么您可以使用 CAS(Check-And-Set)功能代替乐观并发控制,如果您真的想在更新时同时更新缓存和数据库。

总而言之,如果您将它们缓存的数据集中起来,您可以节省资金并更好地调整您的应用层机器。您还可以获得更高的数据准确性,因为您需要处理的数据同步问题更少。我希望这有帮助。

关于java - 在两台服务器之间同步缓存数据的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16585798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com