После полуночи создался новый индекс, и duration_ms стал текстом: первая запись содержала строку вместо числа. Вчера график работал, сегодня агрегация ломается. На заводе одинаковые детали делают по чертежу, а не угадывают размер по первому образцу. Elasticsearch тоже нужен чертёж для каждого будущего индекса.
Шаблон встречает новый индекс
Index template
применяется при создании, в том числе после rollover. Он не чинит старый индекс. В шаблоне:
index_patternsвыбирает будущие имена;template.mappingsзадаёт типы полей;template.settingsзадаёт шарды, реплики и политику ILM;data_stream: {}означает, что подходящее имя создаст data stream;priorityвыбирает победителя среди подходящих composable templates.
Победитель один: Elasticsearch не склеивает все шаблоны, подходящие по имени. У встроенных шаблонов логов есть собственные приоритеты; на реальном кластере проверь их перед назначением своего. В учебном пустом кластере конфликтов нет.
Чертёж из деталей
Component template
позволяет разделить общую схему и эксплуатационные настройки. Общие поля ECS используют nginx и приложение, а число реплик и срок хранения у них могут различаться.
Компоненты из composed_of применяются по порядку. Секция template основного шаблона может переопределять их настройки. Но несовместимые типы поля не превращаются магически один в другой: конфликт надо устранить до создания индекса.
Собери и посмотри результат
_index_template показывает сохранённый чертёж, а _mapping схему уже созданного backing-индекса. Найди service.name: это keyword, а message это text. Попробуй заменить duration_ms в документе на "thirty seconds": заданный long не принимает такой текст.
Удаление component template не удаляет документы. Изменение компонента влияет на будущие индексы, но не переписывает маппинг уже созданных.
На настоящем Elasticsearch запрос POST /_index_template/_simulate_index/logs-gonets.app-production покажет итог будущего шаблона без создания данных. Учебная консоль этот endpoint не исполняет: здесь мы создаём отдельный поток и читаем его реальный маппинг.
Меняем схему без сюрприза
- Опиши новый компонент и на настоящем стенде проверь итог через
_simulate_index; в песочнице создай отдельный учебный источник и прочитай_mapping. - Прогони несколько типичных и сломанных записей на отдельном стенде.
- Если меняется несовместимый тип, создай новый индекс и переиндексируй данные с преобразованием, а не пытайся заменить тип в старом маппинге.
- Сделай rollover для будущих записей и проверь, что широкий data view не получил конфликт типов между старым и новым поколением.
dynamic: false не индексирует неизвестные поля, но сохраняет их в _source; dynamic: "strict" отклоняет документ с неизвестным полем. Это разные договоры с приложением. Не включай strict на весь поток, не согласовав поля со всеми командами.
Теперь одинаковая схема переживает полночь. Но увидеть график поздно, если клиентов уже десятки. Алертинг будет проверять сигнал сам.
урок из курса
Урок из курса «Elasticsearch и ELK». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.