如何实施保存搜索方案

时间:2017-10-04 09:12:58

标签: mysql performance elasticsearch rabbitmq saved-searches

保存什么 - 搜索?

  

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

     

保存的搜索对于具有复杂搜索选项的网站或用户可能想要重新访问或共享动态搜索结果集的网站非常有用。

我们拥有高级搜索功能,并且不需要实施新的搜索功能,我们需要的是实现保存搜索机制的良好性能方案。

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

我们在我们的网站上使用弹性搜索和Mysql。我们仍然没有实现任何东西,只是考虑找到可以处理高速率日期的好解决方案,另一方面**问题是工作规模,因为我们每天都有很多帖子,而且我们猜测用户也经常使用这个功能,所以我们正在寻找可以轻松实现高性能工作规模的好方案。

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

  • 一个快速的解决方案是我们将已保存的搜索保存在Elastic中的saved-search-index中,然后运行一个cronjob,对于所有已保存搜索的项目,从posts-index-弹性得到结果,如果有任何结果推送记录到RabbitMq以通知等效用户。

  • 用户将一个项目发布到我们检查过的网站中存在已保存的搜索 - 在Elastic中的saved-search-index中如果匹配,我们将一条记录放入RabbitMq,(这个方法的主要问题是它可以与插入网站的每个帖子中的大量已保存搜索相匹配。

我最关心的是规模和表现,我很高兴与我分享您对这个问题的经验和想法。

我对比例的估计

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

如果您与我分享您的想法,我将非常感激

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

4 个答案:

答案 0 :(得分:1)

Cron工作 - 没有。持续工作 - 是的。

为什么呢?随着事物的扩展或活动的激增,cron工作变得有问题。如果09:00的cron作业运行时间太长,它将与10:00实例竞争资源;这可能会陷入灾难中。

另一方面,如果cron工作提前完成,那么活动会在"忙碌"之间振荡。 (cron工作正在做的事情)和#34;没有忙碌" (cron已完成,而不是下次调用的时间)。

所以,相反,我建议一项工作不断贯穿所有"存储的查询",一次做一个。完成列表后,只需重新开始。这完全消除了我对cron的抱怨,并提供了自动弹性"处理繁忙/非繁忙时间 - 扫描速度会相应减慢或加速。

当作业完成时,列表会从列表中重新开始。也就是说,它永远运行了#39; (你可以使用一个简单的cron作为一个' keep-alive'监视器,如果它崩溃就会重新启动它。)

好的,"一份工作"一次重新搜索一次"可能不是最好的。但我不同意使用排队机制。相反,我会有少量进程,每个进程都在存储查询的一些块上。有很多方法:抢锁;给我一百个工作;模N;每个人都有利有弊。

答案 1 :(得分:1)

由于您已经在使用Elasticsearch并且已经确认您正在创建类似Google快讯的内容,因此最直接的解决方案是Elasticsearch Percolator。

the official documentation起,Percolator在以下情况下非常有用:

  

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

在性能方面,我不能说太多,因为你没有提供任何查询的例子,但主要是因为我的调查结果不一致。

根据这篇文章(https://www.elastic.co/blog/elasticsearch-queries-or-term-queries-are-really-fast),Elasticsearch查询应该能够达到30,000个查询/秒。 但是,这个未得到答复的问题(Elasticsearch percolate performance)在16 CPU服务器上报告了200次查询/秒的痛苦。

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

答案 2 :(得分:0)

这个答案是在没有真正理解“已保存搜索”的含义的情况下编写的。我把它留在这里作为相关问题的讨论,但不是作为“保存的搜索”解决方案。 - Rick James

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

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

由于数据正在发生变化,结果集很快就会过时?多久?也就是说,保存结果集需要相当快速地清除。当然,数据不是那么静止,你可以等一个月。也许一个小时?

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

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

底线...这闻起来像“过早优化”。我推荐

  1. 在不保存结果集的情况下构建网站。
  2. 进行压力测试以确定它何时会断裂。
  3. 致力于优化慢速部件。
  4. 至于RabbitMQ - “不要排队,就这么做”。排队和出队的成本是(1)增加了用户的等待时间,以及(2)增加了系统的开销。 (中等规模)的好处很小。

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

    • 将客户端移至另一台服务器 - 远离数据库。这将给你一些缩放,但不是2x。要走得更远......
    • 使用复制:一个Master +许多只读Slave - 并在Slaves上执行查询。这为您提供了几乎无限制的数据库扩展。
    • 拥有多个Web服务器 - 此部分几乎无限扩展。

答案 3 :(得分:-2)

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

您是否对ES服务器做过任何事情? (你能负担得起),所以:

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

    1. 你为什么要每半小时开火一次?如果您已经使用了cron,则每分钟触发一次,然后指示查询正在运行。对于另一篇文章,你有一个更好的解决方案和解释。
    2. 为什么要将结果与查询分开?
    3. 请记住标准化查询以更改参数的顺序,而不是强制执行新查询。
    4. 为什么要使用MySQL来存储结果?更好的文档类型数据库,如Elasticsearch xD
    5. 我建议你:

      1. 优化ES结构 - 为字段选择正确的标记器。
      2. 使用异步加载结果 - 例如WebSocket + Node.js