我了解使用别名重新索引以避免停机,如此处所述:Is there a smarter way to reindex elasticsearch?
但是仍然存在一个问题:假设重新索引需要一个小时,而原始数据库不断变化。我需要任何更新才能访问这两个索引。
有没有办法做到这一点?
如果没有,我希望更新到新索引,而查询仍然从旧索引提供。但至少在Tire,我还没有看到使用不同索引进行读写的方法。可以这样做吗?
我了解使用别名重新索引以避免停机,如此处所述:Is there a smarter way to reindex elasticsearch?
但是仍然存在一个问题:假设重新索引需要一个小时,而原始数据库不断变化。我需要任何更新才能访问这两个索引。
有没有办法做到这一点?
如果没有,我希望更新到新索引,而查询仍然从旧索引提供。但至少在Tire,我还没有看到使用不同索引进行读写的方法。可以这样做吗?
您不能同时从 Elasticsearch 更新两个索引。您可以自行处理该问题,并向 Elasticsearch 发送 2 个索引请求。
也就是说,尽管我很确定您可以使用 Tire 搜索多个索引(但我不知道 Tire),但您可能可以在这里使用alias
你有一个旧的 index1
将所有内容推送到 index2 在 index1、index2 之上添加别名索引
索引完成后删除 index1
为了在搜索系统使用新的用户生成内容更新时也允许零停机时间索引更改,您可以使用以下策略:
为指向 ES 索引的读取和写入操作定义别名。更新模型时,查找 model_write 别名并使用它写入所有跟踪的索引,这将包括当前活动的索引和任何正在后台构建的索引。
class User < ActiveRecord::Base
def self.index_for_search(user_id)
Timeout::timeout(5) do
user = User.find_by_id(user_id)
write_alias = Tire::Alias.find("users_write")
if write_alias
write_alias.indices.each do |index_name|
index = Tire::Index.new(index_name)
if user
index.store user
else
index.remove 'user', user_id
end
end
else
raise "Cannot index without existence of 'users_write' alias."
end
end
end
end
现在,当您想要进行完整的索引重建(或初始索引创建)时,添加一个新索引,将其添加到别名中,然后开始构建它,因为知道任何活动用户都将同时将他们的数据添加到两个索引中。继续从旧索引读取,直到构建新索引,然后切换读取别名。
class SearchHelper
def self.set_alias_to_index(alias_name, index_name, clear_aliases = true)
tire_alias = Tire::Alias.find(alias_name)
if tire_alias
tire_alias.indices.clear if clear_aliases
tire_alias.indices.add index_name
else
tire_alias = Tire::Alias.new(:name => alias_name)
tire_alias.index index_name
end
tire_alias.save
end
end
def self.reindex_users_index(options = {})
finished = false
read_alias_name = "users"
write_alias_name = "users_write"
new_index_name = "#{read_alias_name}_#{Time.now.to_i}"
# Make new index for re-indexing.
index = Tire::Index.new(new_index_name)
index.create :settings => analyzer_configuration,
:mappings => { :user => user_mapping }
index.refresh
# Add the new index to the write alias so that any system changes while we're re-indexing will be reflected.
SearchHelper.set_alias_to_index(write_alias_name, new_index_name, false)
# Reindex all users.
User.find_in_batches do |batch|
index.import batch.map { |m| m.to_elasticsearch_json }
end
index.refresh
finished = true
# Update the read and write aliases to only point at the newly re-indexed data.
SearchHelper.set_alias_to_index read_alias_name, new_index_name
SearchHelper.set_alias_to_index write_alias_name, new_index_name
ensure
index.delete if defined?(index) && !finished
end
可以在此处找到描述此策略的帖子:http: //www.mavengineering.com/blog/2014/02/12/seamless-elasticsearch-reindexing/