Как стать автором
Обновить

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

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

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

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

Т.е. при записи первого документа создается индекс с нужными настройками и алиасом для поиска.
Спасибо за статью!
Подскажите пожалуйста.
У нас используется 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?
Есть ли возможность откатиться назад?
И самое главное есть ли смысл переходить?
> И самое главное есть ли смысл переходить?
Если вам нужны какие-то фичи, появившиеся в 6й ветке. Иначе смысла мало, потратите кучу времени, и ничего не выиграете в итоге. 6я версия обратно не совместима с 5й.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

max_restore_bytes_per_sec

Throttles per node restore rate. Defaults to 40mb per second.
Или вот это 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
PUT .kibana/_settings
{
«index»: {
«number_of_replicas»: "<количество_дата_нод>"
}
}


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

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

По поводу компрессии курсоров, проще в настройка 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 для более раннего запуска дефрагментации памяти.
С GCG1 на ранних сборках 8ки (и кажется даже 10ки) наблюдали забавные глюки — собственно поэтому официально этот сборщик не поддерживается, но в планах его включить т.к. CMS уже помечен как deprecated в 10ке, и Oracle/OpenJDK настоятельно рекомендуют именно G1.
Расскажите, я не встречал не на 8-ке, не на 9-ке и на 10-ке тем более. С 10 версии Java G1GC по умолчанию идет.
В старом посте упоминаются 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 и если новых проблем не будет — то партия даст добро.
У нас, при высокой нагрузке по индексации, периодически одна из дата-нод получала очень высокую нагрузку и уходила в себя, остальной кластер простаивал и ждал пока она разгрузится. Грешили на железо, но проблема была плавающая (проблемная дата нода проявлялась случайно) и на низкой нагрузке не проявлялась. В итоге помог возврат с G1 на CMS. Если ничего не путаю, это был ES2.х и JavaSE 8u25.
Не разу таких ситуаций не было с G1GC.
У меня есть один ES 2.x работает на 8 Java (оракловая jdk-8u172-linux-x64.rpm)
Никаких проблем. А вы не пробовали через jstatd посмотреть, что происходит в Heap.
Собрать логи GC, проанализировать их в gceasy.io, очень хорошо показывает проблемы. Вопрос номер два, не наблюдался большой systime, что может быть указателем на большую фрагментацию памяти.
Было уже очень давно, сервера в изолированной зоне, даже вынести и проанализировать на внешнем сервисе было проблемой, тут уже просто поделился результатом почти месяца выяснения причин.
Т.е. сам G1GC вы не настраивали?
История 2016 года, сложно вспомнить, крутили отладку по ElasticSearch, думали, что проблема в нем или в том, как мы его используем. Решение вернуться на CMS было уже от «давайте еще идей», и то, что оно помогло, моментально перевело ситуацию к «работает — не трогай».
adel-s можете еще подсказать. В доке elasticsearch указано что нужно использовать 50% под HEAP.
А куда девается/где используется остальные 50% памяти? Где почитать можно? Искал — но ответа не нашел. Спасибо.
Там же, в доках, указано что остальное используется под кеши ядра и при нехватке свободной памяти производительность будет проседать:
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.
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% от общей оперативной памяти), нужно понимать, что эта память всегда будет свободна.

"Проблема в том, что на свежеустановленном кластере шаблон по умолчанию выглядит примерно так: " А где он этот "шаблон по умолчанию" ?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий