Skip to content

Instantly share code, notes, and snippets.

@tlikai
Created March 31, 2017 16:07
Show Gist options
  • Save tlikai/29ddfb3dca134005d6f344c389d5279a to your computer and use it in GitHub Desktop.
Save tlikai/29ddfb3dca134005d6f344c389d5279a to your computer and use it in GitHub Desktop.
Rebuild elasticsearch index with zero downtime
require 'elasticsearch/rails/tasks/import'
namespace :elasticsearch do
desc 'Rebuild index with zerodown time'
task rebuild: :environment do
size = (ENV['size'].presence || 1000).to_i
model = ENV['model'].to_s.classify.constantize
delete_old_index = ENV['delete'].present?
es = model.__elasticsearch__
count = 0
total = model.count
origin_index_name = model.index_name
new_index_name = "#{origin_index_name}_#{Time.current.strftime('%Y%m%d%H%M%S')}"
model.find_in_batches(batch_size: size) do |group|
actions = group.map do |record|
count += 1
puts "Import #{model} to #{new_index_name} #{count}/#{total}"
{ index: { _id: record.id, data: record.as_indexed_json } }
end
es.client.bulk(
index: new_index_name,
type: model.document_type,
body: actions
)
end
old_indices = begin
es.client.indices.get_alias(name: origin_index_name).keys
rescue Elasticsearch::Transport::Transport::Errors::NotFound
{}
end
actions = old_indices.map do |old_index_name|
{ remove: { index: old_index_name, alias: origin_index_name } }
end
actions << { add: { index: new_index_name, alias: origin_index_name } }
es.client.indices.update_aliases(body: { actions: actions })
puts "Alias #{new_index_name} to #{origin_index_name}"
next unless delete_old_index
old_indices.each do |old_index_name|
puts "Delete #{old_index_name}"
es.client.indices.delete(index: old_index_name)
end
end
end
@tlikai
Copy link
Author

tlikai commented Mar 31, 2017

bundle exec rake elasticsearch:rebuild model=post # rebuild index
bundle exec rake elasticsearch:rebuild model=post delete=true # rebuild index and delete old index

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment