Elasticsearch 复制其他系统数据?
Elasticsearch replication of other system data?
假设我想使用 elasticsearch 在网站上实现通用搜索。顶部的搜索栏有望在整个站点中找到各种不同类型的资源。当然是文件(uploaded/indexed via tika),还有客户、账户、其他人等。
出于架构原因,大多数非文档内容(客户、帐户)将存在于关系数据库中。
实施此搜索时,选项 #1 将创建所有内容的文档版本,然后仅使用 elasticsearch 运行 搜索的所有方面,完全不依赖关系数据库来查找不同的内容对象类型。
选项 #2 将仅使用 elasticsearch 为文档编制索引,这意味着对于一般 "site search" 功能,您必须将多个搜索外包给多个系统,然后在之前汇总结果归还他们。
选项 #1 似乎优越得多,但缺点是它要求弹性搜索本质上在生产关系数据库中拥有大量内容的副本,而且这些副本随着内容的变化而保持最新。
保持这些商店同步的最佳选择是什么?我认为对于一般搜索,选项 #1 更优的想法是否正确?有选项 #3 吗?
您几乎列出了跨多个数据存储进行搜索时的两个主要选项,即在一个中央数据存储中搜索(选项 #1)或在所有数据存储中搜索并汇总结果(选项 #2).
这两个选项都可以,尽管选项 #2 有两个主要缺点:
- 这将需要在您的应用程序中开发大量逻辑,以便 "branch out" 对多个数据存储进行搜索并聚合返回的结果。
- 每个数据存储的响应时间可能不同,因此,您必须等待最慢的数据存储响应才能向用户显示搜索结果(除非您通过使用不同的异步来避免这种情况技术,例如 Ajax、websocket 等)
如果您想提供更好、更可靠的搜索体验,选项 #1 显然会得到我的投票(实际上我大部分时间都采用这种方式)。正如您正确指出的那样,此选项的主要 "drawback" 是您需要使 Elasticsearch 与其他主数据存储中的更改保持同步。
由于您的其他数据存储将是关系数据库,您有几个不同的选项可以使它们与 Elasticsearch 保持同步,即:
- 使用 Logstash JDBC input
- 使用 JDBC importer 工具
前两个选项效果很好,但有一个主要缺点,即它们不会在您的 table 上捕获 DELETE,它们只会捕获 INSERT 和 UPDATE。这意味着如果你删除了一个用户、账户等,你将无法知道你必须删除 Elasticsearch 中的相应文档。当然,除非您决定在每次导入会话之前删除 Elasticsearch 索引。
为了缓解这种情况,您可以使用另一个基于 MySQL binlog 的工具,从而能够捕获每个事件。有一个写在 Go, one in Java and one in Python.
更新:
这是关于该主题的另一篇有趣的博客文章:How to keep Elasticsearch synchronized with a relational database using Logstash
请看Debezium。这是一个变更数据捕获 (CDC) 平台,可让您流式传输数据。
我创建了一个简单的 github repository,展示了它如何与 PostgreSQL 和 ElasticSearch 一起工作。
假设我想使用 elasticsearch 在网站上实现通用搜索。顶部的搜索栏有望在整个站点中找到各种不同类型的资源。当然是文件(uploaded/indexed via tika),还有客户、账户、其他人等。
出于架构原因,大多数非文档内容(客户、帐户)将存在于关系数据库中。
实施此搜索时,选项 #1 将创建所有内容的文档版本,然后仅使用 elasticsearch 运行 搜索的所有方面,完全不依赖关系数据库来查找不同的内容对象类型。
选项 #2 将仅使用 elasticsearch 为文档编制索引,这意味着对于一般 "site search" 功能,您必须将多个搜索外包给多个系统,然后在之前汇总结果归还他们。
选项 #1 似乎优越得多,但缺点是它要求弹性搜索本质上在生产关系数据库中拥有大量内容的副本,而且这些副本随着内容的变化而保持最新。
保持这些商店同步的最佳选择是什么?我认为对于一般搜索,选项 #1 更优的想法是否正确?有选项 #3 吗?
您几乎列出了跨多个数据存储进行搜索时的两个主要选项,即在一个中央数据存储中搜索(选项 #1)或在所有数据存储中搜索并汇总结果(选项 #2).
这两个选项都可以,尽管选项 #2 有两个主要缺点:
- 这将需要在您的应用程序中开发大量逻辑,以便 "branch out" 对多个数据存储进行搜索并聚合返回的结果。
- 每个数据存储的响应时间可能不同,因此,您必须等待最慢的数据存储响应才能向用户显示搜索结果(除非您通过使用不同的异步来避免这种情况技术,例如 Ajax、websocket 等)
如果您想提供更好、更可靠的搜索体验,选项 #1 显然会得到我的投票(实际上我大部分时间都采用这种方式)。正如您正确指出的那样,此选项的主要 "drawback" 是您需要使 Elasticsearch 与其他主数据存储中的更改保持同步。
由于您的其他数据存储将是关系数据库,您有几个不同的选项可以使它们与 Elasticsearch 保持同步,即:
- 使用 Logstash JDBC input
- 使用 JDBC importer 工具
前两个选项效果很好,但有一个主要缺点,即它们不会在您的 table 上捕获 DELETE,它们只会捕获 INSERT 和 UPDATE。这意味着如果你删除了一个用户、账户等,你将无法知道你必须删除 Elasticsearch 中的相应文档。当然,除非您决定在每次导入会话之前删除 Elasticsearch 索引。
为了缓解这种情况,您可以使用另一个基于 MySQL binlog 的工具,从而能够捕获每个事件。有一个写在 Go, one in Java and one in Python.
更新:
这是关于该主题的另一篇有趣的博客文章:How to keep Elasticsearch synchronized with a relational database using Logstash
请看Debezium。这是一个变更数据捕获 (CDC) 平台,可让您流式传输数据。
我创建了一个简单的 github repository,展示了它如何与 PostgreSQL 和 ElasticSearch 一起工作。