Высокая производительность агрегации терминов

Я надеюсь на некоторые разъяснения относительно производительности запросов в эластичной версии 1.5.2, которую я недавно наблюдал.

У меня есть строковое поле с высокой кардинальностью (около 200 000 000). Я заметил, что если я использую простую агрегацию терминов с подсказкой выполнения global_ordinals_low_cardinality, происходят две вещи: 1. Запрос возвращает те же результаты, что и с global_ordinals или global_ordinals_hash. 2. Запрос выполняется значительно быстрее. (примерно в два раза быстрее, чем global_ordinals, и в 4 раза быстрее, чем global_ordinals_hash.

Вот запрос:

{
   "aggs": {
      "myTerms": {
         "terms": {
            "field": "myField",
            "size": 1000,
            "shard_size": 1000,
            "execution_hint": "global_ordinals_low_cardinality"
         }
      }
   }
}

Я не понимаю, почему вообще допустимо использовать global_ordinals_low_cardinality в этом случае, потому что мое поле имеет высокую кардинальность. Так что, возможно, я не понимаю, что именно означает global_ordinals_low_cardinality?

Во-вторых, у меня есть еще одно числовое поле (длинное) примерно с таким же значением кардинальности. Значения длинного поля на самом деле являются предварительно вычисленными хеш-значениями (murmur3) для того же строкового поля, что и выше, что я использую для значительного ускорения агрегирования количества элементов. Выполнение агрегации тех же терминов в числовом поле работает так же плохо, как global_ordinals_hash. Фактически, не имеет значения, какую подсказку выполнения я использую, время выполнения остается прежним.

Так почему же global_ordinals_low_cardinality применим для строковых типов, но не для длинных? Это потому, что числовые поля вообще не требуют глобальных порядковых номеров?

Спасибо


person Roman    schedule 02.08.2015    source источник


Ответы (1)


Я думаю, что и официальная документация и исходный код проливают на это некоторый свет. Во-первых, необходимо упомянуть одну вещь: execution_hint — это именно то, о чем говорит его название, т. е. просто намек, который ES постарается соблюдать, но может не во всех случаях, если сочтет это неуместным.

Итак, сам факт того, что у вас есть поле с высокой кардинальностью, исключает использование global_ordinals_low_cardinality, поскольку:

global_ordinals_low_cardinality включен по умолчанию только для полей с низкой кардинальностью.

Что касается global_ordinals_hash, то он в основном используется в агрегациях внутренних терминов (здесь это не тот случай), а map используется только при запуске агрегации скриптов, и несколько документов соответствуют запросу (тоже не cas)

Таким образом, у вас остается один выбор, то есть global_ordinals, который является подсказкой по умолчанию, используемой для агрегирования терминов верхнего уровня.

Как упоминалось ранее, execution_hint — это просто подсказка, которую вы указываете, но ES сделает все возможное, чтобы выбрать правильный режим выполнения для ваших данных, несмотря ни на что. Изучение исходного кода поучительно и проливает свет на несколько вещей:

Начиная здесь вы увидите следующее:

  1. в строке 201 ваша подсказка читается, а затем может быть переопределена, если поле не поддерживает глобальные порядковые номера (строки 205–241)
  2. если ваш поле является числовым, execution_hint полностью игнорируется, и это, вероятно, должно ответить на ваш вопрос.
person Val    schedule 03.08.2015
comment
Спасибо за ответ Вал. Я знаю, что execute_hint может быть переопределен, но я должен напомнить вам, что запрос работает значительно лучше с global_ordinals_low_cardinality, поэтому я не думаю, что он был проигнорирован. Во-вторых, я также хотел бы знать, почему агрегация терминов в строковом поле с высокой кардинальностью может выполняться намного лучше, чем агрегация терминов в его длинном хеш-аналоге, который вообще не требует глобальных порядковых номеров. .? - person Roman; 03.08.2015
comment
Если вы посмотрите на мой второй пункт, я сказал, что подсказка игнорируется только для вашего поля long, которое отвечает на ваш второй вопрос. Если вы указываете подсказку, конечно, она слепо учитывается ES (кроме случаев, когда поле не поддерживает порядковые номера). Что касается того, почему global_ordinals_low_cardinality работает намного лучше, чем его аналоги, этот запрос на включение может пролить некоторый свет. . - person Val; 04.08.2015
comment
Я получил ответ на вторую часть моего вопроса здесь: discuss.elastic.co/t/ Однако мне до сих пор не совсем понятно, почему global_ordinals_low_cardinality работает лучше даже на полях с высокой кардинальностью. - person Roman; 07.08.2015
comment
Спасибо за продолжение. Как сказал jpountz, global_ordinals_low_cardinality — это самый быстрый режим выполнения, но он требует памяти. Возможно, у вас достаточно памяти, поэтому в конце концов это не имеет никакого значения, и вы ничего не замечаете. - person Val; 07.08.2015
comment
Возможно, у меня достаточно памяти, однако я ожидаю увеличения использования кучи, чего не вижу. Однако я не могу с большой уверенностью сказать, что я тщательно протестировал последнее утверждение, поэтому я проведу несколько тестов на следующей неделе и обновлю его соответствующим образом. - person Roman; 07.08.2015