【问题标题】:What caching strategy for search queries搜索查询的缓存策略是什么
【发布时间】:2012-10-25 09:34:38
【问题描述】:

我们正在开发一个搜索引擎网络应用程序,使用户能够搜索大约 200 个门户的内容。

我们的业务合作伙伴正在负责维护和提供 solr/lucene 实例,该实例正在执行索引数据的主要工作。

我们的应用程序查询 solr 并以人性化的方式呈现结果。但是,我们想知道如何限制查询的数量,或许可以使用某种形式的缓存。结果可能会被缓存几个小时。

我们想知道的是:什么是缓存查询结果的好策略?显然,我们希望方法调用会有很大的不同……做缓存有意义吗?

是否有一些缓存系统特别适合这个用例?我们正在使用 Spring 3 进行开发。

【问题讨论】:

  • 嗯,这不是我的主要领域,但缓存后我们的性能有了显着提高。我们每 6 到 12 小时缓存一次,实际上我们使用 memcached 来处理它。随着时间的推移,您的缓存索引可能会变得非常大,但是通过一些保留策略(即,缓存中的某个页面在一周内没有命中 --> 删除),您应该能够控制一切

标签: spring caching solr search-engine strategy-pattern


【解决方案1】:

我要记住,Solr 已经内置了很多缓存,以加快常见查询。我建议您在使用自己的查询缓存之前查看 Solr/Lucene 中的固有功能,并使用reinvent the wheel

Here 是一个很好的起点。

【讨论】:

    【解决方案2】:

    最简单的解决方案是在查询到达 Solr 之前对其进行重组。

    我创建了自己的 QueryBuilder 方法,在点击 Solr 之前,我通过了我的查询字符串。

    所有这些都是分解所有参数,然后将它们分类到预定义的组中。

    例如,为了规范您的查询以便它们可以缓存,您可以按每个键的字母顺序排序,然后修改查询字符串,然后使用它来查询 Solr。 (实际查询结果不变)。

    在实际运行查询之前,您可以创建 Solr 查询字符串的哈希,并检查已保存的所有键的内存哈希。如果您发现自己很可能接近数百万个查询键,您可能希望开始考虑使用BloomFilter 来减少键空间并在缓存命中时仍保持一定程度的准确性。

    或者,您可能希望考虑在您和 Solr 之间放置一个反向代理缓存。例如,如果您要查询 Solr,Spring -> Varnish -> SolrVarnish 可用于缓存,它将使用查询字符串作为哈希。然后,您可以设置 2 小时到期,以便自动刷新/清除/无效结果。

    希望这会有所帮助。

    【讨论】:

    • 我发现使用自定义 QueryBuilder 确实有助于规范化然后缓存查询。但是您确定单词的顺序无关紧要吗?例如,在邻近搜索中,它确实很重要。
    • 是的,对不起,我打算把它包括在内,但假设它会很清楚。说, fq 参数的顺序无关紧要。因此,您必须将所有 fq 参数排序在一起。您必须确保其他类型分组的顺序保持一致。
    【解决方案3】:

    我发现在 Lucene 之外缓存结果或呈现的内容效果最好。拥有一个指向缓存层的 API 搜索服务,其中包含来自 Lucene 索引的结果。

    如果您将缓存层分开,则可以插入任何您想要的缓存...分布式缓存(Redis、Azure AppFabric、其他云缓存等)。您还可以缓存网页的部分呈现(即 ASP.NET 中的输出缓存)或使用 RESTful 约定缓存 API 调用本身。诸如缓存预热或主动缓存(基于使用情况)之类的事情很容易通过服务来完成。

    然后您的应用程序/索引缓存可以在您的应用程序的更多层中“重复使用”,而不仅仅是在索引级别进行缓存。这一切都取决于您的索引更新是否是实时的,查询对于每个客户端/用户 ID 是否具有日期级别的安全性等。如上所述,Solr 已经为您做了“一些”这些事情。

    【讨论】:

    • 我认为 Solr 可以完成所有这些工作,如果您将其配置为这样做的话,还可以在索引更改时使缓存失效——这很难做到如果您构建自己的查询缓存层来实现。
    猜你喜欢
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    • 2023-03-04
    • 2020-06-01
    • 2020-02-18
    • 1970-01-01
    相关资源
    最近更新 更多