0

什么是保存搜索?

保存是用户在高级搜索中找不到所需结果的机制,只需按下“保存我的搜索条件”底部,我们就会保存搜索条件,当相应的数据发布到网站时,我们会通知用户“嘿,用户,该项目( s)您正在寻找的存在现在来访问它”。

已保存的搜索对于具有复杂搜索选项的站点或用户可能希望重新访问或共享动态搜索结果集的站点很有用。

我们有高级搜索,不需要实现新的搜索,我们需要一个良好的性能场景来实现保存搜索机制。

我们有一个网站,用户每天在网站上发布大约 120,000 条帖子,我们将实施 SAVED SEARCH 方案(类似于https://www.gumtree.com/所做的事情),这意味着用户使用高级搜索,但他们找不到他们想要的内容,只想保存搜索条件,如果网站上有任何结果,我们会通知他们。

我们在我们的网站中使用 Elastic search 和 Mysql。我们仍然没有实施任何东西,只是想找到可以处理高约会率的好解决方案,另一方面**问题是工作规模,因为我们每天有很多帖子,而且我们猜测用户经常使用此功能,因此我们正在寻找可以轻松处理这种规模的工作并具有高性能的良好场景。

建议的解决方案,但不是最好的

  • 一个快速的解决方案是我们将保存的搜索保存在 Elastic 中的保存搜索索引中,然后运行一个 cronjob,为所有保存的搜索项从 Posts-index-Elastic 获取结果,如果有任何结果,将记录推送到 RabbitMq 到通知等效用户。

  • 在用户将项目发布到网站时,我们检查它是否存在已保存的搜索在 Elastic 中的保存搜索索引中,如果匹配,我们将记录放入 RabbitMq,(这种方法的主要问题是它可以匹配一个巨大的插入网站的每个帖子中保存的搜索次数)。

我最关心的是规模和性能,我会很感激与我分享你关于这个问题的经验和想法。

我对规模的估计

  • 已保存搜索的有效期为三个月
  • 每天至少 200,000 次保存搜索
  • 所以我们有9,000,000 条活动记录

如果您与我分享您的想法,我将不胜感激

*仅供参考** - 我们的队列作业也有 RabbitMQ - 我们的 ES 服务器足够好,有 64GB RAM

4

4 回答 4

1

因为您已经在使用 Elasticsearch,并且您已经确认您正在创建类似 Google Alerts 的内容,所以最直接的解决方案是 Elasticsearch Percolator。

官方文档中,Percolator 在以下情况下很有用:

您运行一个价格警报平台,该平台允许精通价格的客户指定一条规则,例如“我有兴趣购买特定的电子产品,如果下个月内任何供应商的小工具价格低于 X 美元,我希望收到通知” . 在这种情况下,您可以抓取供应商价格,将它们推送到 Elasticsearch 并使用其反向搜索 (Percolator) 功能将价格变动与客户查询相匹配,并最终在找到匹配项后将警报推送给客户

关于性能,我不能说太多,因为您没有提供任何查询示例,但主要是因为我的发现不一致。

根据这篇文章 ( https://www.elastic.co/blog/elasticsearch-queries-or-term-queries-are-really-fast),Elasticsearch查询应该能够达到 30,000 次查询/秒。然而,这个未回答的问题(Elasticsearch percolate performance)在 16 个 CPU 的服务器上报告了每秒 200 次查询的速度非常慢。

没有其他信息,我只能猜测原因是配置问题,所以我认为您必须尝试一堆不同的配置才能获得最佳性能。祝你好运!

于 2018-03-14T11:58:32.890 回答
1

Cron 工作 - 不。持续工作 - 是的。

为什么?随着事情的扩展或活动的激增,cron 作业变得有问题。如果 09:00 的 cron 作业运行时间过长,会与 10:00 的实例竞争资源;这可能会演变成一场灾难。

另一方面,如果 cron 作业“提前”完成,则活动在“忙”(cron 作业正在做事)和“不忙”(cron 已完成,而不是下一次调用的时间)之间振荡。

所以,相反,我建议一项工作不断地运行所有“存储的查询”,一次只做一个。当它完成列表时,只是重新开始。这完全消除了我对 cron 的抱怨,并提供了一种自动“弹性”来处理忙碌/不忙碌的时间——扫描将相应地减慢或加快速度。

当工作完成时,列表,它在列表上重新开始。也就是说,它“永远”运行。(您可以使用一个简单的 cron 作业作为“保持活动”监视器,在它崩溃时重新启动它。)

好的,“一份工作”重新搜索“一次一份”可能不是最好的。但我不同意使用排队机制。相反,我会有少量进程,每个进程都作用于存储的查询的一部分。方法有很多种:抓取和锁定;给我一百个工作;模 N; 等等。每个都有优点和缺点。

于 2017-10-08T18:19:58.633 回答
0

这个答案是在没有真正理解“保存的搜索”的含义的情况下编写的。我把它留在这里作为对相关问题的讨论,而不是作为“保存的搜索”解决方案。 ——里克·詹姆斯

如果您只保存“查询”,我看不出有问题。我假设您正在保存查询和“结果集”...

每秒一次“保存的搜索”?240 万行?只需在需要时重新运行搜索。系统应该能够处理这么小的负载。

由于数据在变化,结果集很快就会过时?多久?也就是说,保存结果集需要相当快地清除。当然,数据不是静态的,您可以等待一个月。也许一个小时?

实际上保存结果集并能够重放它涉及 (1) 代码的复杂性,(2) 缓存、I/O 等方面的开销等。

用户查看相同搜索的平均次数是多少?由于我刚才提到的开销,我怀疑平均次数需要超过 2 次才能证明开销是合理的。

底线......这闻起来像“过早的优化”。我建议

  1. 在不保存结果集的情况下构建站点。
  2. 对它进行压力测试,看看它什么时候会破裂。
  3. 努力优化慢速部分。

至于 RabbitMQ——“不要排队,就去做”。排队和出队的成本是(1)增加了用户的延迟和(2)增加了系统开销。好处(在你的中等规模)是最小的。

如果您确实遇到缩放问题,请考虑

  • 将客户端移到另一台服务器上——远离数据库。这会给你一些缩放,但不是 2 倍。为了走得更远...
  • 使用复制:一个 Master + 许多只读的 Slave——并在 Slave 上进行查询。这使您可以在数据库中进行几乎无限的扩展。
  • 拥有多个 Web 服务器——这部分几乎可以无限扩展。
于 2017-10-08T16:47:29.850 回答
-2

我不明白您为什么要使用保存搜索...首先:您应该优化服务,以便尽可能少地使用保存搜索。

你对 ES 服务器做过什么吗?(你能负担得起什么),所以:

  1. 你优化过elasticsearch服务器吗?默认情况下,它使用 1GB 的 RAM。最好的解决方案是给他一半的机器内存,但不超过 16GB(如果我记得的话。检查文档)
  2. ES机器有多强大?他喜欢核心而不是MHZ。
  3. 你有多少个ES节点?您始终可以添加另一台机器以更快地获得结果。
  4. 在我的情况下(ES 2.4),服务器在几天后变慢,所以我每天重新启动一次。

接下来:

  1. 为什么要每半小时启动一次任务?如果您已经使用 cron,则每分钟触发一次,并表明查询正在运行。与其他帖子一起,您有更好的解决方案和解释。
  2. 为什么将结果与查询分开?
  3. 请记住标准化查询以更改参数的顺序,而不是强制执行新查询。
  4. 为什么要使用 MySQL 来存储结果?更好的文档类型数据库,例如 Elasticsearch xD

我建议你:

  1. 优化 ES 结构 - 为字段选择正确的标记器。
  2. 使用异步加载结果 - 例如 WebSocket + Node.js
于 2017-10-09T11:56:55.807 回答