Когда у вас есть большой кластер Elasticsearch, и вы хотите сделать изменение индекса, будь то отображения или настройки, вы хотите иметь некоторые гарантии, что изменение будет улучшать производительность. Изменения также могут быть трудно реализовать, поэтому вы хотите знать, стоит ли усиление производительности времени, когда вам придется предпринять, чтобы обновить код.
Мы сделаем это жить!
Я не ребенку, в первые дни в Кенне, когда мы были маленькими, мы бы буквально проверили на нашем производственном кластере. Подумайте, что новый Shard Setup может быть лучше? Конечно, давайте перенастроим все и посмотрите, что произойдет. Более того, мы закончили поздние ночные сражения, а пожарные боевые, благодарственные оптимизации пошло не так. Это была крутая кривая обучения, но в конце мы выжили!
Теперь, когда мы намного больше, и немного мудрее 😉, мы решили пойти в эти виды изменения немного более ответственно, полностью тестируя их первым! 🎉
Как мы проверяем изменения Elasticsearch
TL; доктор
Теперь мы тестируем изменения Elasticsearch, используя Ruby Поискатель класса Что мы написали. Этот класс позволяет нам сделать запросы два разных индекса одновременно из нашего приложения. Оба запроса, обернуты в код мониторинга, который позволяет нам отслеживать и просматривать их в нашей службе мониторинга. С отслеживанием мы можем сравнить такие вещи, как время запроса, чтобы увидеть, какой индекс выполняет лучше. Ниже приведен один пример, когда мы использовали этот класс.
Оптимизация: Хранение идентификаторов в качестве ключевых слов
В Elasticsearch Training нас сообщили, что нам было сказано, что хранилище IDS в качестве ключевых слов может дать нам повышение производительности, когда она пришла к поиску. Причина состоит в том, что целочисленные типы данных в Elasticsearchearch оптимизированы для запросов диапазона. Ключевые слова оптимизированы для терминов запросов. Термин запрос выглядит так:
{ "terms": { "id": [1, 5, 9] } }
Если вы когда-либо выполняете только термины запросов с вашими идентификаторами, то вы должны хранить их в виде ключевых слов. Это звучало как сплошной совет, но собирается взять на себя некоторую работу, чтобы обновить наши отображения и reindex все 3 миллиарда наших документов, поэтому мы хотели убедиться, что мы действительно увидим некоторые преимущества, прежде чем мы внесли какие-либо изменения.
Настройка тестирования
Прежде чем мы сможем начать тест, мы сначала пришлось создать дубликат индекса нашего производства. Кроме того, этот новый индекс теста будет иметь все идентификаторы, хранящиеся в виде ключевых слов. Мы оно отражаем (скопировано) Все данные из производственного индекса в новый индекс теста, чтобы они оба содержали то же самое данные.
Далее мы должны были поставить хэш в Redis, чтобы сигнализировать на наше приложение, которое мы собирались тестировать этот индекс. Когда наш класс поискового тестирования делает запрос Elasticsearch, сначала проверяет Redis, чтобы увидеть, запустите ли мы тест на запрошенный индекс. Если мы будем, он отправит запрос не только к исходному индексу, но и к индексу тестирования.
Мы создали этот хэш напрямую с нашим классом поиска, используя метод ниже.
def self.set_test_index(original_index_name, test_index_name) index_hashes = cache_index_hashes index_hashes[original_index_name] = { :index_name => test_index_name, :test_searching => true, :test_indexing => true } update_index_cache(index_hashes) end
Полученное хеш выглядит так в Redis:
{ "test_indexes" => { "prod_index" => { "index_name" => "test_index", "test_searching" => true, "test_indexing" => true } } }
Как только этот хэш был на месте, тестирование начнется! Были две вещи, которые мы хотели проверить с нашим классом поиска, скоростью поиска и скоростью индексации.
Тестирование скорости поиска
Когда мы ввели этот новый класс тестирования поиска, мы реализовали его таким образом, что каждый запрос, который мы сделали в Elasticsearch, прошли через него.
@connection.send(m, *args, &block) # was replaced with SearchTesting.new(@connection).send(m, *args, &block)
@connection
Вот объект соединения из нашего elasticsearch-ruby. Gem, который позволяет нам поговорить с Elasticsearch. Передаем это на наш класс поиска, который затем определяет методы, которые мы хотим проверить. Любые неопределенные методы просто отправляются на elasticsearch без помех.
def method_missing(m, *args, &block) connection.send(m, *args, &block) end
Поскольку мы хотели проверить метод поиска, мы определили его так:
def search(*args) self.index_name = args&.first&.dig(:index) test_hash = cache_index_hashes.dig(index_name) test_search_thread = (Thread.new { test_search(*args.deep_dup, test_hash) } if test_searching_enabled?(test_hash)) connection.search(*args) end
Несколько вещей происходит здесь, я хочу увеличить масштаб. Во-первых, мы получаем имя индекса, которому мы делаем запрос. Затем мы проверяем, проверяется ли этот индекс.
self.index_name = args&.first&.dig(:index) test_hash = cache_index_hashes.dig(index_name)
Если тестовый хеш присутствует в Redis, и поиск включен для этого теста HASHH, мы создаем новую тему для запуска запроса теста.
test_search_thread = (Thread.new { test_search(*args.deep_dup, test_hash) } if test_searching_enabled?(test_hash))
Что test_search
Метод довольно прост. Все это делает, замените исходное имя индекса с именем индекса теста, а затем выполняет запрос на индекс теста.
def test_search(*args, test_hash) test_index_name = test_hash[:index_name] # fetch test index name args.first[:index] = test_index_name # replace original index name with test connection.search(*args) # execute request against the test index end
С test_search
Метод работает в другом потоке, нам не нужно беспокоиться о том, чтобы ждать его для завершения. Как только мы выгнали запрос TEST_INDEX, то мы сделаем запрос на исходный индекс и вернуть эти результаты!
Теперь поиск только половина картины. Мы также хотели убедиться, что индексация все еще была исполнена.
Тестирование скорости индексации
Чтобы проверить скорость индексации, нам пришлось тестировать, используя объемный метод, поскольку вся наша индексация выполняется навалом. Мы сделали это похоже на поиск, создав отдельный поток для проведения тестовой индексации в.
def bulk(*args) test_bulk_thread = Thread.new { test_bulk(*args.deep_dup) } connection.bulk(*args) end
Тяжелая часть вот в том, что иногда хэши, идущие в разные индексы, объединены вместе. Благодаря этому, мы должны проверить каждую индексацию хеш индивидуально. Если есть какие-либо хэши, идущие к индексу производства, который проверяется, то мы также будем индексировать эти хэши к индексу теста.
def test_bulk(*args) new_bulk_hashes = test_bulk_hashes(*args) # select hashes to go to the test index return unless new_bulk_hashes.any? # if there are none return connection.bulk({ :body => new_bulk_hashes }) # index hashes to the test index end def test_bulk_hashes(*args) @test_bulk_hashes ||= args.first[:body].map do |index_hash| index_name = test_index_name(index_hash.values.first[:_index]) next unless index_name # if there is an index name, a test is running index_hash.values.first[:_index] = index_name # replace original index with test index index_hash # return new index hash to the map end.compact end
То же, что и с поиском, поскольку индексация происходит в отдельном потоке, как только мы вытираем его, мы можем перейти к индексированию документов к исходному индексу и вернуть этот результат.
Не спешите
Один из ключей, когда вы являетесь индексами тестирования производительности в Elasticsearch Islare, заключается в том, чтобы дать время испытания. Elasticsearch построит кеш, как вы ищете его. Это означает, что ваш оригинальный индекс, который имеет кэширует, скорее всего, будет быстрее первоначально, чем ваш новый индекс. Вы хотите позволить тесту достаточно долго, чтобы создать те же кеши, поэтому тест — это тест на 1-1. Мы обычно позволяем нашим тестам работать не менее нескольких дней. Это не только позволяет индексам времени создавать кеши, но также позволяет сделать широкий спектр запросов на поиск и индексирование.
До сих пор мы использовали этот класс поиска для проверки изменяющихся идентификаторов к ключевым словам и изменениям SCARD. Изменение идентификаторов к ключевым словам дали нам увеличение скорости поиска на 30% без изменений в скорости индексации. Уменьшение нашего Shard Counts повредит нашему характеристику через доску, поэтому мы не двигались вперед с этим изменением в нашей кодовой базе.
Я хотел поделиться этим кодом, так что, надеюсь, другие могут использовать этот класс для настройки своих собственных эластично-исследовательских тестов в Ruby! Если у вас есть какие-либо вопросы или я ничего не объяснил, пожалуйста, не стесняйтесь спрашивать!
Оригинал: «https://dev.to/molly/performance-testing-elasticsearch-2f7»