其他系统数据的Elasticsearch复制?

58

假设我想使用 Elasticsearch 实现网站的通用搜索,顶部搜索栏将能够在整个网站上查找各种不同类型的资源。文档当然是可以找到的(通过 tika 上传/索引),但也会有像客户、账户和其他人等其他东西。

出于架构原因,大多数非文档内容(客户、账户)将存在于关系型数据库中。

在实现此搜索时,选项#1是创建所有内容的文档版本,然后仅使用 Elasticsearch 运行搜索的所有方面,完全不依赖关系型数据库来查找不同类型的对象。

选项#2是仅使用 Elasticsearch 索引文档,这意味着对于通用的“站点搜索”功能,您必须将多个搜索分配给多个系统,然后聚合结果,然后返回它们。

选项#1似乎更优越,但缺点是它要求 Elasticsearch 在生产关系型数据库中拥有许多东西的副本,并且这些副本在事物更改时保持更新。

保持这些存储同步的最佳选项是什么?我的想法是通用搜索使用选项#1是更好的选择。是否有选项#3?

2个回答

56

您列出了跨多个数据存储搜索时的两种主要选择,即在一个中央数据存储中搜索(选项#1)或在所有数据存储中进行搜索并聚合结果(选项#2)。

这两个选项都可以使用,尽管选项#2有两个主要缺点:

  1. 需要在应用程序中开发大量逻辑来“扩展”到多个数据存储以及聚合返回的结果。
  2. 每个数据存储的响应时间可能不同,因此,您必须等待最慢的数据存储响应,才能向用户呈现搜索结果(除非您使用不同的异步技术,例如Ajax、websocket等绕过此问题)

如果您想提供更好且更可靠的搜索体验,则选项#1显然会得到我的支持(实际上我经常采用这种方式)。正如您正确指出的那样,这个选项的主要“缺点”是您需要将 Elasticsearch 与其他主数据存储中的更改保持同步。

由于您的其他数据存储将是关系型数据库,因此有几种不同的选项可让它们与 Elasticsearch 同步,即:

前两个选项效果很好,但有一个主要的缺点,即它们不会捕获表上的 DELETE 操作,它们只会捕获 INSERT 和 UPDATE 操作。这意味着,如果您删除用户、帐户等,则无法知道您必须在 Elasticsearch 中删除相应的文档。除非您在每次导入会话之前决定删除 Elasticsearch 索引。

为了缓解这个问题,你可以使用另一个基于MySQL binlog的工具,因此它能够捕获每个事件。有一种用Go编写的工具,一种用Java编写的工具,还有一种用Python编写的工具。 更新: 以下是另一篇有趣的博客文章: 如何使用Logstash将Elasticsearch与关系型数据库同步

谢谢 - 直觉告诉我选项#1更好。我所缺少的是我不知道像Logstash JDBC输入这样的自动同步工具,这对我来说是一个关键的缺失部分,使得选项#1比我原本想象的要容易得多。我可以处理传播DELETE操作,最终这只意味着我需要做的工作比我原本认为的要少来传播变化。谢谢。 - FrobberOfBits
@Val..有没有框架可以提供拦截器来拦截MySQL二进制日志,这些拦截器可以根据binlog中的事件执行Java代码,并将数据推送到Elasticsearch? - Prannoy Mittal
@PrannoyMittal 看看这个答案是否有用:https://dev59.com/FFwY5IYBdhLWcg3wFkej#33029458 - Val

9
请查看 Debezium。这是一个变更数据捕获(CDC)平台,它允许您流式传输数据。
我创建了一个简单的GitHub存储库,展示了如何将其与PostgreSQL和ElasticSearch一起使用。 enter image description here

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接