我有一个使用 Sunspot 的 Rails 应用程序,它会生成大量单独的更新,这会在 Solr 上产生不必要的负载。将这些更新批量发送到 Solr 的最佳方式是什么?
3 回答
假设来自 Rails 应用程序的更改也更新了持久性存储,您可以检查数据导入处理程序 (DIH)处理程序,该处理程序可以定期安排以更新 Solr 索引。
因此,可以决定批量更新 Solr 的频率,而不是每次在 Solr 上触发更新和提交。
但是,预计搜索结果会出现延迟。
另外,您是否正在更新个人记录并提交?如果使用 Solr 4.0,您还可以检查软提交和硬提交。
Sunspot 使索引一批文档变得非常简单:
Sunspot.index(array_of_docs)
这将向 Solr 发送您在此处寻找的那种批量更新。
Rails 应用程序的诀窍是为这些批次的文档找到正确的范围。它们是由一堆用户请求创建的,并且分散在您不同的应用程序进程中吗?或者你有一些你自己控制的批处理?
GitHub 上的sunspot_index_queue项目看起来是一个合理的方法。
或者,您可以随时关闭 Sunspot 的“自动索引”选项,该选项会在您的文档更新时触发更新。在您的模型中,您可以传入auto_index: false
该searchable
方法。
searchable auto_index: false do
# sunspot setup
end
然后你有更多的自由来控制批量索引。您可能会编写一个独立的 Rake 任务,它会遍历在最后N分钟内创建和更新的所有对象,并以 1,000 个左右的文档批量索引它们。一个无限循环应该能够承受相当稳定的更新流。
在非常大的范围内,您真的希望所有更新都经过某种队列。将您的文档数据插入到Kafka或AWS Kinesis等队列中,以便稍后由另一个独立的索引进程批量处理,这将是大规模的理想选择。
我在这里使用了稍微不同的方法:
我已经auto_index: false
在使用 sidekiq 在后台使用和处理 solr 更新。因此,我没有构建额外的队列,而是使用sidekiq-grouping gem 将 Solr 更新作业组合成批处理。然后我Sunspot.index
在作业中使用索引单个请求中的分组对象。