Кластер из десятков сервисов выдаёт гигабайты логов в сутки, и рано или поздно встаёт вопрос, куда их складывать и как потом искать. Два лагеря спорят давно. Один зовёт проверенный временем стек на основе полнотекстового поиска, другой предлагает лёгкую систему, которая почти ничего не индексирует. Разница между ними не в мелочах настройки, а в самой философии хранения логов, и она тянет за собой всё: и счёт за хранилище, и скорость поиска, и сложность сопровождения. Разберём честно, на чём экономит лёгкий подход, чем за это платит, и какой выбор разумнее под какую задачу.
В чём фундаментальное различие двух подходов
Всё упирается в один вопрос: что именно индексировать. Стек на основе полнотекстового поиска индексирует содержимое каждой строки лога целиком. Каждое слово в каждой строке разбирается и попадает в обратный индекс, структуру, которая сопоставляет каждому уникальному слову список записей, где оно встречается. Это как поисковик по вашим логам: можно искать любое слово или фразу по всей истории, и поиск будет быстрым независимо от объёма.
Лёгкая система устроена принципиально иначе и черпает идею из мира метрик. Она индексирует только метки, то есть метаданные вроде имени пода, пространства имён, уровня лога, а само содержимое строк хранит сжатыми блоками без индексации. Грубо говоря, она знает, из какого пода и когда пришёл лог, но не строит поискового индекса по тексту самих сообщений. Это единственное различие и определяет дальше всё остальное: стоимость, производительность, возможности поиска и операционную сложность.
Почему экономия на хранении настолько велика
Раз содержимое не индексируется, отпадает огромная статья расходов. Полнотекстовый индекс сам по себе занимает место, нередко сопоставимое с объёмом исходных данных или больше, и требует серьёзных вычислений при приёме каждой строки. Лёгкая система всего этого избегает: индексировать почти нечего, поэтому приём логов потребляет заметно меньше процессора и памяти на каждую запись.
Различается и само хранилище. Стек на основе индекса хранит и индекс, и сырые логи на быстрых дисках, потому что для скорости поиска ему нужны производительные накопители. Лёгкая система складывает сжатые блоки логов в дешёвое объектное хранилище, то самое, где обычно лежат резервные копии и файлы. Разница в цене между быстрым диском и объектным хранилищем огромна. По оценкам, переход на лёгкую систему даёт сокращение потребления ресурсов в три-шесть раз по сравнению с полнотекстовым стеком. Чем больше объём логов, тем шире разрыв в счёте.
Сюда же добавляется требовательность к памяти. Полнотекстовый движок прожорлив по своей природе: типичный боевой кластер ради отказоустойчивости держат хотя бы на трёх узлах, и каждому нужно от восьми гигабайт памяти как минимума, а при заметных объёмах реалистичнее шестнадцать или тридцать два. Лёгкая система обходится скромнее, и для команды на ограниченном бюджете это решающий довод.
Где полнотекстовый поиск незаменим
Но честность требует показать обратную сторону, потому что экономия на индексе не бесплатна. Когда нужен богатый поиск по всему содержимому логов, полнотекстовый стек оказывается быстрее, и порой решительно. Его обратный индекс делает мгновенным запрос вида найти все логи, содержащие вот эту строку ошибки, по всем сервисам разом, независимо от объёма данных.
Лёгкая система на таком запросе вынуждена перебирать сохранённые логи переборкой, то есть фактически читать и просматривать блоки, потому что индекса по тексту у неё нет. Если вы знаете, в каком сервисе искать, и фильтруете по метке, лёгкая система эффективна и быстра. Но если нужно прочесать всё содержимое в поисках произвольной фразы без привязки к конкретному поду, полнотекстовый стек выигрывает за счёт индекса.
Разница хорошо видна на двух типах запросов. Запрос с фильтром по метке вроде покажи ошибки из этого конкретного пода за последний час лёгкая система обслуживает прекрасно. А запрос полнотекстового поиска вроде найди соединение отказано по всему продакшену быстрее отработает полнотекстовый движок. Первый сценарий это повседневная отладка известного сервиса, второй это расследование, когда неизвестно, где искать.
Чем различаются языки запросов
Различие в индексации отражается и в том, как формулируют запросы. Лёгкая система предлагает свой язык, похожий по духу на язык полнотекстового стека, но заточенный под фильтрацию по меткам с последующим просеиванием текста. Типичный запрос сперва сужает выборку по метке, а уже потом ищет подстроку в отобранных строках.
# Лёгкая система: сначала метка, потом фильтр по тексту
{namespace="production"} |= "error"
# Полнотекстовый стек: запрос к индексу по содержимому
message: "error" AND kubernetes.namespace: "production"
Принцип лёгкой системы виден сразу: фигурные скобки задают фильтр по проиндексированным меткам, а оператор подстроки уже перебирает текст внутри отобранного. Это работает быстро ровно потому, что метка резко сужает объём данных до просеивания. Полнотекстовый стек обращается напрямую к индексу содержимого, и его сила в сложных запросах: нечёткое совпадение, оценка релевантности, продвинутые агрегации и аналитика по логам, вплоть до поиска аномалий.
Почему операционная сложность тоже часть выбора
Ресурсами и поиском разница не исчерпывается. Сопровождение двух систем устроено по-разному, и это весомый фактор. Лёгкая система проще в эксплуатации во многом потому, что её данные живут в объектном хранилище, а сама она ближе к не хранящей состояние. Масштабирование идёт естественно через распределённую архитектуру, и переиндексация при этом не нужна.
Полнотекстовый стек требует куда большего внимания. Нужно аккуратно управлять разбиением индекса на части, настраивать виртуальную машину, на которой работает движок, следить за дисками, чтобы не упереться в их заполнение или не словить падение по нехватке памяти. Масштабирование возможно через добавление узлов, но процесс сложнее и порой требует переиндексации для равномерного распределения данных. В динамичной среде Kubernetes, где сервисы появляются и исчезают, поддержание полнотекстового кластера в форме превращается в заметную операционную нагрузку.
Есть и плюс зрелости на стороне полнотекстового стека. Это давнее, обкатанное решение с богатой экосистемой надстроек и гибкими средствами визуализации, ставшее во многих местах стандартом наблюдаемости. Лёгкая система моложе, но естественно ложится на экосистему метрик и сама помечает логи по поду и кластеру, что для Kubernetes удобно из коробки.
Как соотносятся сценарии и инструменты
Сведём это в практическую логику выбора. Лёгкая система раскрывается при очень больших объёмах логов, где полнотекстовая индексация стала бы непозволительно дорогой. Если кластер выдаёт сотни гигабайт или терабайты в сутки, а большинство запросов всё равно ограничено метаданными нагрузки, то отказ от индексации содержимого экономит огромные деньги почти без потерь в удобстве. Для облачной среды, где логи естественно помечаются по поду и пространству имён, это попадание в десятку.
Полнотекстовый стек оправдан там, где критичен богатый поиск по всему содержимому, нужны сложные агрегации, аналитика и расследование по неизвестному заранее месту. Аудит, форензика, поиск редких аномалий по всему массиву логов, высокое разнообразие непредсказуемых полей, всё это территория полнотекстового движка. Сюда же относятся ситуации, когда в стек уже вложились: команда знает инструмент, есть готовые панели и накопленный опыт, и менять это ради экономии не всегда разумно.
При выборе полезно честно ответить на несколько вопросов. Каков суточный объём логов и не делает ли он полнотекстовую индексацию разорительной. Как чаще всего ищут инженеры: по известному сервису и метке или произвольным полнотекстовым запросом по всему массиву. Сколько у команды ресурсов и опыта на сопровождение тяжёлого кластера. И есть ли уже сделанные вложения, которые перевесят выгоду перехода.
Какой вывод следует из всего этого
Однозначного победителя в этой паре нет, и это честный итог. Лёгкая система кардинально дешевле по хранению и проще в эксплуатации, потому что не индексирует содержимое и складывает сжатые логи в дешёвое объектное хранилище, но за это расплачивается медленным произвольным поиском по тексту. Полнотекстовый стек даёт мгновенный богатый поиск по всему содержимому и зрелую аналитику ценой высокого расхода ресурсов и серьёзной операционной нагрузки.
Главное при выборе это честно посмотреть на собственный профиль: сколько логов, как их ищут и сколько денег и сил готовы вложить. Тот, кто гонится за богатым полнотекстовым поиском при умеренных объёмах и уже вложился в стек, останется на нём и не прогадает. А тот, у кого логов очень много, а запросы почти всегда привязаны к конкретному сервису, переходом на лёгкую систему срежет счёт за хранилище в разы и упростит сопровождение, смирившись с тем, что редкий полнотекстовый поиск станет медленнее. Решает не мода, а арифметика объёма и характер запросов в конкретном кластере.