Elasticsearch复制其他系统数据?
假设我想使用elasticsearch在网站上实现一个通用的search。 预计顶级search栏可以查找整个网站中所有不同types的资源。 肯定的文件(通过tika上传/索引),但也包括客户,账户,其他人等。
由于架构的原因,大部分非文档内容(客户端,帐户)将存在于关系数据库中。
当执行这个search时,选项#1将会创build所有文件的版本,然后使用elasticsearch运行search的所有方面,而不是依赖关系数据库来寻找不同types的对象。
选项#2将只使用elasticsearch来索引文档,这意味着对于一般的“网站search”function,您必须将多个search用于多个系统,然后在返回结果之前汇总结果。
选项#1看起来好得多,但缺点是它要求在本质上有弹性的search在生产关系数据库中有很多东西的副本,而且随着情况的变化,这些副本要保持新鲜。
保持这些商店同步的最佳select是什么?我认为对于一般search来说,选项#1是否优越是正确的? 有没有一个选项#3?
在多个数据存储区(即在一个中央数据存储区(选项#1)中search或在所有数据存储区中search并汇总结果(选项#2))时,您几乎列出了两个主要选项。
两个选项都可以工作,尽pipe选项#2有两个主要的缺点:
- 这将需要在您的应用程序中开发大量的逻辑,以便将search“分支出”到多个数据存储,并汇总您找回的结果。
- 每个数据存储的响应时间可能不同,因此,您必须等待最慢的数据存储才能响应,以便将search结果呈现给用户(除非您使用不同的asynchronous技术来避免这种情况,例如Ajax ,websocket等)
如果你想提供一个更好,更可靠的search体验,选项#1显然会得到我的投票(我实际上大部分时间采取这种方式)。 正如您已经正确地指出的那样,这个选项的主要“缺点”是您需要保持Elasticsearch与其他主数据存储区中的更改保持同步。
由于您的其他数据存储将是关系数据库,因此您有几个不同的选项可以使它们与Elasticsearch保持同步,即:
- 使用Logstash JDBCinput
- 使用JDBC导入器工具
前两个选项工作的很好,但有一个主要的缺点,即他们不捕获您的表上的DELETE,他们只会捕获插入和更新。 这意味着如果您删除了用户,帐户等,您将无法知道您必须删除Elasticsearch中的相应文档。 当然,除非您决定在每个导入会话之前删除Elasticsearch索引。
为了减轻这一点,你可以使用另一个基于MySQL二进制日志的工具,从而能够捕捉每一个事件。 有一个用Go编写的,一个用Java编写,一个用Python编写。