From ebbe8016650c2d090873a8799e8b127a39a592bf Mon Sep 17 00:00:00 2001 From: "Marcos G. Zimmermann" Date: Mon, 1 Jul 2024 12:42:11 -0300 Subject: [PATCH] Tune index settings for better performance during index reset (#11) * feat: set number_of_replicas to zero and disable refresh_interval during the index reset * close index before update settings * add self to confusion with Kernel#open * fix: can not update number of replicas in a closed index * only delete existing index when the alias name is a real index * fix: fixing broken specs --- lib/esse/index/indices.rb | 29 ++++++++++++++++++++++------- spec/esse/cluster_spec.rb | 12 +++++++----- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/esse/index/indices.rb b/lib/esse/index/indices.rb index c769d29..16e7c0f 100644 --- a/lib/esse/index/indices.rb +++ b/lib/esse/index/indices.rb @@ -26,10 +26,10 @@ module ClassMethods # # @see http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/ # @see Esse::Transport#create_index - def create_index(suffix: nil, **options) + def create_index(suffix: nil, body: nil, **options) options = CREATE_INDEX_RESERVED_KEYWORDS.merge(options) name = build_real_index_name(suffix) - definition = [settings_hash, mappings_hash].reduce(&:merge) + definition = body || [settings_hash, mappings_hash].reduce(&:merge) if options.delete(:alias) && name != index_name definition[:aliases] = { index_name => {} } @@ -48,13 +48,23 @@ def create_index(suffix: nil, **options) # @return [Hash] the elasticsearch response # # @see https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-open-close.html - def reset_index(suffix: index_suffix, import: true, reindex: false, **options) + def reset_index(suffix: index_suffix, optimize: true, import: true, reindex: false, **options) cluster.throw_error_when_readonly! - existing = [] + suffix ||= Esse.timestamp - suffix = Esse.timestamp while index_exist?(suffix: suffix).tap { |exist| existing << suffix if exist } + suffix = Esse.timestamp while index_exist?(suffix: suffix) + + if optimize + definition = [settings_hash, mappings_hash].reduce(&:merge) + number_of_replicas = definition.dig(Esse::SETTING_ROOT_KEY, :index, :number_of_replicas) + refresh_interval = definition.dig(Esse::SETTING_ROOT_KEY, :index, :refresh_interval) + new_number_of_replicas = ((definition[Esse::SETTING_ROOT_KEY] ||= {})[:index] ||= {})[:number_of_replicas] = 0 + new_refresh_interval = ((definition[Esse::SETTING_ROOT_KEY] ||= {})[:index] ||= {})[:refresh_interval] = '-1' + create_index(**options, suffix: suffix, alias: false, body: definition) + else + create_index(**options, suffix: suffix, alias: false) + end - create_index(**options, suffix: suffix, alias: false) if index_exist? && aliases.none? cluster.api.delete_index(index: index_name) end @@ -63,8 +73,13 @@ def reset_index(suffix: index_suffix, import: true, reindex: false, **options) elsif reindex && (_from = indices_pointing_to_alias).any? # @TODO: Reindex using the reindex API end + + if optimize && number_of_replicas != new_number_of_replicas || refresh_interval != new_refresh_interval + update_settings(suffix: suffix) + end + update_aliases(suffix: suffix) - existing.each { |_s| delete_index!(**options, suffix: suffix) } + true end diff --git a/spec/esse/cluster_spec.rb b/spec/esse/cluster_spec.rb index 9324c54..53e7cc3 100644 --- a/spec/esse/cluster_spec.rb +++ b/spec/esse/cluster_spec.rb @@ -199,13 +199,15 @@ it 'retuns an instance of elasticsearch as default' do expect(model.instance_variable_get(:@client)).to eq(nil) + classes = [] + if defined? Elasticsearch::Client # Elasticsearch-ruby >= 8.0 + classes << Elasticsearch::Client + end if defined? Elasticsearch::Transport::Client - expect(model.client).to be_an_instance_of(Elasticsearch::Transport::Client) - expect(model.instance_variable_get(:@client)).to be_an_instance_of(Elasticsearch::Transport::Client) - else # Elasticsearch-ruby >= 8.0 - expect(model.client).to be_an_instance_of(Elasticsearch::Client) - expect(model.instance_variable_get(:@client)).to be_an_instance_of(Elasticsearch::Client) + classes << Elasticsearch::Transport::Client end + expect(classes).to include(model.client.class) + expect(model.client).to be(model.instance_variable_get(:@client)) end it 'store connection using default key' do