Девять граблей Elasticsearch, на которые я наступил

    Автор иллюстрации — Anton Gudim


    «Подготовленный человек тоже наступает на грабли.
    Но с другой стороны — там, где ручка.»


    Elasticsearch — прекрасный инструмент, но каждый инструмент требует не только настройки и ухода, но и внимания к мелочам. Некоторые — незначительны и лежат на поверхности, а другие спрятаны так глубоко, что на поиск уйдет не один день, не один десяток кружек кофе и не один километр нервов. В этой статье расскажу про девять замечательных граблей в настройке эластика, на которые я наступил.

    Я расположу грабли по убыванию очевидности. От тех, которые можно предусмотреть и обойти на этапе настройки и ввода кластера в production state, до весьма странных, но приносящих самый большой опыт (и звёзды в глазах).

    Data-ноды должны быть одинаковыми


    «Кластер работает со скоростью самой медленной дата-ноды» — выстраданная аксиома. Но есть ещё один очевидный момент, не связанный с производительностью: эластик мыслит не дисковым пространством, а шардами, и старается равномерно распределить их по дата-нодам. Если на какой-то из дата-нод больше места, чем на других, то оно будет бесполезно простаивать.

    Deprecation.log


    Может случиться, что кто-то пользуется не самым современным средством отправки данных в эластик, которое не умеет ставить Content-Type при выполнении запросов. В этом списке, например, heka, или когда логи уходят с устройств их встроенными средствами). В таком случае deprecation. log начинает расти с устрашающей скоростью, и на каждый запрос в нём появляются такие строчки:

    [2018-07-07T14:10:26,659][WARN ][o.e.d.r.RestController] Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header.
    [2018-07-07T14:10:26,670][WARN ][o.e.d.r.RestController] Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header.
    [2018-07-07T14:10:26,671][WARN ][o.e.d.r.RestController] Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header.
    [2018-07-07T14:10:26,673][WARN ][o.e.d.r.RestController] Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header.
    [2018-07-07T14:10:26,677][WARN ][o.e.d.r.RestController ] Content type detection for rest requests is deprecated. Specify the content type using the [Content-Type] header.
    

    Запросы приходят, в среднем, каждые 5-10 мс — и каждый раз в лог добавляется новая строчка. Это негативно влияет на производительность дисковой подсистемы и увеличивает iowait. Deprecation.log можно выключить, но это не слишком разумно. Чтобы собирать логи эластика в него же, но не допускать замусоривания, я отключаю только логи класса o.e.d.r.RestController.

    Для этого нужно добавить в logs4j2.properties такую конструкцию:

    logger.restcontroller.name = org.elasticsearch.deprecation.rest.RestController
    logger.restcontroller.level = error
    

    Она повысит логи этого класса до уровня error, и они перестанут попадать в deprecation.log.

    .kibana


    Как выглядит обычный процесс установки кластера? Ставим ноды, объединяем их в кластер, ставим x-pack (кому нужен), ну и конечно, Kibana. Запускаем, проверяем, что всё работает и Кибана видит кластер, и продолжаем настройку. Проблема в том, что на свежеустановленном кластере шаблон по умолчанию выглядит примерно так:

    {
    	"default": {
    		"order": 0,
    		"template": "*",
    		"settings": {
    			"number_of_shards": "1",
    			"number_of_replicas": "0"
    		}
    	},
    	"mappings": {},
    	"aliases": {}
    }

    И индекс .kibana, где хранятся все настройки создаётся в единственном экземпляре.

    Как-то был случай, когда из-за аппаратного сбоя полегла одна из дата-нод в кластере. Он довольно быстро пришел в консистентное состояние, подняв реплики шард с соседних дата-нод, но, по счастливому совпадению, именно на этой дата-ноде располагался единственный шард с индексом .kibana. Ситуация патовая — кластер живой, в рабочем состоянии, а Kibana в red-статусе, и у меня разрывается телефон от звонков сотрудников, которым срочно нужны их логи.

    Решается всё это просто. Пока ещё ничего не упало:

    XPUT .kibana/_settings
    {
    	"index": {
    		"number_of_replicas": "<количество_дата_нод>"
    	}
    }

    XMX/XMS


    В документации написано — «No more than 32 GB», и это правильно. Но также правильно и то, что не нужно устанавливать в настройках сервиса
    -Xms32g
    -Xmx32g

    Потому что это уже больше чем 32 гигабайта, и тут мы упираемся в интересный нюанс работы Java с памятью. Выше определённого предела Java перестаёт использовать сжатые указатели и начинает потреблять неоправданно много памяти. Проверить, использует ли сжатые указатели Java-машина с запущенным Elasticsearch, очень просто. Смотрим в лог сервиса:

    [2018-07-29T15:04:22,041][INFO][o.e.e.NodeEnvironment][log-elastic-hot3] heap size [31.6gb], compressed ordinary object pointers [true]

    Объем памяти, который не стоит превышать, зависит, в том числе, от используемой версии Java. Чтобы вычислить точный объем в вашем случае — смотрите документацию.

    У меня сейчас на всех дата-нодах эластика установлено:

    -Xms32766m
    -Xmx32766m

    Вроде бы банальный факт, и в документации хорошо описан, но регулярно в работе сталкиваюсь с инсталляциями Elasticsearch, где этот момент упущен, и Xms/Xmx выставлены в 32g.

    /var/lib/elasticsearch


    Это путь по-умолчанию для хранения данных в elasticsearch. yml:

    path.data: /var/lib/elasticsearch

    Туда я обычно монтирую один большой RAID массив, и вот почему: указываем ES несколько путей для хранения данных, например, так:

    path.data: /var/lib/elasticsearch/data1, /var/lib/elasticsearch/data2

    В data1 и data2 смонтированы разные диски или raid-массивы. Но эластик не делает балансировки и не распределяет нагрузку между этими путями. Сначала он заполняет один раздел, потом начинает писать в другой, поэтому нагрузка на хранилища будет неравномерной. Зная это, я принял однозначное решение — объединил все диски в RAID0/1 и смонтировал его в путь, который указан в path.data.

    available_processors


    И нет, я сейчас имею в виду не процессоры на ingest-нодах. Если заглянуть в свойства запущенной ноды (через _nodes API), можно увидеть примерно такое:

    "os". {
    	"refresh_interval_in_millis": 1000,
    	"name": "Linux",
    	"arch": "amd64",
    	"version": "4.4.0-87-generic",
    	"available_processors": 28,
    	"allocated_processors": 28
    }

    Видно, что нода запущена на хосте с 28 ядрами, а эластик правильно определил их количество и запустился на всех. Но если ядер больше 32, то иногда бывает так:

    "os": {
    	"refresh_interval_in_millis": 1000,
    	"name": "Linux",
    	"arch": "amd64",
    	"version": "4.4.0-116-generic",
    	"available_processors": 72,
    	"allocated_processors": 32
    }

    Приходится принудительно выставлять количество доступных сервису процессоров — это хорошо сказывается на производительности ноды.

    processors: 72

    thread_pool.bulk.queue_size


    В разделе про thread_pool.bulk.rejected прошлой статьи была такая метрика — счётчик количества отказов по запросам на добавление данных.

    Я писал о том, что рост этого показателя — очень плохой признак, и разработчики рекомендуют не настраивать пулы тредов, а добавлять в кластер новые ноды — якобы, это решает проблемы с производительностью. Но правила нужны и для того, чтобы иногда их нарушать. Да и не всегда получается «забросать проблему железом», поэтому одна из мер борьбы с отказами в bulk запросах — поднять размеры этой очереди.

    По умолчанию настройки очереди выглядят так:

    "thread_pool":
    {
    	"bulk": {
    		"type": "fixed",
    		"min": 28,
    		"max": 28,
    		"queue_size": 200
    	}
    }

    Алгоритм такой:

    1. Собираем статистику по среднему размеру очереди в течение дня (мгновенное значение хранится в thread_pool.bulk.queue);
    2. Аккуратно увеличиваем queue_size до размеров чуть больших, чем средний размер активной очереди — потому что отказ возникает при его превышении;
    3. Увеличиваем размер пула — это не обязательно, но приемлемо.

    Для этого добавляем в настройки хоста что-то наподобие такого (значения у вас, конечно, будут свои):

    thread_pool.bulk.size: 32
    thread_pool.bulk.queue_size: 500

    И после перезапуска ноды обязательно мониторим нагрузку, I/O, потребление памяти. и всё что можно, чтобы при необходимости откатить настройки.

    Важно: эти настройки имеют смысл только на нодах работающих на приём новых данных.

    Предварительное создание индексов


    Как я говорил в первой статье цикла, мы используем Elasticsearch для хранения логов всех микросервисов. Суть проста — один индекс хранит логи одного компонента за один день.

    Из этого следует, что каждые сутки создаются новые индексы по числу микросервисов — поэтому раньше каждую ночь эластик впадал в клинч примерно на 8 минут, пока создавалась сотня новых индексов, несколько сотен новых шардов, график нагрузки на диски уходил «в полку», вырастали очереди на отправку логов в эластик на хостах, и Zabbix расцветал алертами как новогодняя ёлка.

    Чтобы этого избежать, по здравому размышлению был написан скрипт на Python для предварительного создания индексов. Скрипт работает так: находит индексы за сегодня, извлекает их маппинги и создаёт новые индексы с теми же маппингами, но на день вперёд. Работает по cron, запускается в те часы, когда Эластик наименее загружен. Скрипт использует библиотеку elasticsearch и доступен на GitHub.

    Transparent Huge Pages


    Как-то раз мы обнаружили, что ноды эластика, которые работают приём данных, начали зависать под нагрузкой в пиковые часы. Причём с очень странными симптомами: использование всех процессорных ядер падает до нуля, но тем не менее сервис висит в памяти, исправно слушает порт, ничего не делает, на запросы не отвечает и через какое-то время вываливается из кластера. На systemctl restart сервис не реагирует. Помогает только старый-добрый kill −9.

    Стандартными средствами мониторинга это не отлавливается, на графиках до самого момента падения штатная картина, в логах сервиса — пусто. Дамп памяти java-машины в этот момент сделать тоже не удавалось.

    Но, как говорится, «мы же профессионалы, поэтому спустя какое-то время нагуглили решение». Похожая проблема освещалась в треде на discuss.elastic.co и оказалась багом в ядре, связанным с tranparent huge pages. Решилось всё выключением thp в ядре, с помощью пакета sysfsutils.

    Проверить, включены ли у вас transparent huge pages, просто:

    cat /sys/kernel/mm/transparent_hugepage/enabled
    always madvise [never]

    Если там стоит [always] — вы потенциально в опасности.

    Заключение


    Это основные грабли (на деле их было, конечно, больше), на которые мне довелось наступить за полтора года работы в качестве администратора кластера Elasticsearch. Надеюсь, эта информация пригодится вам на сложном и загадочном пути к идеальному кластеру Elasticsearch.

    А за иллюстрацию спасибо Anton Gudim — в его инстаграме еще много хорошего.
    Яндекс.Деньги
    236,00
    Как мы делаем Деньги
    Поддержать автора
    Поделиться публикацией

    Комментарии 68

      0
      Не подскажите, никаких тулзов для архивирования снэпшотов еще не придумали? У меня есть задача хранить много толстых индексов (сотни гигабайт в день) длительное время. Какое-то количество «горячих» индексов живет в кластере, а старые постепенно по одному снэпшотятся и удаляются из кластера. В старых эластиках можно было легко папку со снэпшотом пожать и убрать в куда-то еще более медленное и дешевое место, а вот с 5.х там уже все сложнее. А бесконечно наращивать сторадж тоже не вариант.
        0
        Увы, в связи с нашей спецификой использования эластика — снапшоты мы не делаем.
          0
          Я сейчас делаю это так:
          1. Подключаю репозиторий-директорию для снепшотов
          2. Создаю по снепшоту на каждый индекс
          3. Отключаю репозиторий снепшотов
          4. Создаю архив с репой. Особо не тестил разные алгоритмы сжатия, LZMA пока устраивает.
          5. Очищаю директорию от сырых снапшотов
          6. Отправляю файл с архивом в долгий ящик

          Если дадут разрешение (NDA), то свой скрипт выложу под MIT.
            0
            Да там по сути формат несложный, индекс файлик и набор папок. Индекс это просто json. По нему можно как разобрать, так и собрать снэпшоты по частям. Но не хочется изобретать велосипед, если кто-то уже сделал. У меня к сожалению ваша схема не прокатит, каталог снэпшотов 30 ТБ.
              0
              К сожалению, нельзя вытянуть отдельные снэпшоты из каталога (ссылка).
                0
                В моем случае это не совсем так, так как индекс снэпшотится лишь единожды. Т.е. кусок вытащить можно.
                  0
                  в частном случае да, но в общем случае snapshot'ы инкрементальны
                    0
                    Это все равно не мешает их разбирать по кускам, если что. Если эластик сам может, то и сторонняя утилита тоже.
                      0
                      Понятно, что может — никто из этого никого секрета не делает — open source же. Я про то, что из коробки нельзя вытащить отдельные файлы snapshot'а — в силу специфики Lucene там могут оказаться куски предыдущего snapshot'а, которые мешать не будут, но будут занимать место.

                      Забавно, но буквально сегодня клиент спрашивал — как вытащить последний snapshot из кучи. Может стоит оформить ticket?
          0
          Может сталкивались с задачей склеить два индекса в один? Как решали? Насколько я понимаю, штутных средств эластик не предоставляет.
            0
            Не сталкивался, но «в лоб» решил бы через logstash. Завернуть его на один кластер: читать из двух индексов, складывать в один. Главное проверить чтобы маппинги совпадали.
            Может есть еще какое-то решение, не уверен.
              0
              А даже если маппинги не совпадают, можно придумать схему миграции конфликтующих полей и в пайплане LS разруливать.
                0
                В elasticdump можно указать transform для таких случаев. Индексы правда лучше создать заранее с правильными маппингами, потому что копирует их оно так себе.
              0
              elasticdump
                +1
                Мы используем алиасы.
                  0
                  И это, имхо, самое верное с точки зрения идеологии решение. Только помнить, что писать в алиас поверх >1 индекса нельзя.
                      0
                      Лучший гонец в моей жизни, принесший удивительно прекрасную новость. /me крепко обнимает и целует в карму.
                        0
                        Я сам долго ждал этот функционал. А пока ждал стал делать по другому. Приложуха пишет в индекс с префиксом и индексом. Например «doc-2018-08». И создал template примерно такой:
                        {
                          "template": "doc-*",
                          "aliases": { "searchAlias": {}
                          }
                          mapping ...
                          setting...
                        }

                        Т.е. при записи первого документа создается индекс с нужными настройками и алиасом для поиска.
                +1
                Спасибо за статью!
                Подскажите пожалуйста.
                У нас используется ELK 5.6.8. В ELK 6 написано: Multiple mapping types are not supported in indices created in 6.0
                Как определить какие типы данных относятся к Multiple mapping types?
                Есть ли возможность проверить что ничего не сломается при обновлении с 5.6.8 до 6?
                Есть ли возможность откатиться назад?
                И самое главное есть ли смысл переходить?
                  0
                  > И самое главное есть ли смысл переходить?
                  Если вам нужны какие-то фичи, появившиеся в 6й ветке. Иначе смысла мало, потратите кучу времени, и ничего не выиграете в итоге. 6я версия обратно не совместима с 5й.

                  Лично я обновлялся только из-за появившейся возможности задания кастомной функции tfidf для вычисления similarity в индексах.
                    0
                    В каком смысле
                    6я версия обратно не совместима с 5й.
                    ?

                    Есть ломающие изменения (breaking changes), которые опять-таки описаны — но в целом 6ка должна читать индексы 5ки.
                      0
                      Есть ломающие изменения (breaking changes), которые опять-таки описаны — но в целом 6ка должна читать индексы 5ки.

                      Да, там в целом всё работает, но натыкаешься на разные мелочи.
                      Что-то, что было deprecated, убрали, что-то поменяли, например при создании индекса вместо "index": "not_anylyzed" параметр теперь передаётся как "index": false. Другие подробности не вспомню, апгрейд довольно давно делал.
                      Но эти мелочи выливаются в то, что нельзя просто взять и обновить на серверах эластик, нужно ещё править код своих проектов, и, если используются сторонние библиотеки, то в некоторых случаях и код этих библиотек обновлять.
                        0
                        Согласен, но в целом ES уделяет большое внимание backward-compatibility, и braking changes по возможности делать как можно меньше — если только уже совсем никак. Но и старый воз костылей не хочется ни тащить, ни поддерживать.
                    +1
                    Multiple mappings types означает что больше нельзя в одном индексе несколько типов иметь. Например myindex/users, myindex/sessions. Раньше так можно было, теперь — нет. Созданные до перехода на 6.х индексы будут работать, а вот новые такие уже не создать.
                    0
                    А проблему создания в полночь тыквы, т.е. новых индексов не пробовали решать переходом c yyyy.mm.dd-index схемы на роллап? У меня не так много индексов, но старые индексы ночью мигрируют с hot нод на warm и это тоже доставляет, вот подумываю роллап попробовать, что бы новы ихдекс создавался только при переполнении старого, кроме этого может быть количество шардов уменьшится…
                      0
                      Да много чего по кластеру надо делать, сервис (в его нынешней конфигурации), существует уже восемь месяцев, изменения назрели. Но это буду делать, увы, уже не я.
                      Миграция шард — да, это головная боль. В среднем миграция данных за одни сутки занимает около 8 часов. И хоть гоняется ночью, но к утреннему росту нагрузки уж еле-еле поспевает.
                      0
                      Про 32Гб достаточно подробно описано в документации и о том насколько именно надо быть меньше 32х Гб даже в зависимости от версии java.
                        0
                        Как повлияло на производительность выключение thp?
                          0
                          Никак. Только зависать перестало.
                          0
                          Из похожих «внезапных» проблем:
                          1. Неочевидный лимит на число документов на шард (не более 2 147 483 647 документов) .
                          2. Странное поведение, когда несколько инстансов эластика на 1 сервере работают быстрее чем один (на тех же CPU и дисках, у нас магическая цифра 25 тыс документов в секунду на 1 датаноду).
                          3. Если по каким-то причинам маппинг на индекс не применился по темплейту и эластик его придумал сам (авто маппинг), самые необычные глюки при последующем поиске в данных между нормальными и «странными индексами». Хотя данные в _source выглядят идентично
                            0
                            Огогошеньки у вас объемы! Спасибо, про лимит на шард не знал.
                            Записал в книжечку.

                            По. п.2 — посмотрите на numactl. Возможно там собака зарыта.
                              0
                              Про лимит документов — это общая проблема Lucene-based движков. Elastic в этом не одинок.
                                0
                                Если по каким-то причинам маппинг на индекс не применился по темплейту и эластик его придумал сам (авто маппинг), самые необычные глюки при последующем поиске в данных между нормальными и «странными индексами». Хотя данные в _source выглядят идентично

                                + объем данных индексов почти в 2 раза больше(на наших инсталляциях), помогает _reindex
                                  0
                                  Зависит от данных и задач, конечно, но у нас 99.9% с dynamic: strict теперь, как раз из-за третьего пункта.
                                  0
                                  Добрый день.
                                  Статья отличная, спасибо!
                                  Скажите, вы используете curator? Я предполагал, что предварительное создание индексов как раз ему под силу.
                                    0
                                    Нет, не используем, но это отличная вещь, рекомендую. Сам не использовал, мне было интересно написать скрипты обслуживания самому :)
                                      0
                                      А почему отказались от него, если не секрет?)
                                        0
                                        Не то чтобы «отказались», а просто не начинали. Интересно было самому в деталях реализации разобраться, прежде чем стандартные инструменты использовать. Но к нему все придет, да.
                                    0
                                    В вашей соседней статье (к сожалению, пока не могу ее комментировать) приводятся данные по мощности серверов. Возникли вопросы:
                                    Как вы пришли к такому сайзингу (в особенности памяти для data узлов)? Опытным путем?
                                    Какой % памяти на data ноде отдаете под heap? 50%?
                                    Зачем такие мощные mater ноды?
                                      0
                                      1. Память для дата-нод выделяли сразу по максимуму — 32 гб. И то не хватает периодически. Была мысль попробовать перейти на 64 гб с использованием другого GC (Shenandoah), но руки не дошли и, боюсь, что уже не дойдут. А вот для клиентских нод (в которые смотрит Kibana), подбирали опытным путем, да. Через некоторое время дошли до 24 гб и на этом остановились.
                                      2. «Какой % памяти на data ноде отдаете под heap? 50%?» — вопроса не понял, уточните, пожалуйста.
                                      3. Это старая конфигурация. Она уже была, когда я пришел в компанию и получил в руки то, что получил. В следующей статье, я рассказывал как кластер переделывался под бОльшую оптимизацию ресурсов. Там я разместил все в LXC контейнеры и на каждый железный сервер влезло 2 дата-ноды + 1 мастер. И средствами LXC контейнеры лимитировались по процессорным ядрам — мастерам отдавалось по чуть-чуть, остальное уходило дата-нодам.
                                      Но и это уже старая конфигурация. Потом я перевел кластер на hot/warm архитектуру и там все опять поменялось :)
                                        0
                                        Читайте основную доку: www.elastic.co/guide/en/elasticsearch/guide/current/hardware.html

                                        За себя могу сказать, что желание поднять размер хипа повыше возникает очень быстро, но реально жить можно как и оговорено в статье, когда хип не более 50% от оперативной памяти.
                                          0
                                          А, вот теперь я понял что вы имели в виду «Какой % памяти на data ноде отдаете под heap? 50%?»
                                          Отвечаю — дата-нодам мы выдаем 32 гб. А сервера под дата-ноды закупаем с 64-128 (что чаще) Гб памяти на борту. У нас объемы такие, что дата-нодам отдаем максимум того, что они могут использовать.
                                          +3
                                          Еще добавим грабелек:

                                          Для любого незакрытого индекса на диске требуется оперативная память как минимум 0,1% -0,5% (зависит от маппинга и используемых фич) от объема это индекса на диске. Просто для открытия шардов. Что в купе с требованием про HEAP_SIZE < 32g и тем что хип нужен не только чтобы индексы открыть — приводит к ограничению 16 — 24 ТБ индекса на одной ноде. Дальше придется городить огород с несколькими инстансами на сервер. Причем это еще без всяких сложных запросов.

                                          Очень долгая миграция шардов с узла на узел. Гораздо быстрее «холодные» индексы закрыть, потом rsync скопировать а потом открыть. Но удается это не очень всегда.

                                          Размер кластера ограничен количеством шардов в нем. На практике с ростом числа индексов и шардов просто катастрофически увеличивается время создания новых индексов. Причем в старых версиях просто больше 3х узлов при 20 тысячах индексов (пара шардов на каждый). В новых версиях лучше.

                                          Если активно используете scroll|scan см пункт первый. Ибо scroll_id включает в себя идентификаторы всех шард на которых хоть что-то нашлось пригодное для скана. У нас он достигал значений в сотни мегабайт на кластере из 20-30 узлов с сотней тысяч индексов.

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

                                          Крайне ограниченная возможность поменять маппинг. Причем даже простое добавление поля приводит к необходимости переиндексировать данные (но это правда на ЕS 1.7, в свежих не знаю)
                                            0
                                            Тоже дошли до состояния тупящих нод, подумываем про разделение на кластеры, ситуация вроде позволяет.

                                            Кстати, про холодные индексы: пилил их для внутреннего использования, после попробовал предложить эту фичу девелоперам, но они отказались, слишком сложно. У нас на проде прилично экономит хип, но не никак не посмотрю, как сильно ухудшились поиски. Лежит здесь: github.com/m31collision/elasticsearch/tree/unloadable-indices
                                              0
                                              Видимо одинаковые мысли приходят. Мы запилили крайне похожую вещь для 1.7 аналогично девелоперы отказались (но мы с++, так что джава код там был наверное не очень).
                                              Идея полностью аналогичная + запросы к таким индексам идут через отдельный тредпул. Плюс держим некое количество загруженных «замороженных» индексов в кеше с неким подобим сегментированного LRU алгоритма вытеснения. С учетом того что активных данных у нас примерно 10/300 экономия была существенная.

                                                0
                                                не уверен как в таком виде их можно смёржить в основной репо.
                                                0
                                                Скорость миграции можно поднять, есть опция, по дефолту насколько помню не более 20МБ/с. rsync правда действительно быстрее, но в версиях с 5.х геморней.
                                                  0
                                                  Вот это очень интересно. Не можете подсказать где эту опцию найти? Я все перерыл, не нашел.
                                                    0
                                                    Наверное имеется ввиду вот это:

                                                    max_restore_bytes_per_sec

                                                    Throttles per node restore rate. Defaults to 40mb per second.
                                                      0
                                                      Нет, indices.store.throttle.max_bytes_per_sec, но 6-ке выпили похоже, не учел.
                                                        +1
                                                        Или вот это indices.recovery.max_bytes_per_sec. Сам уже точно не помню.

                                                        И еще вот эту группу настроек можно посмотреть:
                                                        cluster.routing.allocation.node_initial_primaries_recoveries
                                                        cluster.routing.allocation.node_concurrent_incoming_recoveries
                                                        cluster.routing.allocation.node_concurrent_outgoing_recoveries
                                                        cluster.routing.allocation.node_concurrent_recoveries
                                                        cluster.routing.allocation.cluster_concurrent_rebalance
                                                  0
                                                  PUT .kibana/_settings
                                                  {
                                                  «index»: {
                                                  «number_of_replicas»: "<количество_дата_нод>"
                                                  }
                                                  }


                                                  Наверное, правильно «количество_дата_нод — 1» — при трёх нодах заходтим один primary shard и две реплики.
                                                  +1

                                                  А ещё, если индексы не оптимизировать, можно запросто упереться в лимит количества файловых дескрипторов в ОС.

                                                    +2
                                                    По поводу компрессии курсоров, проще в настройка Java выставить -XX:+UseCompressedOops, она просто не даст запуститься с объемом Heap когда компрессия отключается (будет ругаться).
                                                    Дополнительно перфоманса можно выжать, если Java покрутить)
                                                    Я на проде использую GC G1, Huge Pages (-XX:+UseLargePages) большие странички не свопятся, не подвержены фрагментации и все остальные плюхи.
                                                    Желательно писать логи GC во время подручивания Java и анализировать их например через , чтоб оценить работу GC
                                                    А так же, использовать jstatd и VusialVM для просмотра работы GC в режиме online.
                                                    В ранних версия эластика и Java задавался объем young поколения (обычно 1 GB) через параметр -Xmn
                                                    Столкнулся с таким кейсом, когда очень активно использовался young space эластиком, и так как объем был небольшой частый вызов GC. Увеличил в несколько раз наблюдая через VisualVM. Итог нет бешеного GC, эластик стал работать существенно быстрее.
                                                    Для тех, кто юзает mmapfs через sysctl покрутить надо vm.min_free_kbytes для более раннего запуска дефрагментации памяти.
                                                      0
                                                      С GCG1 на ранних сборках 8ки (и кажется даже 10ки) наблюдали забавные глюки — собственно поэтому официально этот сборщик не поддерживается, но в планах его включить т.к. CMS уже помечен как deprecated в 10ке, и Oracle/OpenJDK настоятельно рекомендуют именно G1.
                                                        0
                                                        Расскажите, я не встречал не на 8-ке, не на 9-ке и на 10-ке тем более. С 10 версии Java G1GC по умолчанию идет.
                                                          0
                                                          В старом посте упоминаются A Heap of Trouble: G1:

                                                          LUCENE-6098: Indexwriter changecount assertion fail with g1gc и целый список от Lucene:

                                                          Do not, under any circumstances, run Lucene with the G1 garbage collector. Lucene's test suite fails with the G1 garbage collector on a regular basis, including bugs that cause index corruption.


                                                          Учитывая то, что баг ( bugs.openjdk.java.net/browse/JDK-8038348 ) на который ругаются таки закрыли — сейчас идёт long run test на G1 и если новых проблем не будет — то партия даст добро.
                                                            0
                                                            У нас, при высокой нагрузке по индексации, периодически одна из дата-нод получала очень высокую нагрузку и уходила в себя, остальной кластер простаивал и ждал пока она разгрузится. Грешили на железо, но проблема была плавающая (проблемная дата нода проявлялась случайно) и на низкой нагрузке не проявлялась. В итоге помог возврат с G1 на CMS. Если ничего не путаю, это был ES2.х и JavaSE 8u25.
                                                              0
                                                              Не разу таких ситуаций не было с G1GC.
                                                              У меня есть один ES 2.x работает на 8 Java (оракловая jdk-8u172-linux-x64.rpm)
                                                              Никаких проблем. А вы не пробовали через jstatd посмотреть, что происходит в Heap.
                                                              Собрать логи GC, проанализировать их в gceasy.io, очень хорошо показывает проблемы. Вопрос номер два, не наблюдался большой systime, что может быть указателем на большую фрагментацию памяти.
                                                                0
                                                                Было уже очень давно, сервера в изолированной зоне, даже вынести и проанализировать на внешнем сервисе было проблемой, тут уже просто поделился результатом почти месяца выяснения причин.
                                                                  0
                                                                  Добавлю ссылку на разбор проблем с производительностью, которые в финале пришли проблеме с G1, которую решил откат обратно к CMS.
                                                                  discuss.elastic.co/t/indexing-performance-degrading-over-time/40229
                                                                    0
                                                                    Т.е. сам G1GC вы не настраивали?
                                                                      0
                                                                      История 2016 года, сложно вспомнить, крутили отладку по ElasticSearch, думали, что проблема в нем или в том, как мы его используем. Решение вернуться на CMS было уже от «давайте еще идей», и то, что оно помогло, моментально перевело ситуацию к «работает — не трогай».
                                                          0
                                                          adel-s можете еще подсказать. В доке elasticsearch указано что нужно использовать 50% под HEAP.
                                                          А куда девается/где используется остальные 50% памяти? Где почитать можно? Искал — но ответа не нашел. Спасибо.
                                                            0
                                                            Там же, в доках, указано что остальное используется под кеши ядра и при нехватке свободной памяти производительность будет проседать:
                                                            Lucene makes good use of the filesystem caches, which are managed by the kernel. Without enough filesystem cache space, performance will suffer. Furthermore, the more memory dedicated to the heap means less available for all your other fields using doc values.
                                                              +1
                                                              50% пойдет на нужны самой ОС и страничного кеша ядра, особенно при использовании типа хранения индекса mmapfs. Всегда следите за фрагментацией памяти, особенно где большой интенсивный IO по диску. Симптомы фрагментации (большой systime по процессору, так как вызывается интенсивной работой kswapd0(1), потоком ядра. Например в htop'e можно поставить отображать процессы ядра, он будет всегда в топе по CPU. Второе смотреть через perf top isolate_freepages_block в топе) Хорошая статья у одноклассников habr.com/company/odnoklassniki/blog/266005 в помощь.
                                                              Регулировать можно через sysctl параметром vm.min_free_kbytes (отправная точно 1% от общей оперативной памяти), нужно понимать, что эта память всегда будет свободна.

                                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                            Самое читаемое