S.O*_*O.S 6 java caching rabbitmq cassandra apache-kafka
I\xe2\x80\x99m 使用ScyllaDB / Cassandra作为全局分布式数据存储,使用Caffeine、Infinispan和Hazelcast作为本地内存缓存。
\n我有一个在 1,000 个节点上运行的应用程序。当节点从全局分布式数据存储请求数据时,数据会使用 Caffeine / Infinispan 在本地缓存。这样,应用程序就不必一遍又一遍地请求相同的数据,从而减少了分布式数据存储上的负载。
\n当单个节点更新全局数据存储上的给定数据时,该节点相对容易相对容易从其缓存中逐出相应的数据,因为它可以简单地向本地缓存发出信号以逐出/使数据无效。
\n问题在于,1000个节点中的任何一个节点都可以保存相同的数据,并且任何节点都可以随时更新任何一条数据。例如,如果节点 539更新了特定的数据,而节点 877在其本地缓存中保存了该数据的副本,那么我需要节点 877从其本地缓存中逐出该数据,并在下次更新时实时检索该数据。是需要的。当然,相同的数据可以缓存在数十个节点上,并且所有这些节点都需要知道节点 539所做的更新并相应地逐出数据。
\n设计这样的系统的最佳方法是什么?
\n虽然我不想重新发明轮子,但我无法找到任何能够实现这一目标的现有解决方案,所以我设计了自己的计划:
\n我的计划是使用分布式消息传递系统,例如RabbitMQ(也许Kafka),其中 1,000 个节点中的每个节点都订阅一个主题,该主题包含需要驱逐的数据 ID 列表。每当节点更新特定数据时,它都会将 \xe2\x80\x9cdata ID\xe2\x80\x9d 写入“驱逐”主题。1,000 个节点中的每个节点都会订阅“驱逐”主题,并实时驱逐链接到数据 ID 的数据(如果它在内存中保存该数据)。
然而,我对这个设计有几个担忧。
\n首先,它看起来效率极低。每次 1,000 个节点中的任何一个更新一条数据时,\xe2\x80\x9cdata ID\xe2\x80\x9d 都必须传播到所有 1,000 个节点,因为我们不知道\xe2\x80\x99哪个(如果有)节点保存特定的数据。此外,很可能没有一个节点会缓存大部分正在更新的数据,从而使其效率更低。每次实时读取所有数据甚至可能会更有效。
\n是否有更优雅/高效的设计来达到预期的目标?
\nI\xe2\x80\x99m 使用Java.
谢谢
\n基本上,您将问题从数据库空间转移到了应用程序空间。即使DB一致,也需要使本地缓存一致(用什么类型的保证?一致性有很多种形式)。这不是一个简单的要解决的问题,它需要经历失败等。
ScyllaDB 缓存非常好,您是否可以增强其功能并将一些内存从本地节点移至 Scylla?
一种替代选项是始终先写入数据库,然后让节点侦听 CDC 流并使其本地缓存失效或重新填充
顺便说一句,有一个很好的本地 memcache 项目(C++ 语言) - https://www.scylladb.com/2019/02/20/valustor-a-memcached-alternative-built-on-scylla/
| 归档时间: |
|
| 查看次数: |
994 次 |
| 最近记录: |