我正在为可以更新文档的博客实施弹性搜索。
我需要在弹性搜索中执行无中断重建索引,以避免竞争并保持一致性。 (通过一致性,我的意思是如果应用程序执行写入后跟查询,则查询应该在重新索引期间显示更改)。
我能找到的最好的建议是你使用别名来原子地切换应用程序正在使用哪个索引,并且应用程序写入旧索引(通过write_alias
)和新索引(在重建索引操作期间写入时,通过特殊的write_next_version
别名),并从旧索引读取(通过read_alias
)。只要应用程序首先写入旧索引并将新索引写入第二个,reindex与应用程序之间的并发写入中的任何比赛都将由文档版本号解析。重建索引完成后,只需atomically switch应用程序对新索引的读写别名并删除write_next_version
别名。
但是,仍然存在种族和性能问题。
我的应用程序不知道发生了重新索引,reindex
并且涉及的别名切换是一个单独的长时间运行过程。我可以使用HEAD命令查明是否存在特殊的write_next_version
别名,只有在存在时才会写入。但是,这是ES服务器的额外往返。 HEAD命令和上述reindex进程之间仍然存在争用,删除第二个write_next_version
别名。我可以每次都做两次写操作,并默默地将错误处理到通常不存在的write_next_version
别名。如果我的文档很小,我会通过bulk API执行此操作,但它们是博客条目,它们可能相当大。
我应该每次只写两次并在第二次写入时吞下错误?或者我应该使用HEAD
API来确定应用程序是否需要执行第二次写入以保持一致性?或者有更好的方法吗?
此策略的概要显示在此article中。此older article也显示了如何执行此操作,但它们不使用不可接受的别名。 Elastic Search github上有一个related issue,但是它们没有解决为了保持一致性而需要完成两次写入的问题。他们也没有解决比赛或性能问题。 (他们关闭了这个问题......)