Presto — это бесплатная система обработки SQL-запросов с открытым исходным кодом. Meta пользуется этой системой уже 10 лет, и за это время мы многому научились. При масштабировании инструментов, процессов и служб неизбежно возникают проблемы, которые необходимо решать. Мы расскажем о четырех основных моментах, которым мы научились при масштабировании Presto в Meta, и дадим несколько советов, которые пригодятся тем, кто захочет масштабировать свои запросы.
Рисунок 1. Рабочий процесс отправки новых версий Presto (автор диаграммы: Филип С. Белл)
Meta управляет множеством кластеров Presto, расположенных в центрах обработки данных по всему миру. Новая версия Presto выходит обычно один, а иногда и два раза в месяц. Одной из первых проблем, с которой мы столкнулись, когда доля использования Presto в Meta начала быстро расти, стало развертывание механизма запросов в большом количестве кластеров с обеспечением постоянной доступности и надежности. Эта проблема остается актуальной, если Presto используется интерактивно, т. е. когда пользователь запускает запрос и активно ожидает результата. Сбои в запросах менее характерны для тех случаев, когда они автоматизированы и отправляются "пакетно". Автоматизация гарантирует, что запрос в конечном итоге будет успешным.
Мы нашли простое решение. Все кластеры Presto располагаются за балансировщиком нагрузки — шлюзом, который совместно с другими системами в Meta отвечает за маршрутизацию запросов Presto в соответствующий кластер. Когда необходимо обновить кластер Presto, сначала он помечается как удаленный из шлюза, то есть шлюз перестает направлять ему новые запросы. Затем система автоматизации ожидает заранее определенное время для завершения запросов, которые пока выполняются в кластере. После этого кластер обновляется, а затем включается в сеть и становится видимым для шлюза, который может начать маршрутизацию новых запросов в него.
Другой аспект развертывания новых релизов Presto — доступность. Мы должны гарантировать, что пользователи смогут по-прежнему использовать Presto во время обновления кластеров. И в этом случае автоматизация гарантирует, что в каждом центре обработки данных в каждом физическом регионе всегда есть необходимое количество кластеров Presto. Конечно, мы должны соблюдать баланс между одновременным отключением слишком большого количества кластеров, что вызовет проблемы с доступностью, и одновременным отключением слишком малого количества кластеров, из-за чего развертывание займет слишком много времени.
Рисунок 2. Автоматизированный рабочий процесс добавления оборудования в кластеры (автор диаграммы: Филип С. Белл)
Распределение хранилища данных в Meta по различным регионам постоянно меняется. Из-за этого необходимо регулярно вводить в эксплуатацию новые кластеры Presto и выводить старые. Раньше, когда кластеров Presto было совсем немного, процесс выполнялся вручную. По мере масштабирования Meta отслеживать все изменения вручную стало не так просто. Чтобы решить эту проблему, мы внедрили автоматизацию ввода кластеров в эксплуатацию и вывода из нее.
Прежде всего необходимо было привести все конфигурации к одному стандарту, и мы создали базовые конфигурации для разных сценариев использования Presto в Meta. Для каждого кластера мы определили минимальное количество дополнительных или переопределяемых базовых характеристик. После этого стало возможно запустить любой новый кластер путем автоматической генерации конфигураций на основе базового шаблона. Развертывание кластера также требовало интеграции с механизмами автоматизации, чтобы интегрироваться с различными инфраструктурными службами компании, такими как Tupperware, и службами, связанными с хранилищем данных. После запуска кластера в работу на него отправляется несколько тестовых запросов, и система автоматизации подтверждает, что кластер успешно выполнил их. Затем кластер регистрируется в шлюзе и начинает обрабатывать запросы.
Вывод кластера из эксплуатации — обратный процесс. Необходимо отменить регистрацию кластера в шлюзе и завершить выполняющиеся запросы. При этом процессы Presto останавливаются, а конфигурации кластеров удаляются.
Такая автоматизация интегрирована в рабочий процесс ввода и вывода из эксплуатации на аппаратном уровне для хранилища данных. В итоге автоматизируется весь процесс: от появления нового оборудования в центре обработки данных и до запуска кластеров Presto в сети и обслуживания запросов и их последующего отключения при выводе оборудования из эксплуатации. Внедрение этой системы позволило сэкономить ценные человеческие ресурсы, сократить время простоя оборудования и свести к минимуму вероятность человеческой ошибки.
Рисунок 3. Обнаружение "плохого" хоста (автор диаграммы: Филип С. Белл)
Учитывая масштабы развертывания Presto в Meta, нам крайне важно иметь инструменты и автоматизацию, облегчающие жизнь дежурному оператору, который является точкой контакта с Presto.
За годы работы мы создали несколько "анализаторов", которые помогают оператору эффективно выполнять отладку и оценивать первопричину возникающих проблем. Системы мониторинга оповещают о нарушениях соглашения об уровне обслуживания для клиентов. После этого активируются анализаторы. Они получают информацию из широкого спектра систем мониторинга (Operational Data Store или ODS), событий, опубликованных в Scuba, и даже журналов на уровне хоста. Затем пользовательская логика в анализаторе объединяет эту информацию, чтобы сделать вывод о вероятной первопричине. Это чрезвычайно полезно для дежурного оператора, так как он получает анализ первопричины и может перейти непосредственно к поиску вариантов устранения последствий. В некоторых случаях мы полностью автоматизировали как отладку, так и устранение проблем, чтобы оператору вообще не приходилось заниматься этим. Вот пара примеров.
Используя Presto на большом количестве машин, мы заметили, что из-за некоторых "плохих" хостов могут происходить многочисленные сбои в запросах. После проведенного расследования мы выявили несколько основных причин, по которым хосты стали "плохими", в том числе:
Чтобы разрешить эту проблему, мы начали постоянно отслеживать сбои в запросах в кластерах Presto. В частности, когда это возможно, мы сопоставляем каждый сбой запроса с хостом, который его вызвал. Мы также настроили оповещения, которые срабатывают, когда на определенных хостах возникает слишком большое количество отказов на запросы. Затем начинает действовать автоматизация, позволяющая удалить хост из Presto и тем самым остановить сбои.
Каждый кластер Presto поддерживает постановку запросов в очередь после достижения максимального параллелизма для выполнения запросов в зависимости от сценария использования, конфигурации оборудования и размера запроса. В Meta используется сложный механизм маршрутизации, благодаря которому запрос Presto направляется в "правильный" кластер, который может выполнить его с оптимальным использованием ресурсов. Помимо Presto, в принятии решения о маршрутизации участвуют несколько систем. Они учитывают разные факторы:
Из-за этого дежурному оператору может быть сложно выяснить основную причину проблем с очередями, возникающих в производственной среде. Это ещё один случай, когда на первый план выходят аналитики, которые собирают информацию из нескольких источников и представляют выводы.
Рисунок 4. Надежность балансировщика нагрузки (автор диаграммы: Филип С. Белл)
Как мы уже говорили, наши кластеры Presto располагаются за балансировщиками нагрузки, которые маршрутизируют каждый запрос Presto в Meta. В начале, когда мы ещё не использовали Presto в таком масштабе, как сейчас, шлюз был очень простым. По мере роста использования Presto в Meta мы столкнулись с проблемами масштабируемости в некоторых случаях. Одним из них стал отказ шлюза при высокой нагрузке, что могло привести к недоступности Presto для всех пользователей. Основной причиной некоторых проблем со стабильностью была одна служба, непреднамеренно нагружавшая шлюз миллионами запросов за короткий промежуток времени. Это приводило к сбою процессов шлюза и невозможности их маршрутизации.
Чтобы предотвратить такой сценарий, мы решили сделать шлюз более надежным и устойчивым к такому непреднамеренному трафику, напоминающему DDoS-атаку. Мы внедрили функцию регулирования, которая отклоняет запросы при высокой нагрузке. Регулирование можно активировать в зависимости от количества запросов в секунду по различным параметрам, таким как пользователь, источник, IP-адрес, а также на глобальном уровне для всех запросов. Другое усовершенствование, которое мы внедрили, — автоматическое масштабирование. Благодаря службе, которая используется в Meta для поддержки масштабирование заданий, мы сделали количество экземпляров шлюза динамичным. Это означает, что при высокой нагрузке шлюз теперь может масштабироваться для обработки дополнительного трафика и не исчерпывать ресурсы процессора или памяти, предотвращая тем самым описанный сценарий сбоя. В сочетании с функцией регулирования это гарантирует надежную работу шлюза и то, что он может выдерживать неблагоприятные непредсказуемые режимы трафика.
Рисунок 5. Масштабирование архитектуры Presto (автор диаграммы: Филип С. Белл)
Вот несколько важных аспектов, о которых следует помнить при масштабировании Presto:
Эта статья написана Нирадом Соманчи, инженером по производству (Meta), и Филипом Беллом, консультантом разработчиков (Meta).
Чтобы узнать подробнее о Presto, посетите официальный сайт prestodb.io, посмотрите краткий обзор Presto от Филипа Белла на YouTube, а также подпишитесь на Presto в Twitter, Facebook и LinkedIn.
Чтобы узнать больше о Meta Open Source, перейдите на наш сайт, посвященный открытому исходному коду, подпишитесь на наш YouTube-канал или следите за нами в Twitter, на Facebook и в LinkedIn.