我有一个数据库表和一个 Lucene(可能是 Solr)索引。目标是索引数据库表,每行恰好一个文档。然而:
- Lucene 索引的初始状态是未知的,可能大部分已经同步。它还可能包含不存在行的文档,之后将通过另一种机制将其删除。
- 执行重新同步的应用程序可能需要在此过程中多次重新启动。很少有状态可以在重新启动时存储(理想情况下没有),因此预先强制设置差异是行不通的。
- 不允许对 Lucene 索引进行低级访问;我可以对它运行查询,但不能。直接枚举给定字段中的术语。可以通过查询来查找键或计算范围内的键。
- 数据库中的行没有任何版本信息或 ETag。我们可以假设它们只是一列唯一键。
此处无需处理过期或需要删除的文档。我只需要确保每一行最终都有一个文档,尽可能少地浪费时间。
更新或删除过期文档由系统的一个单独部分处理,该部分可能假定仅在此重新同步机制指示完成后运行。(事实上,一个强大的更新/删除系统很容易......)
以前这个任务是通过蛮力集差异完成的,但是对于特别大的数据集会遇到困难,并且解决方案确实需要利用部分同步来支持恢复:如果应用程序总是在它之前取得一些进展重新启动它最终将同步商店。
The Difference Digest https://www.ics.uci.edu/~eppstein/pubs/EppGooUye-SIGCOMM-11.pdf看起来很有趣,但似乎仅适用于数据存储具有必要的智能来自行计算的情况。在这种情况下,只有一个应用程序在做这项工作,它只能对两个存储进行查询、插入和删除。
到目前为止,我认为这里有三种基本情况:
- 这些集合非常不同步,例如。索引为空。这应该很容易处理,只需从任一集合的最低 ID 开始,从源查询一批记录,并在目标中添加/删除差异。不幸的是,虽然这最初会很快取得进展,但由于每次重新启动后需要更长的“追赶”时间,它会变慢。
- 这些集合几乎是同步的。感觉应该有一种有效的方法来处理这个问题,也许是通过在数据集中生成一个直方图并深入到与源不“匹配”的各个桶中,但仍然有必要访问每个键并添加它是某种桶哈希。
- 这些集合有大量的细微差别,即。每个中的行数相同,但其中约 60% 的行具有不同的键。这似乎是最坏的情况,但并不是特别不可能。
有解决这个问题的既定技术吗?事实上,我们确实使用一种事务日志来记录需要添加的内容,但这只能处理正常操作,不能处理初始同步或迁移后修复。
我知道有些产品和系统可以“为我”处理这个问题,但还有其他实现问题,这意味着该系统目前必须在现有代码库中实现,尽管它可能会被更通用的解决方案取代未来。事实上,这样做的全部意义在于使当前系统成为“中途”,以便能够使用其他解决方案。
我想系统的更新/删除部分可能会被滥用来记录完整扫描的进度,通过添加占位符文档,该过程完成后会自动删除?我想避免在集合几乎同步时进行全面扫描,但是......