Для будущих учащихся на курсе "Highload Architect" и всех желающих подготовили перевод интересной статьи.Также приглашаем посмотреть открытый урок "Паттерны горизонтального масштабирования хранилищ".  Наша группа — Кевин Лью (Kevin Lew), Нараянан Аруначалам (Narayanan Arunachalam), Элизабет Карретто (Elizabeth Carretto), Дастин Хаффнер (Dustin Haffner), Андрей Ушаков, Сет Кац (Seth Katz), Грег Баррелл (Greg Burrell), Рам Вайтхилингам (Ram Vaithilingam), Майк Смит (Mike Smith) и Маулик Пандей (Maulik Pandey) «@Netflixhelps Почему "Король тигров" не идет на моем телефоне?» — подписчик Netflix спрашивает через Twitter Это пример вопроса, на который инженерам нашей службы поддержки приходится отвечать в попытке помочь подписчику решить его проблему, — а это очень сложно, когда вы имеете дело с распределенной системой. Для анализа неполадок со стримингом видео требуется проверка всех аспектов работы учетной записи подписчика. В предыдущей статье нашего блога мы рассказали об Edgar, нашей системе поиска и устранения неисправностей в сеансах стриминга. Теперь давайте поговорим о том, как мы спроектировали инфраструктуру трассировки, на основе которой работает Edgar. До появления Edgar нашим инженерам приходилось просматривать горы метаданных и журналов, полученных от различных микросервисов Netflix, чтобы понять причину конкретного сбоя стриминга, который возник у кого-то из наших подписчиков. Восстановление сеанса стриминга было утомительным и занимающим много времени процессом, в котором требовалось проследить все взаимодействия (запросы) между приложением Netflix, нашей сетью доставки контента (CDN) и серверными микросервисами. В начале процесса инженер вручную получал информацию об учетной записи подписчика, который участвовал в сеансе. Далее необходимо было сложить вместе все детали пазла в надежде, что получившаяся картина позволит решить проблему подписчика. Нам нужно было повысить продуктивность работы специалистов за счет распределенной трассировки запросов. Если бы у нас был идентификатор каждого сеанса стриминга, то путем распределенной трассировки можно было бы легко воспроизвести сбой сеанса и увидеть при этом топологию сервисов, теги повторных попыток и ошибок, а также значения задержек для всех вызовов сервисов. Мы также могли бы получать контекстную информацию о сеансе стриминга, объединяя соответствующие трассировки с метаданными учетной записи и журналами сервисов. Эта идея привела нас к созданию Edgar — инфраструктуры распределенной трассировки, ориентированной на удобство пользователей. Когда четыре года назад мы начинали создавать Edgar, существовало очень мало систем распределенной трассировки с открытым исходным кодом, которые отвечали нашим потребностям. Мы решили подождать, пока эти системы достигнут зрелого состояния, и первое время собирали трассировки от Java-сервисов стриминга с помощью собственных библиотек. К 2017 году такие открытые проекты, как Open-Tracing и Open-Zipkin, достигли достаточного уровня зрелости, чтобы их можно было использовать в многоязычных средах выполнения, применяющихся в Netflix.  Наш выбор пал на Open-Zipkin, поскольку эта система лучше интегрировалась с нашей средой выполнения Java на основе Spring Boot. Мы используем Mantis для обработки потока собранных трассировок, а для хранения трассировок мы используем Cassandra. Наша инфраструктура распределенной трассировки состоит из трех компонентов: инструментарий библиотек трассировки, обработка потоков и хранилище. Трассировки, получаемые от различных микросервисов, обрабатываются как поток и перемещаются в хранилище данных. В следующих разделах описан наш путь по созданию этих компонентов. Это был первый вопрос, заданный нам нашими техническими группами во время интеграции библиотеки трассировки. Этот вопрос важен, поскольку библиотеки трассировки перехватывают все запросы, проходящие через важнейшие сервисы стриминга. Нашим основным приоритетом была надежная интеграция и развертывание библиотек трассировки в наших многоязычных средах выполнения. Чтобы завоевать доверие наших инженеров, мы учли те сложности, которые им приходилось преодолевать во время работы, а также стремились обеспечить эффективную интеграцию библиотек трассировки в среды выполнения. В основе распределенной трассировки лежит распространение контекста для локальных межпроцессных вызовов и клиентских вызовов к удаленным микросервисам для любого произвольного запроса. При передаче контекста запроса фиксируются причинно-следственные связи между микросервисами во время выполнения. Мы использовали механизм распространения контекста на основе заголовков HTTP B3 из Open-Zipkin. Мы следим за тем, чтобы заголовки, используемые для распространения контекста, правильно передавались между микросервисами в разнообразных средах выполнения Java и Node, которые интегрированы в нашу систему разработки ПО (внутри компании она называется paved road). В эту систему входят как базы legacy-кода, так и новые среды, например Spring Boot. Следуя принципу нашей культуры «Свобода и ответственность», мы поддерживаем библиотеки трассировки и в других средах (Python, NodeJS, Ruby on Rails и др.), которые не входят в систему paved road. Наши свободные, но высокоскоординированные инженерные группы могут по своему усмотрению выбирать подходящую библиотеку трассировки для своей среды выполнения и отвечают за обеспечение правильного распространения контекста и интеграцию перехватчиков сетевых вызовов. Средства интеграции со средами выполнения создают теги инфраструктуры, такие как имя сервиса, группа автоматического масштабирования и идентификаторы контейнерных инстансов. При поиске и устранении сбоев в сеансах стриминга Edgar использует эту схему тегов инфраструктуры для запроса и объединения трассировок с данными журналов. Кроме того, благодаря использованию согласованных тегов в Edgar оказалось легко устанавливать глубокие связи с разными системами мониторинга и развертывания. Обеспечив интеграцию со средами выполнения, мы должны были задать надлежащую политику выборки данных трассировки, чтобы обеспечить удобство поиска и устранения сбоев. Это был самый важный вопрос, который мы рассматривали при создании нашей инфраструктуры, поскольку политика выборки данных определяет количество трассировок, которые записываются, передаются и хранятся. При использовании мягкой политики выборки данных трассировки формируется большое количество трассировок в каждом сервисном контейнере, а это может привести к снижению производительности сервисов стриминга, поскольку библиотека трассировки будет потреблять больше ресурсов ЦП, памяти и сети. Еще одной проблемой, которую несет с собой мягкая политика выборки, является необходимость в масштабируемой обработке потоков и инфраструктуре хранения, позволяющей размещать крупные объемы данных. Мы понимали, что полагаться на большие наборы данных трассировки для поиска и устранения сбоев нельзя, поскольку даже при большом количестве выборок нет гарантии, что нужный запрос находится в собранных данных. Нам требовался вдумчивый подход, обеспечивающий сбор всех трассировок в микросервисах стриминга при низкой операционной сложности работы нашей инфраструктуры. В большинстве систем распределенной трассировки политика выборки применяется в точке приема запросов (если представить себе диаграмму вызовов микросервисов). Мы выбрали гибридный подход к выборке данных на основе заголовков, который позволяет записывать 100 % трассировок для определенного, настраиваемого набора запросов. В остальном же трафике выборка производится случайным образом в соответствии с политикой, заданной в точке приема. Такой гибкий подход позволяет библиотекам трассировки записывать все трассировки наших важнейших микросервисов стриминга, собирая при этом минимальное количество трассировок от таких вспомогательных систем, как система отложенной пакетной обработки данных. Наши инженерные группы настроили свои сервисы на максимальную производительность с учетом возросшей из-за трассировки потребности в ресурсах. Следующей проблемой была потоковая передача больших объемов трассировок через масштабируемую платформу обработки данных.   Mantis — это основная платформа обработки операционных данных в Netflix. Мы выбрали платформу Mantis в качестве магистрали для передачи и обработки больших объемов данных трассировки, поскольку нам требовалась масштабируемая система потоковой обработки, способная справляться с эффектами backpressure. Наш агент сбора данных трассировки перемещает эти данные в кластер заданий Mantis с помощью библиотеки Mantis Publish. Мы помещаем диапазоны в буфер на определенный период времени, чтобы собрать все диапазоны трассировки в первом задании. Второе задание забирает поток данных из первого задания, выполняет хвостовую выборку данных и записывает трассировки в систему хранения. Такая цепочка заданий Mantis позволяет нам масштабировать все компоненты обработки данных независимо друг от друга. Дополнительное преимущество использования Mantis заключается в возможности выполнять произвольный просмотр данных в режиме реального времени в Raven с помощью языка запросов Mantis (MQL). Однако наличие масштабируемой платформы потоковой обработки не особо помогает, если невозможно обеспечить экономичное хранение данных. Сначала в качестве хранилища данных мы использовали Elasticsearch: нас привлекли гибкая модель данных и возможности обработки запросов, которые есть в этом продукте. Мы продолжали добавлять в систему все больше сервисов стриминга, и объем данных трассировки начал экспоненциально расти. Из-за высокой скорости записи данных приходилось постоянно масштабировать кластеры Elasticsearch, вследствие чего возрастала операционная нагрузка. Запросы на чтение данных выполнялись все дольше, поскольку кластеры Elasticsearch использовали значительные вычислительные ресурсы для индексирования вносимых в них трассировок. Из-за больших объемов получаемых данных со временем упала производительность и операций чтения, и операций записи. Выйти из этой ситуации нам удалось путем перехода на Cassandra в качестве хранилища данных: этот продукт позволил нам справиться с большим объемом получаемых данных. Использование простых поисковых индексов в Cassandra дает нам возможность поддерживать приемлемые задержки чтения, выполняя при этом большие объемы операций записи. В теории горизонтальное масштабирование позволило бы нам поддерживать высокую скорость записи и сохранять большие объемы данных в кластерах Cassandra. Это означает, что затраты на хранение трассировок растут линейно в зависимости от объема хранимых данных. Нам нужно было сделать так, чтобы рост затрат на хранение был сублинейным по отношению к объему хранимых данных. Стремясь достичь этой цели, мы сформировали следующие стратегии оптимизации хранилища: Использовать более дешевые тома Elastic Block Store (EBS) вместо инстансов EC2 с SSD. Задействовать улучшенные методы сжатия, чтобы уменьшить размер данных трассировки. Хранить только важные и интересные трассировки, используя для этого простые фильтры на основе правил. Мы добавляли новые узлы Cassandra, когда на существующих узлах переполнялись хранилища инстансов EC2 с SSD. Использование более дешевых томов EBS Elastic вместо хранилищ на базе инстансов с SSD было привлекательным вариантом, поскольку AWS позволяет динамически увеличивать размер томов EBS без повторного выделения узла EC2. Это позволило нам увеличивать общую емкость хранилища, не добавляя новые узлы Cassandra в существующий кластер. В 2019 году наши замечательные коллеги из группы Cloud Database Engineering (CDE) протестировали производительность EBS для нашего сценария и перенесли существующие кластеры на тома EBS Elastic.  За счет оптимизации параметров Time Window Compaction Strategy (TWCS, «стратегия уплотнения временных интервалов») они сократили количество операций записи на диск и объединения для файлов Cassandra SSTable, сократив тем самым нагрузку ввода-вывода на EBS. Эта оптимизация помогла нам сократить объем сетевого трафика, связанного с репликацией данных между узлами кластера, поскольку файлы SSTable создавались реже, чем в нашей предыдущей конфигурации. Кроме того, обеспечение возможности сжатия блоков Zstd в файлах данных Cassandra позволило наполовину уменьшить размер наших файлов данных трассировки. Благодаря этим оптимизированным кластерам Cassandra мы теперь тратим на 71 % меньше средств на обеспечение работы кластеров и можем хранить в 35 раз больше данных, чем при использовании предыдущей конфигурации. Мы заметили, что пользователи Edgar просматривали менее чем 1 % собранных трассировок. Зная это, мы полагаем, что можем понизить нагрузку операций записи и помещать больше данных в систему хранения, если будем удалять трассировки, которые не нужны пользователям. В настоящее время мы используем простой фильтр на основе правил в задании Mantis по сохранению данных. Этот фильтр сохраняет интересные трассировки для путей вызовов сервисов, которые очень редко используются в Edgar. Чтобы определить, является ли трассировка интересной единицей данных, фильтр проверяет все диапазоны трассировки, помещенные в буфер, на предмет тегов предупреждений, ошибок и повторных попыток. Хвостовая выборка позволила сократить объем данных трассировки на 20 % без влияния на работу пользователей. Существует возможность использовать методы классификации на основе машинного обучения, чтобы еще больше сократить объемы данных трассировки. Несмотря на то что мы добились значительного прогресса, сейчас мы достигли очередной поворотной точки на пути построения нашей системы хранения данных трассировки. Реализация новых возможностей для пользователей Edgar может потребовать от нас хранить в 10 раз больше данных по сравнению с текущими объемами. С учетом этого сейчас мы экспериментируем с вариантом многоуровневого хранения для нового шлюза данных. Этот шлюз данных имеет интерфейс запросов, который позволяет абстрагироваться от сложностей, связанных с чтением и записью данных в многоуровневые хранилища. Кроме того, шлюз данных направляет получаемые данные в кластер Cassandra и перемещает сжатые файлы данных из кластера Cassandra в S3. Мы планируем сохранять данные за последние несколько часов в кластерах Cassandra, а остальные трассировки, хранящиеся в течение длительного времени, будут находиться в корзинах S3. Помимо обеспечения работы Edgar, данные трассировки используются в следующих случаях. Мониторинг состояния приложений Данные трассировки являются основным сигналом, используемым Telltale при мониторинге состояния приложений на макроуровне в Netflix. Telltale использует причинно-следственную информацию из трассировок для определения топологии микросервисов и соотнесения трассировок с данными временных рядов из Atlas. Такой подход позволяет получить более детальную картину состояния приложений. Проектирование устойчивости Наша группа по хаос-инжинирингу использует трассировки для проверки правильности внесения сбоев, когда наши инженеры выполняют стресс-тесты своих микросервисов с помощью платформы тестирования методом внедрения отказов (FIT). Эвакуация из облачных регионов Инженерная группа, ответственная за мониторинг спроса, применяет трассировку для повышения точности предварительного масштабирования во время эвакуации из облачного региона. Трассировки позволяют определять типы устройств, взаимодействующих с микросервисами, чтобы изменения в спросе для этих сервисов можно было лучше учитывать при эвакуации из региона AWS. Оценка затрат на инфраструктуру при выполнении A-/B-тестирования Группа по data science и исследованию продуктов определяет затраты на выполнение A-/B-тестирования на микросервисах путем анализа трассировок, в которых есть соответствующие имена и теги тестов A/B. По мере роста Netflix объем и сложность наших программных систем продолжают повышаться. При расширении Edgar мы будем уделять основное внимание следующим областям: Обеспечение удобства работы разработчиков при сборе трассировок из всех сред выполнения. Мы надеемся, что при наличии простого способа попробовать в деле распределенную трассировку больше инженеров будут оснащать свои сервисы трассировками и предоставлять дополнительный контекст для каждого запроса, снабжая тегами соответствующие метаданные. Расширение возможностей наших аналитиков по запросу данных трассировки, чтобы компетентные пользователи в Netflix могли создавать собственные узконаправленные панели мониторинга и системы. Создание абстракций, которые связывают данные из систем сбора метрик, журналов и трассировок, для предоставления дополнительной контекстной информации с целью поиска и устранения сбоев. Пока мы развиваем инфраструктуру распределенной трассировки, наши инженеры продолжают использовать Edgar для устранения таких проблем со стримингом, как «Почему "Король тигров" не идет на моем телефоне?». Наша инфраструктура распределенной трассировки способствует тому, что подписчики Netflix могут в любое время смотреть свои любимые сериалы, в том числе и «Король тигров»! Мы ищем талантливых коллег, которые хотели бы присоединиться к нам в нашей работе по созданию инфраструктуры распределенной трассировки. Если вы активно интересуетесь темой мониторинга систем, обязательно свяжитесь с нами. Узнать подробнее о курсе "Highload Architect". Посмотреть открытый урок "Паттерны горизонтального масштабирования хранилищ". ЗАБРАТЬ СКИДКУ Редактор