【问题标题】:Cache solution for a news feed, based on objective information?基于客观信息的新闻提要缓存解决方案?
【发布时间】:2014-09-11 12:09:22
【问题描述】:

我需要一些关于缓存可更新新闻提要的最佳方法的建议。

请,请不要“Fanboy”回答 - 不要寻找关于“最佳”系统的主观意见,只是寻求一些符合以下要求的技术建议。因此,请分享您在现实世界中使用过的东西,即使您更喜欢其他解决方案。

我有一个基于 Rails 的新闻提要(Neo4j 数据库),虽然性能很好,但我想缓存它,这样服务器就不会因为提供实时提要而陷入困境。

要求:

  • 简单的片段更新:我想轻松更新部分用户的新闻源 基于特定触发器的缓存,例如,当用户编辑时 他们的状态更新 - 我不想重新生成用户的整个 缓存中的新闻提要,而我只想更新那个 特定用户提要的“片段”或部分。而且我不想跳过箍来尝试这样做。

  • 删除:如果有人删除活动,我只想删除该活动 在系统最终为该用户刷新整个提要之前,从他们的新闻提要中删除。

  • EASY RETRIEVAL:我想以这样一种方式检索缓存,即 控制器/模型可以轻松读取它们并将它们传递给视图,而无需 意见的任何修改。

  • 持久性:如果我需要重新启动缓存,它应该加载 从磁盘缓存。这意味着它应该将缓存的条目保存到磁盘。

  • SPEED:鉴于它必须能够更新缓存的片段 新闻提要,会有某种形式的性能冲击。但 我需要速度..

哪些缓存技术可以提供这样的功能? Redis、MongoDB、Memcached 能满足这些要求吗?还有哪些其他选择? (CouchDB、东京文件柜等)..

本着 Stack Overflow 的精神,我并不是在询问您更喜欢什么以及为什么更喜欢的主观意见,我只是询问您可能在生产中实际用于完成缓存和更新缓存新闻的候选系统饲料(或任何类似的东西)。

【问题讨论】:

  • MongoDB怎么不持久化? “喜欢”某些东西也是主观的,例如我不喜欢rails,但你显然喜欢。这是一种意见。
  • 我说“AFAIK”=据我所知.. 显然我是在要求人们根据经验而不是仅仅因为它们是 MongoDB,就哪些解决方案可行以及为什么可行、Redis 或任何粉丝。
  • 你不应该那样使用速记,我其实不知道 AFAIK 是什么,现在我知道了。不仅如此,短手在不同地区可能意味着不同的东西,你应该尝试使用正确的英语。无论如何,无论怎么说,你都会得到一个粉丝男孩的答案。
  • 好的 - 我修改了我的问题。对于什么样的系统可以满足这些要求,您有什么建议吗?
  • 为什么需要持久性?您说“如果我需要重新启动缓存,它应该从磁盘加载缓存。这意味着它应该将缓存的条目保存到磁盘”但是拥有缓存的全部优势是您不需要持久化它,因为您可以重建它(在发生崩溃或其他情况下)。这是您提出的非常重量级要求,只是为了(过早地?)优化启动时间以重建缓存似乎......

标签: ruby-on-rails mongodb caching redis memcached


【解决方案1】:

由于它主要是一个基于意见的话题,这个答案将是主观的。但无论如何我都会尽量保持真实。

首先要注意的是,您的要求往往是相互排斥的。正如我们在法国所说,你想要黄油、黄油的钱和农夫的妻子(好吧,这可能是一个糟糕的翻译)。

例如,为了支持简单的片段更新和正确删除,您将需要缓存中的某种数据结构。我对 Rails 的了解为零,但我想它会对数据访问模式以及控制器/模型的定义产生影响。换句话说,它将增加数据检索的复杂性。您需要速度,但与此同时,您还需要持久性以及非平凡的数据访问模式。好吧,你不能同时得到所有东西,你必须做出选择,并优先考虑这些要求。

我的第二点是缓存仅在缓存和底层存储引擎之间的性能存在显着差异时才有用。由于您已经使用了相当高效的 NoSQL 引擎(Neo4j),您只需要考虑真正为原始性能而设计的引擎(即低延迟存储):memcachedrediscouchbase、@987654324 @,命名成熟的开源产品。如果您觉得更有冒险精神,您还可以考虑其他项目,例如 tarantoolhyperdex

还有许多商业产品,但我不确定它们是否提供 Ruby 客户端(TIBCO ActiveSpaces、Gigaspaces、Red-Hat Infinispan 等......)

其他 NoSQL 引擎(MongoDB、Cassandra、CouchDB 等)还有其他有趣的属性,但它们不会在混合读写工作负载的原始性能上击败这些解决方案。在这里,我只讨论原始性能(即高吞吐量下的低延迟),而不是可扩展性。

其实可以排除memcached,因为它不支持持久化。我想说你可能可以用 Redis、Couchbase 或 Aerospike 实现你想要的,但是 Aerospike 3 似乎还没有官方支持的 Ruby 客户端。

使用 Redis 和 Aerospike 支持多个数据访问路径(即一致的索引数据结构)将比 Couchbase 更容易。使用 Couchbase 或 Aerospike 比使用 Redis 更容易实现高可用性。使用 Redis 和 Couchbase 实现缓存行为比使用 Aerospike 更容易。

一些一般性建议:

  • 在添加额外层的复杂性之前,请确保您确实存在 Neo4j 的性能或可扩展性问题。复杂就像牙膏:一旦从管子里拿出来,就无法再放回去了。

  • 数据访问模式应在设计时列出,并且必须由所选引擎中的相应数据结构支持。

  • 还必须考虑硬件占用空间。如果您只有几个盒子,请选择像 Redis 这样的轻量级解决方案。

  • 对于持久性,您还需要考虑 HA。如果缓存层丢失会怎样?实际上,我想说的是,对于缓存来说,HA 可能比持久性更重要。

最后,您还需要定义您想要的确切缓存语义(更新行为、失效行为、缓存未命中管理、TTL 策略(如果有的话)等...)。我列出的 3 个 NoSQL 引擎提供了一些工具来帮助实现各种策略,但它们都不支持现成的策略。这将需要一些编码来实现它。

【讨论】:

  • 你的答案的问题是,即使你试图保持事实,你现在已经遇到了这个问题的另一个问题;它太宽泛了。我可以在这里给出一个可能与您的某些答案相矛盾的答案(即提到与某些技术相关的缓存),但由于用户的问题太宽泛,这两者都不会真正有帮助,他需要离开并实际测试一下
  • Didier 你是对的 - 我需要数据结构,这就是为什么 MongoDB 看起来像一个候选系统。我已经阅读了几篇关于新闻提要的文章,这些文章建议使用一个 redis 实例来保存 ID,而另一个实例来保存对象。虽然这不提供我正在寻求的写入/更新功能,但它确实提供了性能......
  • @RubenCatchmeObregon 为什么要使用 redis 来存储 id?那么您不会查询两个独立的、可能地理上相距遥远的数据库,以获取您可以查询一个数据库的内容吗?我的意思是您不能只向用户显示新闻提要项目 ID。您希望在一个 redis 实例上使用对象的 id 是有道理的;如果你甚至需要 redis 在这个等式中,这些文章中的许多人都会尝试并为技术人员提供乐趣。
  • 就个人而言,我会尽量保持简单:如果需要,添加一个缓存层,但至少要确保缓存层只是一个组件,而不是多个存储引擎的聚合。例如,使用 Redis 存储 ID 和数据是非常好的。您在使用 Redis 时可能遇到的问题更多地与可伸缩性和 HA 有关。
  • 我认为问题在于可扩展性等为什么人们建议对其进行分段。 Neo4j 做得很好,但即便如此,扩展至集群在许可方面也很昂贵。我的提要现在是实时的(并通过 Neo4j 缓存),它的行为与 sql 查询非常相似——返回数据行。但即便如此,它在性能方面的成本很高,并且在仅使用一台服务器或测功机等进行扩展方面效果不佳 - 宁愿缓存它并让我的新闻提要进程使用实时提要在后台更新缓存的提要而不是用户访问实时提要..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-01
  • 2011-10-29
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
相关资源
最近更新 更多