Thanos - масштабований Prometheus

Переклад статті підготовлений спеціально для студентів курсу «DevOps практики та інструменти».

Фабіан Рейнарц (Fabian Reinartz) — розробник програмного забезпечення, фанат Go та аматор вирішувати складні завдання. Також він мейнтейнер Prometheus та співзасновник Kubernetes SIG instrumentation. У минулому він був production-інженером у SoundCloud і очолював групу моніторингу CoreOS. В даний час працює в Google.

Бартек Плотка (Bartek Plotka) - Інфраструктурний інженер в Improbable. Захоплюється новими технологіями та проблемами розподілених систем. Має досвід низькорівневого програмування в Intel, досвід контриб'ютора Mesos і production-досвід SRE світового масштабу в Improbable. Займається покращенням світу мікросервісів. Три його кохання: Golang, open source і волейбол.

Дивлячись на флагманський продукт SpatialOS, ви можете здогадатися, що для Improbable потрібна високодинамічна хмарна інфраструктура глобального масштабу з десятками кластерів Kubernetes. Ми були одними з перших, хто почав використовувати систему моніторингу Прометей. Prometheus здатний відслідковувати мільйони метрик у реальному часі і поставляється з потужною мовою запитів, що дозволяє отримувати необхідну інформацію.

Простота та надійність Prometheus є однією з основних його переваг. Однак, пройшовши певний масштаб, ми зіткнулися з кількома вадами. Для вирішення цих проблем ми розробили Танос — проект з відкритим вихідним кодом, створений компанією Improbable для безшовної трансформації існуючих кластерів Prometheus в єдину систему моніторингу з необмеженим сховищем історичних даних. Thanos доступний на Github тут.

Будьте в курсі останніх новин від Improbable.

Наші цілі з Thanos

При певному масштабі виникають проблеми, що виходять за межі можливостей ванільного Prometheus. Як надійно та економно зберігати петабайти історичних даних? Чи можна зробити це без шкоди часу відповіді на запит? Чи можна отримати доступ до всіх метриків, розташованих на різних серверах Prometheus, за допомогою одного API-запиту? Чи можна об'єднати репліковані дані, зібрані за допомогою Prometheus HA?

Для вирішення цих питань ми створили Thanos. У наступних розділах описується, як ми підійшли до вирішення цих питань і пояснюються цілі, які ми переслідували.

Запит даних з кількох екземплярів Prometheus (global query)

Prometheus пропонує функціональний підхід до шардингу. Навіть один Prometheus-сервер забезпечує достатню масштабованість, щоб звільнити користувачів від складнощів горизонтального шардингу практично у всіх варіантах використання.

Хоча це чудова модель розгортання, але часто потрібно отримати доступ до даних на різних серверах Prometheus через єдиний API або UI - Global view. Звичайно, можна відобразити кілька запитів в одній панелі Grafana, але кожен запит може бути виконаний тільки на один сервер Prometheus. З іншого боку, за допомогою Thanos ви можете вимагати та агрегувати дані з декількох серверів Prometheus, оскільки всі вони доступні з однієї кінцевої точки.

Раніше, для отримання global view у Improbable, ми організували наші екземпляри Prometheus у багаторівневу Hierarchical Federation. Це означало створення одного мета-сервера Prometheus, який збирає частину метрик із кожного "листового" сервера.

Thanos - масштабований Prometheus

Цей підхід виявився проблематичним. Він призвів до ускладнення конфігурації, додавання додаткової потенційної точки відмови та застосування складних правил для надання федеральної-кінцевої точки лише потрібних даних. Крім того, federation такого роду не дозволяє отримати справжнє global view, так як не всі дані доступні з одного API-запиту.

З цим тісно пов'язане єдине уявлення даних, зібраних на високодоступних (high-availability, HA) серверах Prometheus. HA модель Prometheus незалежно збирає дані двічі, що настільки просто, що простіше бути не може. Однак використовувати об'єднане та дедупліковане уявлення обох потоків було б набагато зручніше.

Звичайно, у високодоступних серверах Prometheus існує потреба. В Improbable ми справді серйозно ставимося до щохвилинного моніторингу даних, але наявність одного екземпляра Prometheus на кластер є єдиною точкою відмови. Будь-яка помилка конфігурації або збій обладнання може потенційно призвести до втрати важливих даних. Навіть просте розгортання може призвести до невеликих збоїв у зборі метрик, оскільки перезапуск може бути значно довшим за інтервал скрапінгу.

Надійне зберігання історичних даних

Дешеве, швидке та довгострокове сховище метрик – це наша мрія (поділена більшістю користувачів Prometheus). В Improbable ми були змушені настроїти термін зберігання метрик на дев'ять днів (для Prometheus 1.8). Це додає очевидні обмеження про те, як далеко ми можемо подивитися назад.

Prometheus 2.0 у цьому відношенні став кращим, оскільки кількість time series більше не впливає на загальну продуктивність сервера (див. KubeCon keynote o Prometheus 2). Проте Prometheus зберігає дані на локальному диску. Хоча високоефективне стискування даних може значно скоротити використання локального SSD, але в кінцевому рахунку все одно існує обмеження на обсяг історичних даних, що зберігаються.

Крім того, в Improbable ми дбаємо про надійність, простоту та вартість. Великі локальні диски складніші в експлуатації та резервному копіюванні. Вони коштують дорожче та вимагають більше інструментів для резервного копіювання, що призводить до зайвої складності.

Даунсемплінг

Як тільки ми почали працювати з історичними даними, ми зрозуміли, що існують фундаментальні складності з O-великим, які роблять запити дедалі повільнішими, якщо ми працюємо з даними за тижні, місяці та роки.

Стандартним вирішенням цієї проблеми буде даунсемплінг (Downsampling) - Зменшення частоти дискретизації сигналу. За допомогою зниження дискретизації ми можемо “зменшити масштаб” до більшого часового діапазону та підтримувати колишню кількість вибірок, що дозволить зберегти чуйність запитів.

Даунсемплінг старих даних є неминучою вимогою будь-якого рішення для довгострокового зберігання і виходить за рамки ванільного Prometheus.

Додаткові цілі

Однією з початкових цілей проекту Thanos була безшовна інтеграція з будь-якими установками Prometheus. Друга мета полягала у простій експлуатації з мінімальним вхідним бар'єром. Будь-які залежності повинні бути легко задоволені як для невеликих, так і для великих користувачів, що також має на увазі незначну базову вартість.

Архітектура Thanos

Після того, як у попередньому розділі були перераховані наші цілі, давайте попрацюємо над ними та подивимося, як Thanos вирішує ці проблеми.

Global view

Щоб отримати global view поверх існуючих екземплярів Prometheus, нам потрібно зв'язати єдину точку входу запитів з усіма серверами. Саме цим і займається компонент Thanos коляска мотоцикла. Він розгортається поряд з кожним сервером Prometheus і працює як проксі, обслуговуючи локальні дані Prometheus через gRPC-інтерфейс Store API, що дозволяє вибирати time series дані за мітками та тимчасовим діапазоном.

З іншого боку, знаходиться горизонтально масштабований компонент Querier без збереження стану, який робить трохи більше, ніж просто відповідає на запити PromQL через стандартний Prometheus HTTP API. Компоненти Querier, Sidecar та інші Thanos взаємодіють по протоколу gossip.

Thanos - масштабований Prometheus

  1. Querier під час отримання запиту підключається до відповідного серверу Store API, тобто до наших Sidecar'ам і отримує time series дані з відповідних Prometheus-серверів.
  2. Після цього він поєднує відповіді та виконує за ними PromQL-запит. Querier може об'єднувати як дані, що не перетинаються, так і дубльовані дані з HA-серверів Prometheus.

Це вирішує основну частину нашої головоломки - об'єднання даних із ізольованих серверів Prometheus в єдине уявлення. Фактично Thanos можна використовувати лише заради цієї можливості. До існуючих серверів Prometheus не потрібно вносити будь-які зміни!

Необмежений термін зберігання!

Однак рано чи пізно ми захочемо зберегти дані, що виходять за межі звичайного часу зберігання Prometheus. Для зберігання історичних даних ми вибрали об'єктне сховище. Воно широко доступне в будь-якій хмарі, а також у локальних ЦОДах і є дуже економічним. Крім того, практично будь-яке об'єктне сховище є доступним через добре відомий S3 API.

Prometheus записує дані з оперативної пам'яті на диск приблизно кожні дві години. Блок даних, що зберігаються, містить всі дані для фіксованого проміжку часу і є незмінним. Це дуже зручно, оскільки Thanos Sidecar може просто дивитися каталог даних Prometheus і, у міру появи нових блоків, завантажувати їх у бакети об'єктного сховища.

Thanos - масштабований Prometheus

Завантаження в об'єктне сховище відразу після запису на диск дозволяє зберегти простоту "скрапера" (Prometheus і Thanos Sidecar). Що спрощує підтримку, вартість та дизайн системи.

Як бачите, резервне копіювання даних реалізується дуже легко. Але що про запит до даних в об'єктному сховищі?

Компонент Thanos Store діє як проксі для отримання даних із об'єктного сховища. Як і Thanos Sidecar, він бере участь у gossip-кластері та реалізує Store API. Таким чином, існуючі Querier можуть розглядати його як Sidecar, як ще одне джерело time series даних - ніякої спеціальної настройки не потрібно.

Thanos - масштабований Prometheus

Блоки time series даних складаються з кількох великих файлів. Завантаження їх на вимогу було б досить неефективною, а локальне кешування зажадало величезної пам'яті та дискового простору.

Натомість Store Gateway знає, як поводитися з форматом зберігання Prometheus. Завдяки розумному планувальнику запитів та кешування лише необхідних індексних частин блоків стало можливим скоротити складні запити до мінімальної кількості HTTP-запитів до файлів об'єктного сховища. Таким чином, можна скоротити кількість запитів на чотири-шість порядків і досягти часу відгуку, яке загалом важко від запитів до даних на локальному SSD.

Thanos - масштабований Prometheus

Як показано на діаграмі вище, Thanos Querier значно знижує витрати на один запит до даних в об'єктному сховищі, використовуючи формат зберігання Prometheus та розміщуючи пов'язані дані поряд. Використовуючи цей підхід, ми можемо поєднати безліч одиночних запитів у мінімальну кількість bulk-операцій.

Ущільнення та даунсемплінг

Після того, як новий блок time series даних успішно завантажений в об'єктне сховище, ми розглядаємо його як "історичні" дані, які відразу стають доступними через Store Gateway.

Однак через деякий час блоки з одного джерела (Prometheus із Sidecar) накопичуються і вже не використовують весь потенціал індексації. Для вирішення цієї проблеми ми запровадили ще один компонент під назвою Compactor. Він просто застосовує локальний механізм ущільнення Prometheus до історичних даних в об'єктному сховищі та може бути запущений як просте періодичне пакетне завдання.

Thanos - масштабований Prometheus

Завдяки ефективному стиску, запит у сховище за тривалий проміжок часу не становить проблем з погляду розміру даних. Однак потенційна вартість розпакування мільярда значень і прогін через обробник запитів неминуче призведе до різкого збільшення часу виконання запиту. З іншого боку, оскільки кожен піксель екрана припадають сотні точок даних, стає неможливим навіть візуалізувати дані у повному дозволі. Таким чином, даунсемплінг не тільки можливий, але і не призведе до помітної втрати точності.

Thanos - масштабований Prometheus

Для даунсемплінгу даних Compactor безперервно агрегує дані з роздільною здатністю п'ять хвилин і одну годину. Для кожного необробленого фрагмента, закодованого за допомогою TSDB XOR-стиснення, зберігаються різні типи агрегованих даних, такі як min, max або sum для одного блоку. Це дозволяє Querier автоматично вибирати агрегат, який підходить для цього PromQL-запиту.

Для використання даних зі зниженою точністю користувачеві не потрібно ніякої спеціальної конфігурації. Querier автоматично перемикається між різними дозволами та необробленими даними у міру збільшення та зменшення масштабу користувачем. За бажання користувач може керувати цим безпосередньо через параметр “step” у запиті.

Так як вартість зберігання одного ГБ є невеликою, то за умовчанням Thanos зберігає вихідні дані, дані з роздільною здатністю п'ять хвилин і в одну годину. Не потрібно видаляти вихідні дані.

Recording rules

Навіть з Thanos recording rules є значною частиною стека моніторингу. Вони зменшують складність, затримку та вартість запитів. Вони також зручні користувачам для отримання агрегованих даних за метриками. Thanos базується на ванільних екземплярах Prometheus, тому цілком припустимо зберігати recording rules та alerting rules на існуючому сервері Prometheus. Однак у деяких випадках цього може бути недостатньо:

  • Глобальні alert та rule (наприклад, оповіщення, коли сервіс не працює на більш ніж двох із трьох кластерів).
  • Rule для даних поза локальним сховищем.
  • Прагнення зберігати всі rule та alert в одному місці.

Thanos - масштабований Prometheus

Для всіх цих випадків Thanos включає окремий компонент, званий Ruler, який обчислює rule і alert через Thanos Queries. Надаючи добре відомий StoreAPI, вузол Query може отримати доступ до нових обчислених метриків. Пізніше вони зберігаються в об'єктному сховищі і стають доступними через Store Gateway.

Потужність Thanos

Thanos досить гнучкий, щоб його можна було налаштувати під ваші вимоги. Це особливо корисно при міграції з простою Prometheus. Давайте на невеликому прикладі швидко згадаємо, що ми довідалися про компоненти Thanos. Ось як перенести ваш ванільний Prometheus у світ “безлімітного зберігання метрик”:

Thanos - масштабований Prometheus

  1. Додайте Thanos Sidecar до ваших серверів Prometheus – наприклад, сусідній контейнер у Kubernetes pod.
  2. Розгорніть кілька реплік Thanos Querier для перегляду даних. На даному етапі легко налаштувати gossip між Scraper та Querier. Для перевірки взаємодії компонента використовуйте метрику 'thanos_cluster_members'.

Тільки цих двох кроків достатньо, щоб забезпечити global view та безшовну дедуплікацію даних від потенційних HA-реплік Prometheus! Просто підключіть свої дашборди до кінцевої точки HTTP Querier або використовуйте інтерфейс Thanos UI безпосередньо.

Однак якщо вам потрібне резервне копіювання метрик і довгострокове зберігання, потрібно буде виконати ще три кроки:

  1. Створіть бакет AWS S3 або GCS. Налаштуйте Sidecar для копіювання даних у ці бакети. Тепер можна мінімізувати локальне зберігання даних.
  2. Розгорніть Store Gateway і підключіть його до існуючого gossip-кластеру. Тепер можна надсилати запити до даних у резервних копіях!
  3. Розгорніть Compactor, щоб підвищити ефективність запитів для тривалих проміжків часу, використовуючи ущільнення та даунсемплінг.

Якщо ви хочете дізнатися більше, не соромтеся, подивіться на наші приклади маніфесту kubernetes и починаємо!

Всього за п'ять кроків ми перетворили Prometheus на надійну систему моніторингу з global view, необмеженим часом зберігання та потенційною високою доступністю метрик.

Pull request: ви потрібні нам!

Танос від початку був проектом з відкритим вихідним кодом. Безшовна інтеграція з Prometheus та можливість використовувати тільки частину Thanos робить його чудовим вибором для масштабування системи моніторингу без зайвих зусиль.

Ми завжди раді GitHub Pull Request та Issues. У той же час, не соромтеся звертатися до нас через Github Issues або slack Improbable-eng #thanosЯкщо у вас є питання або відгуки, або ви хочете поділитися своїм досвідом використання! Якщо вам подобається те, що ми робимо в Improbable, не соромтеся звертатися до нас. у нас завжди є вакансії!

Дізнатись детальніше про курс.

Джерело: habr.com

Додати коментар або відгук