История инфраструктурных технологий редко развивается по сценарию, в котором одна система внезапно оказывается "плохой", а другая приходит ей на смену в роли безусловного победителя. Обычно всё происходит значительно интереснее. Технологии появляются как ответ на конкретные ограничения своего времени, прекрасно решают поставленные перед ними задачи, постепенно становятся отраслевым стандартом, а затем сталкиваются с изменением окружающей среды. В этот момент выясняется, что проблема заключается вовсе не в качестве инженерных решений. Просто мир, для которого они создавались, перестал существовать в прежнем виде.
Именно это произошло с ELK.
Сегодня вокруг Elasticsearch можно услышать диаметрально противоположные мнения. Одни называют его устаревшим монстром, пожирающим оперативную память и дисковое пространство быстрее, чем отдел закупок успевает согласовывать новые серверы. Другие продолжают считать его золотым стандартом анализа журналов событий и относятся к любым альтернативам с откровенным скепсисом. Как это часто бывает, обе стороны одновременно правы и одновременно ошибаются. Elasticsearch действительно способен превратиться в чрезвычайно дорогой компонент инфраструктуры, если использовать его там, где он изначально не должен был применяться. Но при этом он остаётся одним из самых мощных поисковых движков, когда-либо появлявшихся в инженерном мире.
Чтобы понять, почему Loki сумел так стремительно занять место в современных Kubernetes-платформах и почему Elasticsearch при этом никуда не исчез, необходимо ненадолго вернуться в прошлое и вспомнить, каким выглядела инфраструктура ещё десять-пятнадцать лет назад. Тогда подавляющее большинство приложений представляли собой монолиты, работающие на физических серверах или виртуальных машинах. Релизы происходили относительно редко, зачастую по заранее согласованному графику. Серверы жили годами, их имена практически не менялись, а сами системы обладали довольно предсказуемым поведением. Даже крупные организации зачастую оперировали десятками гигабайт журналов в сутки, а не терабайтами, как это происходит сегодня.
В подобных условиях централизованное логирование выглядело задачей, имеющей вполне очевидное решение. Необходимо было собрать данные с различных источников, привести их к единому виду, сохранить и предоставить удобный механизм поиска. Именно тогда стремительный рост популярности Elasticsearch выглядел абсолютно закономерным. Он предлагал то, чего остро не хватало инфраструктурным командам: возможность превратить хаотичный поток текстовых журналов в структурированную поисковую систему, внутри которой можно было практически мгновенно находить нужную информацию.
Как ELK стал отраслевым стандартом
Популярность ELK невозможно объяснить исключительно удачным маркетингом или отсутствием конкурентов. Наоборот, в разные годы существовало множество альтернативных решений, однако именно связка Elasticsearch, Logstash и Kibana сумела стать тем инструментом, который инженеры начали рекомендовать друг другу практически автоматически.
Причина подобного успеха заключалась в удивительно удачном сочетании возможностей. Logstash позволял принимать события из самых разных источников, преобразовывать их и приводить к единому формату. Elasticsearch обеспечивал высокоскоростной поиск и мощные аналитические возможности. Kibana предоставляла визуальный интерфейс, благодаря которому работа с журналами переставала быть исключительно уделом людей, уверенно чувствующих себя в командной строке. Всё это создавало ощущение законченной платформы, внутри которой можно было решить практически любую задачу, связанную с анализом событий.
Особенно важным оказалось то обстоятельство, что Elasticsearch позволял не просто искать данные, а исследовать их. Это различие кажется незначительным лишь на первый взгляд. В классическом системном администрировании инженер обычно знает, что именно он пытается обнаружить. Например, необходимо найти ошибку подключения к базе данных или выяснить причины отказа приложения. Но существуют задачи совершенно иного класса, где человек не знает ответа заранее и пытается обнаружить закономерности внутри огромных массивов информации.
Именно здесь Elasticsearch раскрывал свои сильнейшие стороны.
Представим расследование инцидента информационной безопасности. Аналитику необходимо определить, какие учётные записи использовались злоумышленником, существовали ли признаки перемещения внутри сети и какие действия предшествовали компрометации системы. Заранее невозможно определить, какие поля окажутся наиболее значимыми. Возможно, придётся анализировать версии программного обеспечения, географию подключений, поведение пользователей или последовательность выполнявшихся операций. Подобная работа напоминает исследование незнакомого города без карты, когда каждое новое наблюдение способно полностью изменить направление дальнейшего поиска.
Именно для подобных сценариев Elasticsearch подходил практически идеально.
Например, вполне обычный запрос мог одновременно фильтровать события, выполнять агрегацию и строить статистическую картину происходящего:
GET logs-*/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"level": "ERROR"
}
}
],
"filter": [
{
"range": {
"@timestamp": {
"gte": "now-24h"
}
}
}
]
}
},
"aggs": {
"top_hosts": {
"terms": {
"field": "host.keyword"
}
},
"top_versions": {
"terms": {
"field": "app.version.keyword"
}
}
}
}
Подобные возможности производили сильное впечатление. Инженеры получали инструмент, который не просто отвечал на заранее известные вопросы, а помогал формулировать новые гипотезы и исследовать данные практически в интерактивном режиме. Именно поэтому ELK очень быстро превратился в стандарт де-факто для централизованного логирования.
Однако любая инженерная магия имеет свою цену.
Почему скорость поиска обходится дорого
Главная сила Elasticsearch всегда заключалась в том, что он заранее подготавливает данные к будущему поиску. Каждое событие разбирается, анализируется и индексируется ещё до того, как пользователь сформулирует запрос. Благодаря этому система способна отвечать с впечатляющей скоростью даже при работе с огромными массивами информации.
Но подобный подход требует серьёзных ресурсов.
Каждое новое поле увеличивает объём индексов. Каждая реплика повышает отказоустойчивость, одновременно увеличивая требования к дисковой подсистеме. Каждый дополнительный shard влияет на сложность сопровождения кластера. Внутренние механизмы Lucene создают служебные структуры, выполняют слияние сегментов и постоянно перераспределяют данные между узлами.
На ранних этапах эксплуатации эти особенности практически незаметны. Когда организация обрабатывает десятки гигабайт журналов в сутки, подобные расходы выглядят вполне оправданными. Но по мере роста инфраструктуры начинают проявляться закономерности, о которых редко рассказывают в рекламных материалах.
Предположим, что платформа генерирует один терабайт журналов ежедневно. На интуитивном уровне кажется, что потребуется примерно такой же объём дискового пространства. Однако в реальности ситуация выглядит значительно сложнее. Индексы занимают дополнительное место. Репликация удваивает объём данных. Фоновые процессы используют вычислительные ресурсы. Возникает необходимость выделять отдельные узлы для мастер-компонентов. Появляются требования к объёму heap-памяти.
Типичная политика создания индексов может выглядеть следующим образом:
PUT _index_template/application-logs
{
"index_patterns": [
"application-*"
],
"template": {
"settings": {
"number_of_shards": 6,
"number_of_replicas": 1,
"refresh_interval": "30s"
}
}
}
Каждый параметр в этой конфигурации представляет собой компромисс между производительностью, стоимостью и отказоустойчивостью. Увеличение количества shard позволяет распределить нагрузку, но одновременно усложняет сопровождение. Репликация защищает от потери данных, однако требует дополнительных дисковых ресурсов. Частое обновление индексов ускоряет появление новых событий в поиске, но увеличивает интенсивность фоновых операций.
Долгое время подобные компромиссы считались вполне приемлемыми. Инженеры принимали их как естественную плату за мощнейшие аналитические возможности Elasticsearch.
А затем в жизнь инфраструктурных команд пришёл Kubernetes.
И именно в этот момент оказалось, что прежняя экономика логирования больше не работает.
Как Kubernetes сломал прежнюю экономику логирования
Появление Kubernetes изменило значительно больше вещей, чем может показаться на первый взгляд. Обычно, говоря о контейнерной оркестрации, инженеры вспоминают автоматическое масштабирование, декларативные развёртывания, GitOps и удобство эксплуатации больших распределённых систем. Однако одной из наиболее недооценённых революций стало фундаментальное изменение самой природы инфраструктурных данных.
До эпохи контейнеров журналы событий представляли собой относительно предсказуемый поток информации. Серверы существовали годами, приложения развёртывались на заранее известных узлах, а их поведение редко выходило за рамки привычных сценариев. Даже если инфраструктура насчитывала несколько сотен виртуальных машин, большинство инженеров могли довольно точно оценить объёмы логов, которые будут генерироваться ежедневно. Система логирования воспринималась как нечто второстепенное: её необходимо было поддерживать в рабочем состоянии, но мало кто ожидал, что однажды она превратится в один из наиболее дорогостоящих компонентов платформы.
Kubernetes принёс совершенно иную модель эксплуатации. Теперь сама инфраструктура стала динамической. Количество экземпляров приложений перестало быть фиксированным. Релизы начали происходить ежедневно, а иногда и несколько раз в течение суток. Автомасштабирование научилось создавать новые pod в ответ на всплески нагрузки, после чего столь же быстро их уничтожать. В результате журналы перестали описывать относительно стабильный мир и превратились в поток телеметрии, отражающий непрерывно изменяющееся состояние системы.
Представим достаточно типичную платформу электронной коммерции среднего размера. Внутри неё работают несколько десятков микросервисов, обслуживающих каталог товаров, корзину, платёжный шлюз, систему уведомлений, рекомендательные механизмы и внутренние административные интерфейсы. Каждый сервис развёрнут в нескольких экземплярах, а в периоды сезонных распродаж автоматически увеличивает количество pod в несколько раз. Дополнительно функционируют фоновые обработчики задач, брокеры сообщений, сервисы аналитики и вспомогательные компоненты самой платформы Kubernetes. Подобная инфраструктура способна без особых усилий генерировать терабайты журналов ежедневно, причём значительная часть этих данных существует исключительно потому, что контейнеры живут считанные минуты и постоянно пересоздаются.
Именно здесь впервые стало очевидно, что традиционный подход к индексированию начинает сталкиваться с экономическими ограничениями. Если раньше индексировать все события казалось вполне разумной стратегией, то в новых условиях цена подобного решения росла практически пропорционально объёмам телеметрии. Дисковые подсистемы увеличивались. Elasticsearch-кластеры расширялись. Возрастали требования к оперативной памяти. Команды эксплуатации тратили всё больше времени на обслуживание самой платформы логирования. В какой-то момент организации начали осознавать неприятную истину: система, предназначенная для наблюдения за инфраструктурой, сама становится одной из наиболее сложных и дорогих систем внутри этой инфраструктуры.
При этом характер работы инженеров практически не изменился. Несмотря на многократный рост объёмов журналов, большинство эксплуатационных сценариев по-прежнему выглядело удивительно приземлённо. Разработчику требовалось понять, почему очередной релиз привёл к росту количества ошибок. Дежурному инженеру было необходимо выяснить причины увеличения времени ответа конкретного сервиса. SRE-команда пыталась локализовать источник деградации производительности после изменения конфигурации. Во всех этих случаях люди уже обладали определённым контекстом происходящего. Они знали имя приложения, пространство имён Kubernetes, временной диапазон возникновения проблемы и зачастую даже приблизительно понимали, какие компоненты необходимо исследовать.
Именно в этот момент индустрия начала задавать вопрос, который ещё несколько лет назад казался почти еретическим.
А действительно ли необходимо индексировать абсолютно всё?
Рождение другой философии
Если внимательно посмотреть на большинство инженерных инноваций, можно заметить интересную закономерность. Очень редко новые технологии появляются благодаря внезапным озарениям. Гораздо чаще они возникают как попытка отказаться от старых предположений, которые долгое время воспринимались как аксиомы.
Для Elasticsearch подобной аксиомой являлась идея полного индексирования. Если заранее неизвестно, какие данные понадобятся пользователю, логично подготовить к поиску всё, что только возможно. В эпоху относительно стабильных инфраструктур это действительно работало превосходно.
Однако Kubernetes сформировал иной класс задач.
Инженерам уже не требовалась полноценная поисковая система для исследования неизвестных территорий каждый раз, когда приложение начинало работать нестабильно. Гораздо чаще им нужен был быстрый доступ к журналам конкретного сервиса в определённый промежуток времени. Контекст расследования существовал ещё до момента выполнения поискового запроса.
Именно из этого наблюдения выросла идея Loki.
На первый взгляд она выглядела почти вызывающе простой. Вместо того чтобы индексировать содержимое каждого сообщения, система должна индексировать только ограниченный набор атрибутов, описывающих источник событий. Всё остальное можно хранить значительно дешевле, выполняя поиск лишь внутри заранее определённых потоков данных.
Если перевести эту философию на язык инженерной эксплуатации, получится следующее. Elasticsearch говорит:
"Я заранее подготовлю ответы практически на любые вопросы."
Loki отвечает:
"Сначала покажи мне, где именно ты ищешь проблему, и только после этого я начну разбирать содержимое журналов."
Подобный подход кажется спорным лишь до тех пор, пока не посмотреть на реальные поисковые запросы внутри Kubernetes-платформ.
Например, большинство дежурных инженеров выполняет что-то подобное:
{namespace="payments", app="gateway"}
или:
{cluster="production", pod=~"checkout-.*"}
|= "timeout"
В подобных запросах уже присутствует вся необходимая информация для существенного сокращения области поиска. Никто не пытается исследовать миллиарды строк журналов без малейшего понимания происходящего. Напротив, люди используют знания об архитектуре приложения для локализации проблемы.
Именно поэтому Loki оказался настолько органичным продолжением философии Kubernetes. Он не пытался конкурировать с Elasticsearch в области глубокой аналитики. Вместо этого платформа переосмыслила саму экономику хранения данных, сделав ставку на дешевизну хранения и минимизацию индексации. И, как это часто бывает с по-настоящему сильными инженерными идеями, её преимущество оказалось заметно не на демонстрационных стендах, а спустя месяцы эксплуатации, когда инфраструктура продолжала расти, а расходы на систему логирования переставали увеличиваться столь же стремительно, как объёмы самих журналов.
Почему простая идея оказалась настолько влиятельной
С высоты сегодняшнего дня может показаться, что концепция Loki была очевидной. Однако в момент появления она фактически предлагала отказаться от одного из главных принципов, лежавших в основе большинства платформ логирования. Инженерам пришлось признать, что далеко не все данные обладают одинаковой ценностью с точки зрения индексирования. Более того, необходимость заранее готовить абсолютно любую информацию к поиску оказалась следствием ограничений прошлого, а не универсальным законом построения систем наблюдаемости.
Это изменение мышления оказалось гораздо важнее конкретной реализации Loki. Фактически индустрия пришла к пониманию, что разные задачи требуют различных подходов к работе с телеметрией. Эксплуатационная диагностика и исследовательская аналитика перестали восприниматься как одно и то же. Одни инструменты начали оптимизироваться под быстрый доступ к огромным потокам журналов, другие сохранили ориентацию на сложные поисковые сценарии и построение гипотез.
Именно поэтому разговор о противостоянии Loki и Elasticsearch зачастую оказывается искусственным. Эти системы выросли из разных предположений о том, каким образом люди работают с данными. Понимание этой разницы является, пожалуй, самым важным шагом на пути к осознанному выбору платформы логирования. Потому что большинство дорогостоящих ошибок возникает не из-за недостатков самих технологий, а из-за попыток использовать их за пределами тех задач, для решения которых они когда-то создавались.
Внутренняя архитектура Loki: почему простота снаружи скрывает сложность внутри
Одной из причин популярности Loki стала удивительно удачная маркетинговая формула. Платформу часто описывали как "Prometheus для логов", и это сравнение оказалось чрезвычайно удачным. Инженеры, уже привыкшие к философии Prometheus, мгновенно понимали основной принцип: минимальное индексирование, горизонтальное масштабирование и опора на внешнее объектное хранилище. Всё выглядело настолько естественно, что создавалось впечатление, будто Loki представляет собой относительно простой инструмент, который можно установить за несколько минут и навсегда забыть о его существовании.
Как это обычно бывает в инфраструктуре, реальность оказалась несколько сложнее.
Действительно, запустить Loki в режиме Single Binary не составляет большого труда. Для небольших команд, лабораторных стендов или сред разработки достаточно одного экземпляра сервиса, способного принимать журналы, сохранять их и выполнять поисковые запросы. Именно с подобными демонстрационными конфигурациями большинство инженеров знакомится впервые. Они устанавливают Helm Chart, подключают Grafana и уже через несколько минут наблюдают журналы приложений внутри красивого веб-интерфейса. В этот момент легко возникает опасная иллюзия, будто вся платформа логирования представляет собой компактный сервис без серьёзных эксплуатационных требований.
Однако производственная эксплуатация быстро разрушает подобные представления.
Представим компанию, эксплуатирующую три Kubernetes-кластера: production, staging и development. В production работают несколько сотен узлов, ежедневно обслуживающих миллионы пользовательских запросов. Приложения активно масштабируются в зависимости от нагрузки, а общий объём журналов превышает два терабайта в сутки. Служба эксплуатации ожидает, что доступ к данным будет сохраняться даже при отказе отдельных компонентов, а инженеры смогут выполнять поисковые запросы независимо от интенсивности поступления новых событий. В подобных условиях архитектура Loki неизбежно начинает усложняться.
Вместо одного процесса появляются специализированные компоненты, каждый из которых отвечает за собственный участок жизненного цикла данных. Distributor принимает входящие журналы и распределяет нагрузку между экземплярами ingester. Ingester временно хранят данные в памяти, формируют блоки и подготавливают их к выгрузке в долговременное хранилище. Querier отвечает за выполнение поисковых запросов, извлекая информацию как из оперативной памяти активных ingester, так и из объектного хранилища. Query Frontend занимается оптимизацией пользовательских запросов, их кэшированием и балансировкой нагрузки. Compactor выполняет обслуживание уже сохранённых данных, уменьшая их фрагментацию и оптимизируя внутреннюю структуру хранения.
Упрощённо подобную архитектуру можно представить следующим образом:
Grafana
│
▼
Query Frontend
│
┌────────┴────────┐
▼ ▼
Querier Querier
│ │
└────────┬────────┘
▼
Object Storage
▲
┌────────┴────────┐
▼ ▼
Ingester Ingester
▲ ▲
└────────┬────────┘
▼
Distributor
▲
│
Alloy / Agents
Если внимательно посмотреть на эту схему, становится очевидно, что Loki давно перестал быть "лёгкой альтернативой ELK". Фактически перед нами полноценная распределённая система со всеми вытекающими последствиями. Появляются вопросы отказоустойчивости. Возникает необходимость планирования обновлений. Необходимо понимать механизмы репликации, тестировать сценарии отказа и контролировать производительность отдельных компонентов. Другими словами, исчезает ощущение магии, а на её месте появляется привычная инженерная работа.
Именно в этот момент многие команды испытывают лёгкое разочарование. Они ожидали получить чрезвычайно простой инструмент, а вместо этого обнаруживают ещё одну критически важную систему, требующую внимания. Однако это разочарование быстро сменяется пониманием. Масштаб современных платформ таков, что простых решений больше не существует. Если система способна обрабатывать терабайты телеметрии ежедневно, она неизбежно становится сложной. Вопрос заключается лишь в том, каким образом эта сложность распределена между различными компонентами.
Объектное хранилище как фундамент новой экономики логирования
Одним из наиболее радикальных отличий Loki от классического ELK является отношение к долговременному хранению данных. Исторически Elasticsearch был тесно связан с локальными дисковыми ресурсами собственных узлов. Да, внутри него существовали различные уровни хранения, механизмы управления жизненным циклом индексов и возможность перемещения данных между горячими и холодными слоями. Однако сама поисковая система оставалась неразрывно связанной с вычислительными узлами, обслуживающими эти данные.
Loki предложил иной взгляд на проблему.
Вместо того чтобы рассматривать хранилище как продолжение поискового движка, платформа начала относиться к нему как к независимому сервису. Именно поэтому объектные системы хранения стали одним из важнейших элементов архитектуры. Amazon S3, MinIO, Ceph Object Gateway, Google Cloud Storage и Azure Blob перестали восприниматься исключительно как инструменты резервного копирования. Они превратились в основной механизм долговременного хранения журналов.
Подобное решение обладает несколькими важными последствиями.
Во-первых, стоимость хранения становится значительно более предсказуемой. Объектные системы проектировались именно для работы с огромными объёмами данных и зачастую обходятся существенно дешевле высокопроизводительных локальных дисков. Во-вторых, вычислительные ресурсы и объёмы хранения начинают масштабироваться независимо друг от друга. Если организации требуется увеличить срок хранения журналов с тридцати до девяноста дней, это больше не означает автоматического расширения всех вычислительных компонентов Loki. В-третьих, объектное хранилище обеспечивает гибкость при построении отказоустойчивых архитектур, поскольку его эксплуатационные характеристики хорошо изучены и проверены практикой.
Конфигурация MinIO может выглядеть следующим образом:
loki:
storage:
type: s3
bucketNames:
chunks: loki-chunks
ruler: loki-ruler
admin: loki-admin
s3:
endpoint: minio.monitoring.svc.cluster.local:9000
accessKeyId: loki
secretAccessKey: supersecret
s3ForcePathStyle: true
insecure: true
На первый взгляд подобная конфигурация выглядит достаточно лаконично. Однако за несколькими строками YAML скрывается важное изменение мышления. Инженеры перестают рассматривать систему логирования как набор серверов с подключёнными дисками и начинают воспринимать её как конвейер обработки данных, использующий специализированные сервисы для решения различных задач. Один компонент отвечает за приём событий, другой - за их обработку, третий - за выполнение поисковых запросов, а объектное хранилище обеспечивает практически неограниченную долговременную сохранность информации.
Подобный подход удивительно хорошо совпал с общей философией Kubernetes. Современная инфраструктура всё чаще строится вокруг специализированных сервисов, взаимодействующих друг с другом через чётко определённые интерфейсы. Loki лишь перенёс эту идею в мир логирования.
Однако вместе с новыми возможностями пришли и новые риски. Потому что достаточно было совершить одну, на первый взгляд совершенно безобидную ошибку при выборе меток, чтобы даже самая элегантная архитектура начала стремительно терять эффективность. Именно так многие команды впервые сталкивались с явлением, которое позже стало практически легендой в мире Loki - cardinality explosion, или взрывом кардинальности.
Cardinality explosion: как одна неудачная метка способна уничтожить кластер наблюдаемости
Если спросить инженеров, имеющих реальный опыт эксплуатации Loki в производственной среде, какие проблемы доставляют больше всего неприятностей, очень многие неожиданно вспомнят вовсе не отказ объектного хранилища, не ошибки обновления и даже не проблемы производительности поисковых запросов. Вместо этого разговор почти неизбежно перейдёт к кардинальности меток и той цепочке событий, которую в сообществе давно называют cardinality explosion.
Любопытно, что сама проблема возникает вовсе не из-за ошибок разработчиков Loki. Напротив, она является прямым следствием той философии, которая сделала платформу успешной. Если Elasticsearch строит полнотекстовые индексы практически по всему содержимому событий, то Loki опирается на концепцию потоков. Поток представляет собой последовательность журналов, объединённых общим набором меток. Именно по этим меткам система определяет, где необходимо искать нужные данные.
На первый взгляд подобный подход выглядит предельно логичным. Если инженеры почти всегда знают контекст возникновения проблемы, почему бы не использовать этот контекст для организации хранения?
Например, поток журналов может определяться следующим набором атрибутов:
{
cluster="production",
namespace="payments",
app="gateway",
environment="prod"
}
Подобная комбинация прекрасно отражает структуру современной инфраструктуры. Она позволяет быстро локализовать интересующий сервис, практически не увеличивая нагрузку на систему индексирования. Более того, количество подобных комбинаций остаётся относительно предсказуемым. Даже если в организации работают сотни приложений, их число растёт постепенно и редко изменяется скачкообразно.
Проблемы начинаются в тот момент, когда инженеры пытаются сделать систему "ещё удобнее".
Представим вполне жизненную ситуацию. Разработчики активно используют идентификаторы запросов, позволяющие проследить путь конкретной операции через цепочку микросервисов. В журналах присутствует поле request_id, и кто-то вполне справедливо замечает, что возможность мгновенно находить все события, связанные с определённым запросом, была бы чрезвычайно полезной.
Идея выглядит настолько разумной, что возражать против неё психологически трудно.
Конфигурация может выглядеть следующим образом:
pipeline_stages:
- json:
expressions:
request_id: request_id
- labels:
request_id:
Если рассматривать её изолированно, ничего тревожного не происходит. Однако стоит взглянуть на ситуацию глазами самой платформы.
Предположим, что платёжный шлюз обрабатывает пять тысяч запросов в секунду. Каждый запрос обладает уникальным идентификатором. Каждый идентификатор превращается в новую метку. Каждая новая комбинация меток создаёт отдельный поток данных.
Через минуту появляются сотни тысяч потоков.
Через час их количество начинает измеряться миллионами.
Потребление памяти растёт значительно быстрее ожидаемого.
Увеличивается нагрузка на процессоры.
Усложняется внутренняя структура индексов.
Замедляются поисковые запросы.
А инженеры с удивлением обнаруживают, что система, ещё недавно прекрасно справлявшаяся со своей задачей, внезапно начинает деградировать.
Самое неприятное заключается в том, что подобные ошибки почти всегда совершаются из лучших побуждений. Никто не пытается сознательно навредить платформе наблюдаемости. Наоборот, люди стремятся сделать поиск более удобным и информативным. Именно поэтому взрыв кардинальности считается одной из самых коварных эксплуатационных проблем Loki.
Почему высокая кардинальность так опасна
Чтобы понять масштаб проблемы, полезно вспомнить, как вообще устроена экономика Loki.
Платформа выигрывает у традиционных поисковых систем именно потому, что количество индексируемых сущностей остаётся относительно небольшим. Если условный Elasticsearch готов индексировать практически каждое поле, Loki ограничивается описанием потоков. Благодаря этому удаётся радикально сократить требования к дисковой подсистеме и вычислительным ресурсам.
Однако подобная экономия работает лишь до тех пор, пока сами потоки остаются разумными по количеству.
Рассмотрим два примера.
В первом случае используются следующие метки:
{
cluster="prod",
namespace="checkout",
app="api",
region="eu-west"
}
Предположим, что организация использует пять кластеров, двадцать пространств имён, сто приложений и три региона размещения. Даже при грубой оценке количество возможных комбинаций остаётся вполне контролируемым.
Во втором случае к ним добавляются:
{
request_id="4fd61f4d-7b35-4c29-a17d"
}
или:
{
user_id="123456789"
}
В этот момент количество потоков начинает зависеть уже не от архитектуры платформы, а от активности пользователей. Система теряет предсказуемость. Любой всплеск нагрузки автоматически приводит к экспоненциальному росту количества индексируемых комбинаций.
Именно поэтому опытные команды относятся к проектированию меток практически так же серьёзно, как архитекторы баз данных относятся к проектированию индексов.
Набор labels перестаёт быть технической деталью реализации.
Он превращается в архитектурное решение.
Какие метки действительно стоит использовать
За годы эксплуатации Loki внутри сообщества сформировались вполне устойчивые рекомендации. Разумеется, универсальных правил не существует, однако определённые закономерности встречаются практически повсеместно.
Хорошими кандидатами для использования в качестве меток считаются атрибуты, обладающие низкой изменчивостью и отражающие структуру самой платформы.
Например:
-
имя кластера;
-
пространство имён Kubernetes;
-
название приложения;
-
окружение;
-
регион размещения;
-
принадлежность к команде;
-
тип рабочей нагрузки.
Именно эти параметры позволяют быстро локализовать область поиска, не создавая чрезмерной нагрузки на систему.
Напротив, крайне осторожно следует относиться к данным, отражающим поведение отдельных пользователей или конкретных операций.
Сюда относятся:
-
идентификаторы запросов;
-
идентификаторы сессий;
-
UUID транзакций;
-
адреса электронной почты;
-
пользовательские идентификаторы;
-
trace_id;
-
номера заказов.
Важно понимать, что подобные данные вовсе не являются бесполезными. Более того, зачастую именно они оказываются наиболее ценными при расследовании инцидентов. Однако их место находится внутри содержимого журналов, а не внутри механизма индексирования.
Например, структурированный JSON-журнал может выглядеть следующим образом:
{
"timestamp": "2026-06-17T12:01:34Z",
"level": "ERROR",
"request_id": "4fd61f4d-7b35-4c29-a17d",
"user_id": 482913,
"message": "payment processing failed",
"service": "checkout"
}
Подобный подход позволяет сохранить ценную диагностическую информацию, не превращая её в источник неконтролируемого роста кардинальности.
Архитектурная дисциплина как часть культуры эксплуатации
Пожалуй, самый интересный вывод из всей истории с cardinality explosion заключается в том, что Loki требует от команд определённой зрелости инженерного мышления.
Очень легко воспринимать систему логирования как техническую деталь, существующую где-то на периферии внимания. Кажется, что её задача сводится к простому хранению текстовых сообщений, а любые неудобства можно компенсировать дополнительными вычислительными ресурсами.
Практика показывает обратное.
Платформа наблюдаемости начинает отражать архитектурную культуру организации. Команды, привыкшие проектировать API, тщательно выбирать индексы баз данных и учитывать стоимость вычислений, обычно достаточно быстро осваивают философию Loki. Они воспринимают проектирование меток как ещё одну разновидность архитектурной ответственности.
Там же, где любые данные автоматически объявляются критически важными, а последствия решений оцениваются лишь после появления первых проблем, система логирования очень быстро превращается в источник постоянной боли.
Именно поэтому разговор о кардинальности оказывается значительно глубже обсуждения конкретных настроек. Фактически он касается того, насколько осознанно организация относится к управлению собственной сложностью. Потому что современные платформы наблюдаемости уже давно перестали быть набором утилит для просмотра логов. Они превратились в самостоятельные распределённые системы, успех эксплуатации которых определяется не только качеством программного кода, но и зрелостью инженерных решений, принимаемых людьми, которые ежедневно работают с этими системами.
Promtail, Alloy и взросление экосистемы наблюдаемости
Если история Loki демонстрирует, каким образом изменилась экономика хранения журналов, то эволюция инструментов доставки телеметрии прекрасно показывает, насколько сильно изменилась сама философия наблюдаемости. На ранних этапах развития платформы всё выглядело относительно просто. Существовал Promtail - небольшой агент, который устанавливался на каждом узле Kubernetes, считывал журналы контейнеров и пересылал их в Loki. Он выполнял вполне конкретную задачу и, по большому счёту, не претендовал на роль чего-то большего.
Именно поэтому многие инженеры воспринимали его как нечто само собой разумеющееся. В Kubernetes-кластере уже существовал Prometheus, отвечающий за сбор метрик. Рядом работал Promtail, занимающийся журналами. Если организация использовала трассировки, появлялись дополнительные агенты. Всё это выглядело вполне естественно. Каждый инструмент отвечал за строго определённый тип данных и практически не пересекался с остальными.
Проблема заключалась лишь в том, что сама инфраструктура продолжала усложняться.
Современные платформенные команды работают уже не только с логами и метриками. Они собирают трассировки распределённых запросов, профили производительности приложений, события безопасности, информацию о конфигурации сервисов и огромное количество дополнительных атрибутов. Каждый новый тип телеметрии приносил с собой ещё один специализированный агент. В какой-то момент Kubernetes-кластеры начали напоминать небольшие зоопарки, населённые десятками компонентов наблюдаемости, каждый из которых обладал собственным жизненным циклом, настройками, механизмами обновления и требованиями к ресурсам.
Любой инженер, сопровождавший подобную систему, хорошо понимает, насколько быстро подобная архитектура начинает создавать проблемы. Обновление версии одного агента может неожиданно изменить формат передаваемых данных. Неправильно настроенные лимиты ресурсов способны привести к потере части телеметрии. Команды вынуждены поддерживать экспертизу сразу по нескольким инструментам, которые решают очень похожие задачи, но делают это совершенно разными способами.
Именно на этом фоне Grafana Labs начала постепенно переосмысливать подход к сбору данных.
Почему эпоха специализированных агентов подходит к концу
Если внимательно посмотреть на развитие индустрии, можно заметить любопытную тенденцию. Многие технологии начинают свой путь как специализированные инструменты, решающие одну конкретную задачу чрезвычайно эффективно. Однако по мере роста зрелости экосистемы возникает стремление к консолидации.
Когда-то существовали отдельные системы управления конфигурацией для различных типов инфраструктуры. Позже появились платформы, стремящиеся объединить эти возможности. Аналогичный процесс происходил и в мире наблюдаемости.
Promtail прекрасно справлялся с доставкой журналов в Loki. Но он практически ничего не знал о трассировках. Он не был предназначен для маршрутизации метрик. Он не учитывал стремительное развитие OpenTelemetry, постепенно превращавшегося в отраслевой стандарт обмена телеметрией.
Именно поэтому появился Alloy.
По своей сути Alloy представляет собой попытку объединить сбор различных типов данных внутри единого конвейера обработки. Вместо множества специализированных агентов организация получает платформу, способную принимать, преобразовывать и маршрутизировать практически любую телеметрию.
С точки зрения эксплуатации подобный подход выглядит чрезвычайно привлекательно. Количество компонентов уменьшается. Снижается разнообразие используемых инструментов. Появляется возможность описывать правила обработки данных внутри единой конфигурационной модели.
Однако вместе с преимуществами неизбежно возникает новая сложность.
Если раньше отказ Promtail влиял исключительно на доставку журналов, то теперь единый агент может оказаться ответственным сразу за несколько критически важных потоков данных. Ошибка конфигурации начинает иметь значительно более серьёзные последствия. Инженеры вынуждены понимать уже не только особенности доставки логов, но и принципы работы всей системы телеметрии.
Другими словами, инфраструктура вновь проходит через знакомый цикл: множество простых компонентов заменяются меньшим количеством более сложных.
Как выглядит современный конвейер обработки телеметрии
В демонстрационных материалах доставка журналов обычно выглядит предельно прямолинейно. Агент читает файлы из каталога /var/log/containers, извлекает необходимые метаданные и отправляет данные в Loki. Подобная схема действительно существует, однако в производственных средах она давно перестала быть исчерпывающим описанием происходящего.
Рассмотрим достаточно типичный сценарий.
Крупная организация использует несколько Kubernetes-кластеров. Разработчики активно внедряют структурированные JSON-журналы. В системе присутствуют служебные сообщения Kubernetes, журналы приложений, события сервисной сетки и различные фоновые задачи. Часть данных необходимо сохранять полностью. Некоторые сообщения желательно отфильтровывать ещё до отправки. Дополнительно требуется добавлять информацию о кластере и окружении.
В подобных условиях конвейер обработки начинает выглядеть значительно интереснее.
Сначала происходит обнаружение источников данных:
discovery.kubernetes "pods" {
role = "pod"
}
Далее Alloy начинает считывать журналы обнаруженных контейнеров:
loki.source.kubernetes "pods" {
targets = discovery.kubernetes.pods.targets
forward_to = [loki.process.default.receiver]
}
После этого вступает в действие этап предварительной обработки:
loki.process "default" {
stage.static_labels {
values = {
cluster = "production"
environment = "prod"
}
}
stage.drop {
expression = "GET /healthz"
}
forward_to = [
loki.write.default.receiver
]
}
Наконец, данные передаются в целевую систему хранения:
loki.write "default" {
endpoint {
url = "http://loki-gateway/loki/api/v1/push"
}
}
Если внимательно посмотреть на подобную конфигурацию, становится заметно, насколько сильно изменилась сама природа наблюдаемости. Речь уже не идёт о банальном копировании строк из одного места в другое. Современный агент выполняет обнаружение сервисов, обогащение событий, фильтрацию, преобразование и маршрутизацию данных. Фактически он превращается в полноценный телеметрический конвейер.
И именно здесь многие команды впервые начинают задумываться о качестве самих журналов.
Почему плохие логи стоят дорого
Существует старая инженерная привычка считать, что дополнительная информация никогда не бывает лишней. Если приложение способно записать в журнал ещё одно сообщение, почему бы этого не сделать? Если можно добавить несколько дополнительных полей, разве это не облегчит последующее расследование?
Подобная логика кажется абсолютно разумной до тех пор, пока организация не сталкивается с реальными объёмами данных.
Представим сервис, обрабатывающий двадцать тысяч запросов в секунду. Разработчики решают фиксировать в журналах каждое обращение к внутренним API, каждую проверку состояния и каждую успешную операцию. Через некоторое время выясняется, что более девяноста процентов всех сообщений никогда не используются ни для расследований, ни для диагностики. Они просто перемещаются через всю платформу наблюдаемости, потребляют вычислительные ресурсы и увеличивают стоимость хранения.
Именно поэтому зрелые команды начинают относиться к журналам так же, как относятся к программному коду.
Они задают неудобные вопросы.
Нужна ли эта запись вообще?
Кто будет использовать данное сообщение?
Поможет ли оно расследовать инцидент?
Как долго необходимо хранить подобную информацию?
Нельзя ли заменить поток однотипных записей агрегированной метрикой?
Подобный подход меняет отношение к логированию. Оно перестаёт быть бесплатным побочным эффектом работы приложения и превращается в осознанное архитектурное решение.
В определённом смысле это и есть главный признак взросления наблюдаемости. Организации начинают понимать, что стоимость платформы определяется не только ценой серверов и лицензий. Она напрямую зависит от качества инженерных решений, принимаемых задолго до появления первой строки в журнале приложения.
Production-эксплуатация Loki: когда платформа наблюдаемости сама становится критическим сервисом
Практически каждая команда, впервые внедряющая Loki, проходит через одинаковый этап восприятия. На фоне тяжеловесных Elasticsearch-кластеров новая система кажется удивительно лёгкой и даже в некотором смысле беззаботной. Действительно, первые впечатления обычно оказываются весьма позитивными. Helm Chart разворачивается за считанные минуты, Grafana подключается практически автоматически, а первые поисковые запросы выполняются достаточно быстро даже на скромных ресурсах. После нескольких лет борьбы с heap-памятью Elasticsearch и бесконечными обсуждениями количества shard подобная простота воспринимается почти как подарок судьбы.
Однако производственная эксплуатация обладает неприятной особенностью разрушать любые иллюзии.
Рано или поздно платформа наблюдаемости перестаёт быть вспомогательным инструментом и превращается в полноценный критически важный сервис. Именно через неё инженеры расследуют аварии. Именно она позволяет понять причины деградации после неудачного релиза. Именно к ней обращаются специалисты по безопасности во время инцидентов. И именно в этот момент становится очевидно, что сама система логирования должна соответствовать тем же стандартам надёжности, которые предъявляются к основным бизнес-сервисам.
Это изменение восприятия оказывается чрезвычайно важным.
Очень многие организации продолжают относиться к наблюдаемости как к чему-то второстепенному. Пока всё работает хорошо, журналы остаются где-то на периферии внимания. Но стоит произойти серьёзному сбою, как выясняется, что потеря логов означает потерю возможности понять происходящее. А отсутствие понимания во время инцидента зачастую оказывается опаснее самого инцидента.
Именно поэтому зрелые команды начинают применять к Loki те же инженерные практики, которые используют для сопровождения собственных платформ.
Отказоустойчивость перестаёт быть опцией
Одна из наиболее распространённых ошибок заключается в попытке строить производственную систему логирования по принципу "запустим один экземпляр, а потом посмотрим". Подобный подход может быть оправдан в средах разработки или небольших лабораторных стендах, однако в реальных производственных системах он практически гарантированно приводит к проблемам.
Представим интернет-магазин, обрабатывающий несколько миллионов пользовательских сессий ежедневно. В какой-то момент после очередного релиза резко возрастает количество ошибок оформления заказов. Разработчики открывают Grafana, пытаясь выяснить причины происходящего, и обнаруживают, что Loki недоступен из-за отказа единственного экземпляра ingester.
С технической точки зрения это означает потерю самого важного инструмента диагностики именно тогда, когда он нужен больше всего.
Поэтому типичная production-конфигурация Loki предусматривает репликацию практически на всех уровнях архитектуры.
Например:
loki:
commonConfig:
replication_factor: 3
distributor:
replicas: 4
ingester:
replicas: 6
querier:
replicas: 4
queryFrontend:
replicas: 2
indexGateway:
replicas: 2
compactor:
replicas: 1
За этой относительно компактной конфигурацией скрывается вполне конкретная инженерная логика. Несколько distributor позволяют равномерно распределять входящую нагрузку и переживать отказ отдельных экземпляров. Репликация ingester обеспечивает сохранность недавно поступивших данных до их выгрузки в объектное хранилище. Независимое масштабирование querier позволяет обслуживать большое количество поисковых запросов без влияния на процесс записи журналов.
Важно понимать, что подобная архитектура появляется не потому, что Loki является недостаточно надёжной системой. Напротив, именно возможность независимого масштабирования компонентов и делает её пригодной для крупных инфраструктур. Однако за эту гибкость приходится платить усложнением эксплуатации.
Инженерам необходимо понимать последствия отказа каждого компонента, регулярно проверять сценарии восстановления и заранее готовиться к ситуациям, которые неизбежно возникнут в любой достаточно крупной системе.
Сколько ресурсов действительно требует Loki
Вопрос расчёта ресурсов традиционно вызывает наибольшее количество споров. Причина заключается в том, что официальные рекомендации почти всегда оказываются слишком абстрактными. Они не учитывают специфику конкретных нагрузок, особенности журналов и поведение пользователей.
Например, две организации могут генерировать одинаковый объём данных - условные два терабайта в сутки. При этом одна из них будет успешно работать на относительно скромной инфраструктуре, а другая столкнётся с постоянными проблемами производительности.
Разница заключается в характере использования платформы.
Если инженеры преимущественно выполняют короткие поисковые запросы в пределах нескольких часов, нагрузка на querier остаётся вполне умеренной. Если же аналитики регулярно исследуют данные за несколько месяцев, выполняя сложные фильтрации, требования к вычислительным ресурсам возрастают многократно.
В качестве отправной точки для платформы, принимающей около двух терабайт журналов в сутки, можно рассматривать следующую конфигурацию:
| Компонент | Количество экземпляров | CPU | Память |
|---|---|---|---|
| Distributor | 4 | 2 vCPU | 4 ГБ |
| Ingester | 6 | 4 vCPU | 16 ГБ |
| Querier | 4 | 4 vCPU | 8 ГБ |
| Query Frontend | 2 | 2 vCPU | 2 ГБ |
| Compactor | 1 | 2 vCPU | 4 ГБ |
| Index Gateway | 2 | 2 vCPU | 4 ГБ |
Однако подобные цифры следует воспринимать исключительно как ориентир.
Настоящая инженерная практика начинается там, где появляются нагрузочные тесты.
Команды, серьёзно относящиеся к наблюдаемости, проверяют платформу ещё до ввода в эксплуатацию. Они моделируют пиковые нагрузки, имитируют рост количества поисковых запросов, проверяют поведение системы при отказе отдельных узлов и оценивают влияние изменения сроков хранения данных.
Именно такой подход позволяет избежать неприятных сюрпризов спустя несколько месяцев после запуска.
Наблюдаемость должна наблюдать саму себя
Существует определённая ирония в том, что система наблюдаемости очень быстро становится ещё одним объектом наблюдения.
Многие команды начинают осознавать это лишь после первого серьёзного инцидента. Они внимательно отслеживают метрики приложений, контролируют доступность Kubernetes API и измеряют задержки пользовательских запросов, но при этом практически ничего не знают о состоянии собственной платформы логирования.
До тех пор, пока она работает.
Проблема становится очевидной в момент деградации.
Поисковые запросы внезапно начинают выполняться по тридцать секунд вместо привычных трёх. Задержка доставки журналов увеличивается до нескольких минут. Пользователи жалуются на отсутствие свежих данных. А инженеры обнаруживают, что у них нет даже базовых метрик, позволяющих понять причины происходящего.
Именно поэтому зрелые платформенные команды формируют для Loki собственные показатели качества обслуживания.
Например, вполне разумными целями могут быть следующие значения:
-
доставка новых журналов менее чем за тридцать секунд;
-
успешная обработка не менее 99,9% входящих событий;
-
выполнение типовых поисковых запросов менее чем за пять секунд;
-
отсутствие потери данных при отказе отдельного узла;
-
завершение восстановления после сбоя в заранее определённый промежуток времени.
Подобные показатели превращают абстрактное понятие "система работает нормально" в измеримые характеристики, позволяющие принимать инженерные решения на основании фактов, а не субъективных ощущений.
Фактически Loki начинает жить по тем же законам, что и любой другой производственный сервис.
Для него появляются собственные SLO.
Определяются допустимые риски.
Планируются окна обслуживания.
Проводятся проверки резервных сценариев.
И в этом заключается одно из самых интересных изменений, произошедших в индустрии за последние годы. Когда-то журналы представляли собой обычные текстовые файлы, лежащие в каталоге /var/log. Их анализ зачастую ограничивался командой grep, а вопросы отказоустойчивости даже не поднимались всерьёз.
Сегодня платформа логирования превратилась в самостоятельную распределённую систему, от состояния которой напрямую зависит способность организации понимать происходящее внутри собственной инфраструктуры. И чем сложнее становятся современные платформы, тем более очевидным оказывается простой вывод: наблюдаемость перестала быть дополнительной возможностью. Она стала таким же базовым элементом инженерной культуры, как резервное копирование, автоматизация развёртываний и тестирование изменений.
Где Elasticsearch по-прежнему остаётся незаменимым инструментом
После нескольких лет стремительного роста популярности Loki вокруг него начала формироваться вполне предсказуемая волна технологического энтузиазма. В профессиональных сообществах стали появляться публикации о том, что Elasticsearch окончательно проиграл борьбу за рынок логирования, а его место безоговорочно заняли более лёгкие и экономичные решения. Подобные утверждения звучат достаточно убедительно, особенно если их произносят инженеры, только что сократившие расходы на хранение журналов в несколько раз после перехода на новую платформу. Проблема заключается лишь в том, что подобные выводы обычно отражают исключительно опыт эксплуатации конкретного типа инфраструктуры.
Реальная картина оказывается значительно сложнее.
Loki действительно блестяще справляется с задачами, ради которых он создавался. Он позволяет хранить огромные объёмы журналов контейнеризированных приложений без взрывного роста стоимости инфраструктуры. Он прекрасно вписывается в экосистему Kubernetes. Он помогает инженерам быстро локализовывать проблемы в рамках заранее известного контекста. Но существуют целые классы задач, где его сильные стороны неожиданно превращаются в ограничения.
Чтобы понять природу этих ограничений, необходимо вернуться к вопросу о том, каким образом люди вообще работают с данными.
Когда дежурный инженер открывает Grafana после ночного оповещения, он почти всегда обладает определённым набором исходной информации. Ему известно, какой сервис ведёт себя нестабильно. Он понимает, в каком кластере возникла проблема. Он знает примерное время появления первых симптомов. Даже если истинная причина инцидента пока остаётся неизвестной, область поиска уже существенно ограничена.
Именно на подобные сценарии ориентирован Loki.
Однако существует другой тип работы, гораздо менее предсказуемый.
Представим специалиста по информационной безопасности, расследующего подозрительную активность внутри корпоративной сети. У него отсутствует понимание того, какие именно признаки окажутся значимыми. Возможно, придётся анализировать поведение пользователей, версии клиентских приложений, последовательность аутентификаций, источники сетевых подключений и действия внутри различных подсистем. Каждый новый факт способен полностью изменить направление расследования.
Подобная деятельность напоминает исследование незнакомой территории без заранее подготовленного маршрута.
Именно в этот момент Elasticsearch вновь оказывается в своей естественной среде.
Аналитика как исследование неизвестного
Одной из наиболее сильных сторон Elasticsearch всегда была возможность исследовать данные, не обладая полным пониманием того, что именно необходимо обнаружить. Это различие кажется незначительным лишь до тех пор, пока не приходится работать с действительно сложными расследованиями.
Предположим, что банк пытается выявить мошеннические операции. Аналитики замечают незначительный рост количества подозрительных транзакций, однако не могут определить, какие именно характеристики объединяют эти события. Возможно, злоумышленники используют определённые устройства. Возможно, они действуют преимущественно в конкретные часы. Не исключено, что ключевым фактором является версия мобильного приложения или последовательность предыдущих действий пользователей.
В подобной ситуации поиск превращается в процесс последовательного формирования и проверки гипотез.
Например, запрос может выглядеть следующим образом:
GET transactions/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"amount": {
"gte": 50000
}
}
}
],
"filter": [
{
"term": {
"country": "RU"
}
},
{
"range": {
"@timestamp": {
"gte": "now-7d"
}
}
}
]
}
},
"aggs": {
"devices": {
"terms": {
"field": "device_id.keyword",
"size": 20
}
},
"application_versions": {
"terms": {
"field": "app_version.keyword",
"size": 20
}
}
}
}
Подобный запрос одновременно выполняет фильтрацию событий, анализирует распределение устройств и выявляет наиболее распространённые версии приложений. Более того, аналитик может продолжать развивать расследование, постоянно изменяя критерии поиска и исследуя всё новые взаимосвязи.
Именно в таких сценариях становится очевидно, что Elasticsearch представляет собой не просто систему хранения журналов.
Фактически это полноценная аналитическая платформа.
Попытка заменить её Loki будет примерно столь же разумной, как попытка использовать отвёртку вместо набора хирургических инструментов только потому, что отвёртка дешевле и проще в обслуживании.
Почему крупные компании всё чаще используют обе платформы
Если посмотреть на архитектуры действительно крупных организаций, можно заметить интересную закономерность. Несмотря на бесконечные дискуссии о превосходстве тех или иных технологий, очень немногие компании делают выбор исключительно в пользу одного инструмента.
Наоборот, всё чаще встречается модель сосуществования нескольких платформ наблюдаемости, каждая из которых обслуживает собственный класс задач.
Причина подобного подхода предельно прагматична.
Разработчикам и SRE-командам необходим быстрый доступ к эксплуатационным журналам приложений. Они расследуют последствия релизов, анализируют ошибки сервисов и ищут причины деградации производительности. Для подобных сценариев Loki оказывается чрезвычайно удобным решением.
Специалисты по безопасности работают совершенно иначе. Их интересуют аномалии, сложные корреляции и исследовательские расследования. Они редко знают заранее, какие именно данные окажутся критически важными. Elasticsearch предоставляет им значительно более богатый инструментарий.
Бизнес-подразделения зачастую используют журналы как источник информации о поведении пользователей и качестве предоставляемых услуг. Для них важны агрегированные отчёты, анализ тенденций и построение аналитических моделей.
В результате архитектура начинает выглядеть примерно следующим образом:
Kubernetes
│
▼
Alloy
│
┌───────────┴───────────┐
▼ ▼
Loki Elasticsearch
│ │
▼ ▼
SRE / DevOps Security Teams
Developers Fraud Analysts
BI Platforms
Подобная схема может показаться чрезмерно сложной лишь на первый взгляд. На практике она отражает вполне естественное разделение потребностей различных групп пользователей. Вместо попыток заставить одну систему одинаково хорошо решать все возможные задачи организации начинают использовать специализированные инструменты там, где они действительно приносят наибольшую пользу.
Что особенно важно, подобная архитектура вовсе не является проявлением инженерной нерешительности.
Наоборот.
Она свидетельствует о зрелости команды, готовой признать, что универсальных решений не существует. Каждая технология обладает собственными сильными сторонами и собственными ограничениями. Игнорирование этих ограничений редко приводит к успеху, каким бы привлекательным ни выглядел выбранный инструмент.
Именно поэтому разговоры о "смерти Elasticsearch" оказываются столь же поверхностными, как и утверждения о том, что Loki представляет собой исключительно модную игрушку из мира Kubernetes. Эти платформы появились в ответ на разные вызовы и отражают различные способы взаимодействия людей с данными. Понимание этой разницы позволяет выбирать технологии осознанно, исходя не из популярности очередного тренда, а из реальных потребностей инфраструктуры и команд, которым предстоит сопровождать её долгие годы.
Миграция с ELK на Loki: почему успешные проекты начинаются не с технологий
Если посмотреть на публикации производителей и многочисленные выступления на конференциях, может сложиться впечатление, будто миграция с одной платформы логирования на другую представляет собой преимущественно техническую задачу. Необходимо установить новый Helm Chart, перенастроить агентов доставки, переключить источники данных в Grafana и убедиться, что поисковые запросы продолжают работать. После этого остаётся лишь выключить старую систему и наслаждаться снижением расходов.
Практика показывает, что подобный сценарий встречается исключительно редко.
На самом деле большинство сложностей миграции никак не связано с Loki, Elasticsearch или любыми другими технологиями. Главная проблема заключается в том, что за годы эксплуатации вокруг системы логирования формируется целая экосистема процессов, привычек и ожиданий. Разработчики привыкают к определённым способам поиска ошибок. Аналитики безопасности строят расследования на основе конкретных возможностей поискового движка. Руководители получают отчёты в привычном формате. Автоматизированные сценарии используют существующие API. И всё это постепенно превращается в часть организационной культуры.
Именно поэтому успешные проекты миграции начинаются вовсе не с установки нового программного обеспечения.
Они начинаются с инвентаризации сценариев использования.
Кто именно работает с журналами?
Какие задачи решаются ежедневно?
Какие возможности действительно используются?
Какие функции считаются критически важными, а какие существуют исключительно потому, что "когда-нибудь могут пригодиться"?
Очень часто результаты подобного анализа оказываются неожиданными.
Выясняется, что подавляющее большинство разработчиков никогда не использовало сложные агрегации Elasticsearch. SRE-команды практически всегда ограничивались поиском по заранее известным сервисам и временным диапазонам. При этом специалисты по безопасности активно использовали аналитические возможности платформы и не были готовы отказаться от них без серьёзных последствий.
Именно в этот момент становится очевидно, что вопрос миграции следует формулировать иначе.
Речь идёт не о замене одной технологии другой.
Речь идёт о перераспределении ответственности между различными инструментами.
Почему стратегия "большого взрыва" почти всегда заканчивается плохо
Существует соблазнительная идея выполнить миграцию быстро и решительно. Определяется дата переключения. Настраиваются новые агенты доставки. В заранее согласованный момент старая платформа отключается, а все пользователи начинают работать исключительно с новой системой.
Подобный подход обладает очевидным преимуществом.
Он выглядит очень красиво на архитектурных диаграммах.
К сожалению, именно поэтому он так опасен.
Любая достаточно крупная организация представляет собой сложную экосистему. Даже если команда уверена, что полностью понимает все сценарии использования журналов, почти неизбежно обнаруживаются неожиданные зависимости. Кто-то использует старые API для интеграции с внутренними инструментами. Отдел информационной безопасности полагается на определённые поисковые возможности. Разработчики создали собственные панели мониторинга, существование которых никем не документировано.
Когда подобные вещи выясняются уже после отключения старой системы, проект миграции начинает стремительно превращаться в борьбу с последствиями.
Именно поэтому зрелые организации предпочитают эволюционный подход.
В течение определённого периода времени обе платформы существуют параллельно.
Loki постепенно начинает обслуживать эксплуатационные сценарии.
Elasticsearch продолжает использоваться для аналитических задач.
Команды получают возможность адаптировать процессы без давления со стороны критических сроков.
Более того, подобный подход позволяет принимать решения на основании фактических данных, а не предположений.
Например, спустя несколько месяцев эксплуатации может оказаться, что определённые аналитические функции Elasticsearch используются настолько редко, что их поддержка перестаёт быть экономически оправданной. Либо, наоборот, выясняется, что они критически важны для отдельных подразделений и должны сохраниться независимо от стоимости сопровождения.
Как выглядит практическая миграция
Рассмотрим достаточно типичный сценарий.
Организация использует EFK-стек для обслуживания нескольких Kubernetes-кластеров. Суточный объём журналов составляет около полутора терабайт. Основные жалобы связаны со стоимостью хранения и постоянной необходимостью расширять Elasticsearch-кластер.
Первым этапом становится внедрение Loki без изменения существующих процессов.
Агенты начинают отправлять журналы одновременно в обе системы.
Например, подобная схема маршрутизации может быть реализована следующим образом:
loki.write "primary" {
endpoint {
url = "http://loki-gateway/loki/api/v1/push"
}
}
loki.write "secondary" {
endpoint {
url = "http://elasticsearch-proxy:8080"
}
}
loki.process "default" {
forward_to = [
loki.write.primary.receiver,
loki.write.secondary.receiver,
]
}
Подобный подход увеличивает нагрузку на систему доставки телеметрии, однако предоставляет чрезвычайно ценную возможность.
Команды продолжают работать привычным образом, одновременно знакомясь с новой платформой.
Разработчики начинают использовать Grafana Explore.
SRE-команды адаптируют существующие процедуры реагирования.
Специалисты по безопасности оценивают влияние изменений на собственные расследования.
Именно в этот период обычно становится заметно, какие возможности действительно востребованы.
Через некоторое время начинают происходить более интересные изменения.
Часть панелей мониторинга переносится в Grafana.
Типовые эксплуатационные сценарии полностью переходят на Loki.
Разработчики постепенно перестают открывать Kibana для повседневных задач.
Elasticsearch начинает использоваться всё реже, но одновременно всё отчётливее проявляется его ценность в специализированных аналитических сценариях.
Таким образом организация приходит к архитектуре не через революцию, а через накопление практического опыта.
Настоящая стоимость платформы наблюдаемости
Когда обсуждаются системы логирования, разговор почти неизбежно сводится к вычислительным ресурсам.
Сколько потребуется процессоров?
Какой объём оперативной памяти необходим?
Во сколько обойдётся хранение данных?
Безусловно, все эти вопросы чрезвычайно важны.
Однако существует ещё одна статья расходов, которую инженеры зачастую начинают замечать лишь спустя годы эксплуатации.
Стоимость человеческого времени.
Сколько часов тратит дежурная смена на расследование типового инцидента?
Как быстро разработчики локализуют последствия неудачного релиза?
Насколько оперативно специалисты по безопасности способны обнаружить признаки компрометации?
Как много усилий требуется для сопровождения самой платформы наблюдаемости?
Представим две гипотетические организации.
Первая экономит значительные средства на инфраструктуре, однако каждый серьёзный инцидент сопровождается многочасовыми поисками необходимой информации. Вторая использует более дорогую архитектуру, но позволяет инженерам получать ответы за считанные минуты.
Формально первая платформа действительно дешевле.
Но если учитывать стоимость простоев, переработок и снижение скорости принятия решений, картина может оказаться диаметрально противоположной.
Именно поэтому разговор о выборе между Loki и Elasticsearch никогда не должен сводиться исключительно к сравнению технических характеристик.
Платформа наблюдаемости представляет собой инструмент коллективного мышления организации. Она определяет, насколько быстро люди способны понять происходящее внутри сложной распределённой системы. А скорость понимания во время кризисных ситуаций зачастую оказывается значительно важнее экономии нескольких виртуальных машин.
Возможно, именно в этом заключается главный урок всей истории развития современных систем логирования. Мы больше не выбираем программное обеспечение исключительно по количеству поддерживаемых функций или популярности среди коллег. Мы выбираем способ взаимодействия с неопределённостью, неизбежно возникающей внутри любой сложной инфраструктуры. И от качества этого выбора зависит не только размер ежемесячных счетов за облачные ресурсы, но и способность команды сохранять эффективность в те моменты, когда всё вокруг начинает работать совсем не так, как предполагалось на архитектурных диаграммах.
Что выбрать сегодня: универсального ответа не существует
К этому моменту у читателя вполне закономерно может возникнуть чувство лёгкого раздражения. После нескольких десятков страниц сравнений, архитектурных схем и эксплуатационных историй очень хочется получить простой и однозначный вывод. Какую систему всё-таки выбирать? Что лучше? Какая технология позволит избежать ошибок и не потребует пересмотра решений через два года?
Проблема заключается в том, что именно стремление получить универсальный ответ чаще всего становится причиной дорогостоящих ошибок.
Инфраструктурная индустрия вообще удивительно любит простые рецепты. Периодически появляется технология, которую начинают воспринимать как решение абсолютно всех проблем. Несколько лет назад подобным образом обсуждали Kubernetes. Затем похожая история произошла с сервисными сетками. Сегодня аналогичные процессы можно наблюдать вокруг платформ наблюдаемости. Каждая новая волна энтузиазма сопровождается попытками найти единственно правильный путь и навсегда закрыть вопрос выбора.
Практика эксплуатации больших систем последовательно разрушает подобные иллюзии.
Любое архитектурное решение является отражением ограничений конкретной организации. Размер команды, зрелость процессов, доступный бюджет, отраслевые требования, характер нагрузки и даже корпоративная культура оказывают на итоговый выбор значительно большее влияние, чем сравнительные таблицы функциональных возможностей.
Именно поэтому одна и та же технология способна стать источником огромной выгоды для одной компании и причиной бесконечных проблем для другой.
Когда Loki действительно является лучшим выбором
Существует довольно большой класс организаций, для которых преимущества Loki оказываются настолько убедительными, что дальнейшие обсуждения практически теряют смысл.
Представим современную платформенную команду, сопровождающую несколько Kubernetes-кластеров. Большинство приложений реализовано в виде микросервисов. Разработчики используют структурированные JSON-журналы. Основная задача системы наблюдаемости заключается в поддержке повседневной эксплуатации: расследовании инцидентов, анализе последствий релизов и диагностике проблем производительности.
В подобных условиях характер работы с журналами оказывается удивительно предсказуемым.
Инженеры уже знают, какой сервис необходимо исследовать.
Они понимают, в каком окружении возникла проблема.
Они обладают временным диапазоном возникновения ошибки.
Им требуется максимально быстро получить доступ к информации, а не проводить исследовательский анализ огромных массивов данных.
Для подобных сценариев Loki оказывается чрезвычайно удачным решением.
Он позволяет хранить большие объёмы журналов без экспоненциального роста расходов на инфраструктуру. Он органично интегрируется с Grafana. Он использует архитектурные подходы, хорошо согласующиеся с философией Kubernetes. И, что особенно важно, он позволяет командам сосредоточиться на эксплуатации собственных сервисов, а не на постоянном сопровождении платформы логирования.
Следует отметить ещё один аспект, который редко обсуждается публично.
Очень многие организации впервые начинают задумываться о стоимости логирования только после того, как объёмы данных достигают нескольких терабайт в сутки. До этого момента даже не самые эффективные архитектурные решения могут оставаться вполне приемлемыми. Однако при дальнейшем росте инфраструктуры ситуация меняется кардинально.
В этот момент философия Loki перестаёт быть вопросом вкусовых предпочтений.
Она превращается в экономическую необходимость.
Когда Elasticsearch остаётся наиболее разумным вариантом
Существует и другая категория организаций, для которых отказ от Elasticsearch способен принести значительно больше вреда, чем пользы.
Особенно хорошо это заметно в финансовом секторе, информационной безопасности и аналитических подразделениях крупных компаний.
В подобных средах журналы рассматриваются не только как средство диагностики приложений.
Они становятся полноценным источником знаний о поведении пользователей, состоянии процессов и потенциальных угрозах.
Специалисты по безопасности исследуют последовательности событий, пытаясь обнаружить признаки компрометации.
Аналитики выявляют аномалии и строят гипотезы.
Команды antifraud изучают сложные взаимосвязи между действиями клиентов.
Во всех этих случаях ключевым требованием становится возможность задавать вопросы, ответы на которые заранее неизвестны.
Именно здесь Elasticsearch продолжает демонстрировать свои сильнейшие стороны.
Его стоимость действительно может оказаться выше.
Его сопровождение требует высокой квалификации.
Его эксплуатация предполагает глубокое понимание принципов работы индексов, shard и распределённого хранения данных.
Однако отказ от подобных возможностей зачастую означает потерю важнейших инструментов исследования.
Поэтому зрелые организации рассматривают подобные расходы не как избыточную роскошь, а как инвестиции в собственную способность понимать происходящее внутри сложных систем.
Почему зрелость команды важнее выбора технологии
Одним из наиболее неожиданных выводов, к которому приходят инженеры после нескольких лет эксплуатации различных платформ наблюдаемости, становится понимание того, насколько сильно качество результата зависит не от выбранного инструмента, а от культуры его использования.
Можно приобрести дорогостоящий Elasticsearch-кластер, обладающий впечатляющими аналитическими возможностями, и при этом продолжать хранить хаотичные журналы без структуры и единых соглашений.
Можно внедрить Loki, но превратить его в источник постоянных проблем из-за бесконтрольного роста кардинальности меток.
Можно построить отказоустойчивую архитектуру и никогда не проверять сценарии восстановления после сбоев.
Во всех этих случаях технология сама по себе оказывается совершенно непричастной к возникновению проблем.
Настоящая причина заключается в отсутствии инженерной дисциплины.
Зрелые команды обладают несколькими общими чертами независимо от используемого инструментария.
Они стандартизируют форматы журналов.
Они регулярно пересматривают практики логирования.
Они проводят нагрузочное тестирование платформ наблюдаемости.
Они документируют процессы расследований.
Они рассматривают телеметрию как важнейший производственный актив, а не как побочный продукт работы приложений.
Именно такие организации получают максимальную пользу практически от любой технологии.
Наблюдаемость как отражение инженерной культуры
Пожалуй, самым интересным изменением последних лет стало постепенное переосмысление роли наблюдаемости внутри современных компаний.
Когда-то журналы существовали исключительно для того, чтобы помочь системному администратору разобраться в причинах очередной ошибки. Их воспринимали как техническую деталь реализации, не заслуживающую особого внимания. В лучшем случае они использовались во время расследований серьёзных инцидентов.
Сегодня ситуация выглядит принципиально иначе.
Метрики помогают обнаруживать деградацию производительности ещё до появления пользовательских жалоб.
Трассировки позволяют восстанавливать путь запроса через десятки микросервисов.
Журналы предоставляют необходимый контекст для понимания происходящего.
Профилирование помогает находить узкие места внутри приложений.
Все эти элементы постепенно объединяются в единую систему коллективного восприятия инфраструктуры.
Фактически наблюдаемость превращается в способ мышления организации.
Она определяет, насколько быстро люди замечают отклонения от нормального поведения. Насколько эффективно они способны формировать и проверять гипотезы. Насколько уверенно принимаются решения в условиях неопределённости.
Именно поэтому вопрос выбора между Loki и Elasticsearch оказывается значительно глубже обсуждения технических характеристик.
Речь идёт не просто о программном обеспечении.
Речь идёт о том, каким образом организация учится понимать собственные системы.
А это понимание, как показывает практика, зачастую оказывается одним из важнейших конкурентных преимуществ в мире, где сложность инфраструктуры продолжает расти быстрее, чем количество людей, способных удерживать её устройство целиком в собственной голове.
Заключение: чему нас на самом деле научила история Loki и ELK
История противостояния Loki и Elasticsearch часто подаётся как очередной технологический конфликт, в котором одна система должна окончательно вытеснить другую. Подобный подход хорошо работает в заголовках новостей и конференционных докладов, однако имеет крайне мало общего с реальной инженерной практикой. Чем дольше работаешь с крупными распределёнными системами, тем отчётливее понимаешь, что развитие инфраструктуры редко происходит через полное уничтожение предыдущих подходов. Гораздо чаще новые технологии появляются потому, что меняется окружающая среда, а вместе с ней меняются и требования к инструментам.
Именно это произошло с логированием.
Elasticsearch появился в эпоху, когда основной проблемой было отсутствие удобного способа исследовать данные. Организациям требовалась поисковая платформа, способная превратить набор разрозненных текстовых файлов в единое пространство анализа. Необходимо было находить неизвестные закономерности, строить отчёты и исследовать события, взаимосвязь между которыми заранее оставалась неочевидной. Elasticsearch великолепно справился с этой задачей и фактически сформировал культуру централизованного логирования такой, какой мы знаем её сегодня.
Затем мир изменился.
Kubernetes превратил инфраструктуру в динамическую среду, где контейнеры живут считанные минуты, количество экземпляров приложений постоянно меняется, а объёмы телеметрии растут быстрее, чем бюджеты на вычислительные ресурсы. В подобных условиях выяснилось, что прежние архитектурные предположения начинают работать против самих организаций. Полное индексирование огромных потоков журналов перестало быть очевидным благом и превратилось в дорогостоящий компромисс.
На этом фоне появился Loki.
Он предложил не новую реализацию старых идей, а совершенно иной взгляд на саму природу эксплуатационных расследований. Вместо попытки подготовить ответы на любые возможные вопросы платформа исходила из предположения, что инженеры уже обладают значительной частью необходимого контекста. Они знают, какое приложение исследуют. Они понимают, в каком окружении возникла проблема. Они способны ограничить область поиска ещё до момента выполнения запроса.
Именно поэтому Loki оказался настолько востребованным в Kubernetes-средах.
Он не пытался победить Elasticsearch на его территории.
Он предложил новую экономическую модель работы с журналами.
Что в действительности выбирают инженеры
После всех сравнений может показаться, что выбор платформы наблюдаемости представляет собой исключительно техническое решение. Достаточно сравнить производительность, стоимость хранения и набор функций, после чего определить победителя.
Реальная жизнь устроена значительно сложнее.
На практике инженеры выбирают не программное обеспечение.
Они выбирают компромиссы.
Выбирают между стоимостью хранения и глубиной аналитики.
Между универсальностью и специализацией.
Между простотой эксплуатации и богатством функциональных возможностей.
Между необходимостью исследовать неизвестное и стремлением максимально быстро реагировать на хорошо понятные инциденты.
Именно поэтому две компании, обладающие одинаковыми объёмами журналов, могут прийти к совершенно разным архитектурным решениям и при этом обе окажутся правы.
Организация, сопровождающая сотни микросервисов в Kubernetes и ориентированная преимущественно на эксплуатационные расследования, с высокой вероятностью получит огромную выгоду от использования Loki.
Банк, ежедневно анализирующий сложные мошеннические схемы и исследующий поведение миллионов пользователей, вероятнее всего продолжит активно использовать Elasticsearch.
Крупная корпорация может одновременно применять обе платформы, распределяя между ними различные сценарии работы.
Во всех этих случаях речь идёт не о выборе "правильной" технологии.
Речь идёт о понимании собственных потребностей.
Самый важный урок современной наблюдаемости
Пожалуй, существует ещё один вывод, который редко формулируется напрямую, хотя именно он объединяет всю историю развития систем логирования.
Наблюдаемость перестала быть технической функцией.
Она превратилась в элемент инженерной культуры.
Когда команда проектирует структуру журналов, она фактически определяет, насколько быстро сможет понимать происходящее внутри собственных систем.
Когда архитекторы принимают решения о сроках хранения данных, они выбирают баланс между стоимостью и возможностью расследовать инциденты спустя месяцы после их возникновения.
Когда разработчики добавляют или удаляют сообщения журналов, они влияют не только на удобство диагностики, но и на общую экономику платформы.
Когда SRE-команды определяют показатели качества обслуживания для систем наблюдаемости, они признают очевидный, но крайне важный факт: невозможно эффективно управлять инфраструктурой, которую невозможно понять.
Именно поэтому современные платформы логирования требуют зрелости.
Недостаточно установить Helm Chart.
Недостаточно выбрать модную технологию.
Недостаточно следовать рекомендациям из чужих архитектурных диаграмм.
Необходимо понимать последствия принимаемых решений.
Потому что любая распределённая система рано или поздно начинает вести себя неожиданным образом. Неудачные релизы, каскадные отказы, ошибки конфигурации и человеческий фактор были и останутся неотъемлемой частью эксплуатации. Единственное, что действительно отличает зрелые организации от всех остальных, - это способность быстро разобраться в происходящем и принять правильные решения до того, как локальная проблема превратится в полноценный кризис.
Именно эту способность и обеспечивает наблюдаемость.
Вместо послесловия
Когда-то журналы представляли собой обычные текстовые файлы, лежащие в каталоге /var/log. Администраторы открывали их при помощи less, выполняли несколько команд grep и, немного поворчав на разработчиков, возвращались к привычной работе. Тогда мало кто мог предположить, что спустя годы платформы логирования превратятся в распределённые системы, обрабатывающие терабайты данных ежедневно и требующие не меньшего внимания, чем сами производственные сервисы.
Но именно это и произошло.
Сегодня наблюдаемость находится в самом центре современной инфраструктуры. Она объединяет журналы, метрики, трассировки и профилирование в единое пространство понимания происходящего. Она помогает инженерам сохранять контроль над системами, сложность которых уже давно превысила возможности одного человека удерживать всю архитектуру в голове. Она позволяет организациям двигаться быстрее, выпускать изменения чаще и при этом не терять способность разбираться в последствиях собственных решений.
И, возможно, именно в этом заключается главная ирония всей истории.
Loki не победил Elasticsearch. Elasticsearch не проиграл Loki.
Победила сама идея о том, что наблюдаемость должна соответствовать характеру современной инфраструктуры, а не заставлять инфраструктуру подстраиваться под ограничения выбранного инструмента.
И пока распределённые системы продолжают усложняться, эта идея будет становиться только важнее.