如何缓存多个节点以实现可伸缩性

时间:2012-02-06 19:26:31

标签: caching scalability

仅供参考 - 我是新成员,相当新的程序员,这是我在stackoverflow上的第一篇文章。

对于我的网络应用程序,我一直在编写自己的数据缓存层;在这样做时,应用程序已设置为仅在缓存中找不到时才从数据库中获取数据。随着时间的推移,应用程序会从缓存中删除过时数据,以尽量减少RAM中保存的数据量。如果我的webapp驻留在单个服务器上,这对我来说很有效,可以限制对数据库服务器发出的只读请求数。现在我正在考虑在许多节点上对我的webapp进行负载均衡,并且我希望保持缓存实现不变。我试图解决的问题是如何保持不同的webapp节点缓存层同步。

问题场景可能是典型问题:

  1. Person A读取节点#1上记录#1的版本#1;缓存在节点#1上更新。
  2. 人B读取节点#2上记录#1的版本#1;缓存在节点#2上更新。
  3. Person A更新节点#1上的记录#1;
    • 数据不会从数据库中读取,因为它位于缓存中。
    • 缓存使用记录#1的版本#2进行更新。
    • 版本#2 data-write被发送到db。
  4. 人B在节点#2上读取记录#1;
    • 数据不是从数据库读取的,因为它在缓存中导致版本#1,现在已经过时了。
  5. 所以我想到了一些想法。

    1. 我可以放弃缓存,每次读/写都来自db(显然不适合我)。
    2. 我可以实现某种形式的一致哈希。即我可以将所有记录#1项发送到节点#1。但是我发现需要在每个节点之间共享数据,例如用户配置文件数据(即当记录#1更新时,用户配置文件也需要更新) ,因此需要进入其他节点缓存以及让我对配置文件记录存在同样的问题。)
    3. 我可以对记录使用一致的哈希并以某种方式拆分用户数据,以便不缓存该数据层(仍然不理想)。
    4. 我可以学习erlang并开始在缓存层之间发送消息,但是我已经尝试过我从未真正使用的erlang(可能是理想的技术解决方案,但我宁愿不学习erlang - lol)。
    5. 所以这是我第一次考虑这个问题。像我一样的隐士般的爱好程序员应该知道的任何众所周知的策略?想法,解决方案?

      注意: - 我的主要语言是Clojure,但这并不一定与手头的问题有关。 - 我已经在使用NoSQL dbs。

      感谢。

1 个答案:

答案 0 :(得分:0)

如果您真的对实现自己的缓存解决方案感兴趣并希望保持节点同步,那么您可能希望在系统中添加一些外部缓存失效接口。

例如,如果NoSQL数据库支持更新后挂钩,则可以向所有节点发出 multicast UDP 命令,使某些值无效。或者,您可以使用某种类型的消息队列(例如ActiveMQRabbitMQ),但这可能会有点过分。

由于Clojure是一种基于JVM的语言,因此您可以使用一些现有的JVM缓存解决方案,例如Ehcache。如果您没有为教育目的实现此缓存系统,这样做可以为您节省大量时间和精力。

通过学习Erlang的方式是有趣和有用的体验的完美结合。我从不后悔自己花了一些时间来适应它。它也将在你的情况下最终得到回报。