【问题标题】:Caching vs Indexing缓存与索引
【发布时间】:2016-03-26 23:05:59
【问题描述】:

缓存解决方案和索引解决方案之间的真正区别是什么?在我看来,索引解决方案实际上是具有运行搜索查询能力的缓存(例如:弹性搜索)。是否有任何真正的理由在同一个项目中同时使用缓存解决方案和索引解决方案,或者索引解决方案基本上会使任何其他缓存变得多余?

示例:假设我将 NEST 用于 ElasticSearch,它将存储和返回 POCO;如果我随后查询 ElasticSearch 并让 POCO 返回给我,那不认为是在使用从 ElasticSearch 返回的缓存对象吗?

目前,我使用我拥有的 ICacheManager 接口将数据存储在缓存中.. 像这样:

return CacheManager.Get(cacheKey, () =>
{
    // return something...
});

这对于 ElasticSearch 会变得多余吗?

编辑

感谢大家的回答。我完全了解缓存是什么,并且已经理解了文本搜索索引背后的一般概念,所以我只是想知道索引是否已经兼作缓存,因此会使任何其他缓存变得多余。毕竟,我不想在内存中保留 2 个缓存(例如:ElasticSearch + Redis),而一个缓存可以做得很好。不过,我想我现在有一个更好的主意;特别是当我意识到并非所有字段都始终存储在索引中时,因此我们需要从缓存中获取对象或直接从数据库中获取对象 - 至少在某些情况下是这样。谢谢大家!

【问题讨论】:

  • 鉴于这是一年多前提出的问题,我很想知道您是否探索过 ES 作为缓存解决方案。

标签: caching indexing elasticsearch


【解决方案1】:

缓存的全部目的是尽快返回已请求的数据。缓存的一个限制是它们不能太大,因为查找时间会增加,因此首先会破坏拥有缓存的目的。话虽这么说,如果您计划在数据库中拥有几百万/十亿条记录,那么将它们全部编入索引并不难,但很难将它们全部缓存起来,尽管因为 RAM 越来越越来越便宜,您也许可以将所需的所有内容存储在内存中。您还需要问自己,您的缓存是否需要分布在多个主机上(无论是现在还是将来)。

考虑到 ES 中的查找和查询非常快(+ ES 还为您带来更多好处,例如评分),即通常比从数据库中检索相同数据更快,因此使用 ES 是有意义的作为缓存。我看到的一个问题是一个常见问题,即一旦您开始复制数据(DB -> ES),您需要确保两个存储不会不同步。

现在,如果您在该组合中添加缓存,则它是需要维护并确保与主数据存储一致的第三个数据存储。如果您知道您的数据非常稳定,即写入后不经常更新,那可能没问题,但在设计数据访问策略时,您需要始终牢记这一点。

正如@paweloque 所说,最终这一切都取决于您的确切用例。每个问题都是不同的,我可以证明,在过去五年左右围绕 ES 进行了几十个项目之后,我从未见过两个项目以相同的方式配置。对于某些特定情况,缓存可能有意义,但对于其他情况则根本没有。

您需要认真思考需要存储数据的方式和位置、请求它们的人(以及以何种速度)、谁在创建/更新它们(以及以何种速度),但最终,最佳实践就是尽可能少地使用所需的组件来保持您的堆栈尽可能精简,每个组件都是您必须了解、集成、维护、调整和监控的潜在瓶颈。

最后,我还要补充一点:添加缓存或索引应该被视为软件堆栈的性能优化。正如您可能知道"Premature optimization is root of all evil" 的俗语,您应该首先只使用您的数据库,测量性能,对其进行负载测试,然后见证它可能不支持负载。只有这样,您才能根据需要决定在其上放置缓存和/或索引。再次,负载测试,测量,然后决定。如果你每天只有十个用户发出几个请求,那么只有一个数据库可能就很好了。您必须了解何时以及为何需要在巴别塔上添加另一层,但最重要的是您需要一次添加一层,并了解该层如何提高/降低堆栈的稳定性。

最后但同样重要的是,您可以找到一些使用 ES 作为缓存的在线文章(主要是 key-value storesobject caches)。

【讨论】:

  • 嗨 Val,我也在考虑同样的问题。我的用例是自动完成,就像谷歌的搜索一样,每当有人输入时,它都会向 ES 查询结果。你觉得这中间加redis缓存层有好处吗?
  • @user1955934 并不是因为completion suggester 针对速度进行了优化,并且完成数据存储在内存中的FST(有限状态传感器)中。 old article 解释了完成数据与倒排索引中索引的数据有何不同。另请阅读:stackoverflow.com/a/51085473/4604579
  • 添加redis缓存层会为ES节省工作,值得吗?如果我们需要扩大规模,我们是否只扩大 ES?
  • @user1955934 再次阅读我的帖子:“过早的优化是万恶之源”。您应该先尝试不使用,然后在必要时进行优化,因为优化您不知道如何优化以及为什么优化的东西是没有意义的。
【解决方案2】:

你的问题:

问。缓存解决方案和索引解决方案之间的真正区别是什么?

A.简单的区别是缓存用于存储经常使用的数据以更快地服务相同的请求。从本质上讲,您的缓存比您的主存储更快,但大小更小,因此它可以存储数据(考虑到它会更昂贵)

对所有数据进行索引以使其可更快地进行搜索。一个简单的 Hashtable/HashMap 有哈希作为索引,在一个数组中,0 和 1 是索引。

您可以索引某些列以更快地搜索它们。但是缓存是您希望让您的数据更快地获取它们的地方。 通常缓存是内存,数据库是硬盘

缓存通常也是键值存储,因此如果您知道键然后从缓存中获取它,则无需运行查询。 在 NHibernate 和 EntityFrameworks 中,查询缓存被插入,查询作为键,所有数据都被缓存。现在您的查询将从缓存中获取,而不是通过数据库运行。

【讨论】:

  • 所有数据或添加到索引中的经常搜索的数据?
【解决方案3】:

有趣的问题!好吧,您实际上可以使用 elasticsearch 来实现缓存。它提供了一些可以使文档过期的功能,但我不确定它们是否非常适合使缓存过期。问题是 elasticsearch 不是为缓存解决方案而构建的。它的最佳点是索引和查找文档。

索引是建立索引的任务,就像为书籍所做的那样:您阅读整个文本并写下找到单词的页面。这让我们以后可以非常快速地找到单词在文本中的位置。

Elasticsearch 提供了一个工具箱,可让您定义如何索引和处理文本,即应用词干提取。然后在下一步中,它将为您提供不同类型的查询来查找您的文档。

但是,您可以将文档写入 elasticsearch 并使用文档的 id 来读取它。像这样,您可以将 elasticsearch 用作可以用作缓存的存储。

【讨论】:

  • 谢谢。我确实理解索引的意义在于搜索;唯一不清楚的是它是否使缓存变得多余。一般是做什么的?我可以想到 3 种可能性: 1. DB -> 缓存 -> 搜索索引 2. DB -> 搜索索引 -> 缓存 3. DB -> 搜索索引(忽略任何其他缓存) 所以我真的想决定是否缓存完全需要,如果需要,是搜索索引查询缓存还是缓存查询搜索索引?
  • 如果同时使用两者,当然对于复杂的查询我们会直接去搜索引擎..但是当通过 ID 检索时,我不确定我们是否应该先去缓存(哪个将查询索引)或将查询缓存的索引
  • 我刚才有个想法:是不是搜索引擎只用于复杂的查询(全文搜索),而传统的缓存将用于通过ID返回对象?跨度>
  • 您可以使用弹性作为数据库的缓存。在 elasticsearch 中存储数据,例如以表格形式显示结果。然后,如果您需要更多数据来查看详细信息,您可以从 db.xml 中获取。这在很大程度上取决于您的具体用例。
猜你喜欢
  • 2010-10-15
  • 2016-02-29
  • 2016-03-16
  • 1970-01-01
  • 2017-08-19
  • 1970-01-01
  • 2015-10-29
  • 2014-04-12
  • 2013-08-20
相关资源
最近更新 更多