Привет, Хабр! Меня зовут Алексей Вахов, я технический директор Учи.ру. В середине марта, когда школы начали переходить на дистанционное обучение, мы предоставили учителям и школьникам несколько сервисов для онлайн-занятий. По нашим расчётам, у нас был запас прочности, чтобы выдержать максимум в 1,5-2 раза больше нагрузки. В середине апреля наш трафик вырос в 8 раз. Пришлось сделать много, чтобы удержаться на плаву. Возможно, кому-то пригодится наш опыт, чтобы пережить этот или будущий кризис.
Мы не ожидали таких сюрпризов и не были к ним готовы, к такому не была готова, наверное, ни одна компания в России, да и в мире. Обычно в марте активность на Учи.ру ниже относительно осени из-за весенних и приближающихся летних каникул, в это время мы уже готовимся к сентябрю: пилим фичи, делаем рефакторинг, проводим масштабные архитектурные изменения и занимаемся другой приятной рутиной. Однако в этот раз все было по-другому.
Пиковое количество уникальных пользователей на сайте единовременно достигло 240 тысяч, предыдущий максимум текущего учебного года мы фиксировали на 30 тысячах человек. К этому моменту нагрузка росла каждый день, а мы круглосуточно работали над стабилизацией сайта.
Когда на сайт обрушивается такая нагрузка, как правило, складываются приложения, сервисы, балансеры, базы, веб, каналы. Обнажаются все «бутылочные горлышки» инфраструктуры. В таких условиях тяжело диагностировать проблемы — симптоматически глючит абсолютно всё. Чинить просто, когда трафик растет плавно и ломается что-то одно. Когда же нагрузка идет шквалом, одна из больших проблем — понять причины сбоев.
Стратегия работы в таких условиях — устранять то, что бьет по сайту сильнее всего, затем находить следующую самую больную точку, одновременно искать потенциальные проблемы и исправлять их, и так далее. Вот некоторые наиболее заметные вещи, которые мы сделали, чтобы стабилизировать платформу.
Во время кризиса перед трафиком вы как команда становитесь одни. Именно от ваших сотрудников и будет зависеть, найдете ли вы решения, справитесь с кризисом, или нет.
В индустрии не существует людей, которые бы пришли, заглянули в вашу сложную систему, сходу что-то сделали и всё бы стало хорошо. Конечно, в мире есть достаточно специалистов, которые справятся с задачей при наличии времени. Но когда фундаментальное решение нужно прямо сейчас, можно рассчитывать только на свою команду, которая знает систему и ее специфику. Результат и ответственность перед бизнесом лежит на команде. Внешнюю экспертизу целесообразно подключать точечно.
Быстро сориентироваться и выстроить работу нам в том числе помогла оперативная координация антикризисной команды в специальном чате в Slack — все вопросы решали здесь и сейчас. Мы разделили зоны ответственности между сотрудниками, чтобы не возникало пересечений и ребята не делали двойной работы. В самые сложные дни приходилось быть на связи буквально круглосуточно.
Застраховаться от всех кризисов нельзя, но важно быть гибкими. Облачный стек дал нам такую пластичность и шанс оставаться на плаву даже при таком драматическом росте нагрузки.
Изначально мы увеличивали ресурсы под возросшую нагрузку, но в какой-то момент уперлись в квоты региона нашего облачного провайдера. Проблемы возникли и на его уровне: наши виртуальные сервера аффектили соседи, на которых трафик также вырос, из-за чего возникали сбои в работе наших приложений. Это было ожидаемо: мы зависим от провайдера и от его инфраструктуры, которая в свою очередь тоже испытывала высокую нагрузку. Часть ресурсов с неприоритетных виртуальных машин мы освободили для основного сайта. С провайдером мы договорились о выделенном ресурсе.
В кризис алертинг фактически перестал выполнять свою функцию. Все члены команды и так наблюдали за всеми системами круглосуточно, а инцидент-менеджмент сводился к постоянной работе по всем фронтам. Для полноценной диагностики проблем, с которыми мы столкнулись, у нас оказалось слишком мало данных. Например, для мониторинга виртуальных машин мы используем стандартный Node Exporter для Прометея. Он хорош, чтобы видеть общую картину, для более пристального изучения отдельной виртуальной машины стали использовать NetData.
Проблема возникла также и с хранилищами key-value. В одном из приложений Redis не справлялся — в единственном экземпляре он может работать только на одном ядре. Поэтому использовали форк Redis под названием KeyDB, который может работать в несколько потоков.
Чтобы повысить пропускную способность в другом приложении, мы подняли 10 независимых Redis’ов. Их проксирует наш Service Mesh, который также шардирует по ключам. Даже если один или два Redis’а выйдут из строя, это не создаст проблем из-за консистентного хеширования. Плюс их практически не нужно администрировать.
Как вы знаете, 640 Кб хватит всем. Мы всегда использовали приватные подсети /24, но на фоне карантина пришлось экстренно расширять до /22. Теперь сеть вмещает в четыре раза больше серверов, надеемся, точно будет достаточно.
В качестве реляционной базы данных мы везде используем PostgreSQL, где-то небольшие инстансы-виртуалки, а где-то — установку из нескольких больших выделенных серверов под мастер и реплики. Очевидное узкое место такой архитектуры, это мастер, который в идеальном случае используется только для записи и не масштабируется горизонтально. С ростом трафика мы начали упираться в CPU.
В то же время для управления соединениями мы используем PgBouncer, который был установлен на мастере и на каждой реплике. На одном порту он может использовать не больше одного ядра процессора, поэтому на каждом сервере у нас было по несколько баунсеров. В какой-то момент стало ясно, что сам по себе PgBouncer отнимает у базы ощутимую часть CPU, а при максимальной нагрузке мы испытывали стремительный рост load average и падение производительности системы.
Мы вынесли баунсеры на отдельный сервер, что помогло нам сэкономить 20-25% CPU на каждом сервере баз данных.
Только одному инструменту нельзя доверять, особенно в кризис. Наоборот, избыточность инструментария помогает, потому что дает возможность увидеть более объективную картину. Привычные инструменты начинают отказывать по самым разным причинам. Например, обычно для оценки количества людей на сайте мы обычно используем real-time отчет Google Analytics, это чуткая и точная метрика. Но иногда он глючит и в этот раз нам пришлось смотреть на внутренние метрики вроде количества событий просмотра страницы и количества запросов в секунду.
Для централизованного логирования используем ELK. Наш конвейер доставки логов основан на Apache Kafka и Elastic Filebeat. Под высокой нагрузкой конвейер доставки логов перестал справляться, логи стали теряться или отставать. Мы увеличили скорость передачи логов и индексации хранилища за счет манипуляций с индексами Elasticsearch, увеличения количества партиций в Kafka и Filebeat, тонко настроили сжатие на всех этапах. Благодаря тому, что пайплайн сбора логов отделен от продакшена, проблемы с возросшим трафиком логов не оказывали никакого влияния на функционирование сайта.
Невозможно подготовиться к каждому кризису заранее, но можно изначально стараться построить гибкую систему. Стартапу или компаниям, которые постепенно перестают быть стартапами, в спокойное время не всегда рационально готовиться к аномальному росту трафика: ресурсы команды ограничены. Если отвести их подготовке к тому, чего, возможно, никогда не произойдет, не останется сил на основной продукт. Гораздо важнее правильно среагировать в моменте и не бояться смелых решений. Как правило, выход их кризиса — это выход на качественно новый уровень.
Вот такая в этом году веселая весна. Когда кажется, что всё возможное сделано, порой оказывается, что это лишь начало.
Мы не ожидали таких сюрпризов и не были к ним готовы, к такому не была готова, наверное, ни одна компания в России, да и в мире. Обычно в марте активность на Учи.ру ниже относительно осени из-за весенних и приближающихся летних каникул, в это время мы уже готовимся к сентябрю: пилим фичи, делаем рефакторинг, проводим масштабные архитектурные изменения и занимаемся другой приятной рутиной. Однако в этот раз все было по-другому.
Пиковое количество уникальных пользователей на сайте единовременно достигло 240 тысяч, предыдущий максимум текущего учебного года мы фиксировали на 30 тысячах человек. К этому моменту нагрузка росла каждый день, а мы круглосуточно работали над стабилизацией сайта.
Когда на сайт обрушивается такая нагрузка, как правило, складываются приложения, сервисы, балансеры, базы, веб, каналы. Обнажаются все «бутылочные горлышки» инфраструктуры. В таких условиях тяжело диагностировать проблемы — симптоматически глючит абсолютно всё. Чинить просто, когда трафик растет плавно и ломается что-то одно. Когда же нагрузка идет шквалом, одна из больших проблем — понять причины сбоев.
Стратегия работы в таких условиях — устранять то, что бьет по сайту сильнее всего, затем находить следующую самую больную точку, одновременно искать потенциальные проблемы и исправлять их, и так далее. Вот некоторые наиболее заметные вещи, которые мы сделали, чтобы стабилизировать платформу.
Положились на себя
Во время кризиса перед трафиком вы как команда становитесь одни. Именно от ваших сотрудников и будет зависеть, найдете ли вы решения, справитесь с кризисом, или нет.
В индустрии не существует людей, которые бы пришли, заглянули в вашу сложную систему, сходу что-то сделали и всё бы стало хорошо. Конечно, в мире есть достаточно специалистов, которые справятся с задачей при наличии времени. Но когда фундаментальное решение нужно прямо сейчас, можно рассчитывать только на свою команду, которая знает систему и ее специфику. Результат и ответственность перед бизнесом лежит на команде. Внешнюю экспертизу целесообразно подключать точечно.
Быстро сориентироваться и выстроить работу нам в том числе помогла оперативная координация антикризисной команды в специальном чате в Slack — все вопросы решали здесь и сейчас. Мы разделили зоны ответственности между сотрудниками, чтобы не возникало пересечений и ребята не делали двойной работы. В самые сложные дни приходилось быть на связи буквально круглосуточно.
Расширили облако
Застраховаться от всех кризисов нельзя, но важно быть гибкими. Облачный стек дал нам такую пластичность и шанс оставаться на плаву даже при таком драматическом росте нагрузки.
Изначально мы увеличивали ресурсы под возросшую нагрузку, но в какой-то момент уперлись в квоты региона нашего облачного провайдера. Проблемы возникли и на его уровне: наши виртуальные сервера аффектили соседи, на которых трафик также вырос, из-за чего возникали сбои в работе наших приложений. Это было ожидаемо: мы зависим от провайдера и от его инфраструктуры, которая в свою очередь тоже испытывала высокую нагрузку. Часть ресурсов с неприоритетных виртуальных машин мы освободили для основного сайта. С провайдером мы договорились о выделенном ресурсе.
Модернизировали инструменты мониторинга
В кризис алертинг фактически перестал выполнять свою функцию. Все члены команды и так наблюдали за всеми системами круглосуточно, а инцидент-менеджмент сводился к постоянной работе по всем фронтам. Для полноценной диагностики проблем, с которыми мы столкнулись, у нас оказалось слишком мало данных. Например, для мониторинга виртуальных машин мы используем стандартный Node Exporter для Прометея. Он хорош, чтобы видеть общую картину, для более пристального изучения отдельной виртуальной машины стали использовать NetData.
Оптимизировали кеш-хранилища
Проблема возникла также и с хранилищами key-value. В одном из приложений Redis не справлялся — в единственном экземпляре он может работать только на одном ядре. Поэтому использовали форк Redis под названием KeyDB, который может работать в несколько потоков.
Чтобы повысить пропускную способность в другом приложении, мы подняли 10 независимых Redis’ов. Их проксирует наш Service Mesh, который также шардирует по ключам. Даже если один или два Redis’а выйдут из строя, это не создаст проблем из-за консистентного хеширования. Плюс их практически не нужно администрировать.
Расширили сеть
Как вы знаете, 640 Кб хватит всем. Мы всегда использовали приватные подсети /24, но на фоне карантина пришлось экстренно расширять до /22. Теперь сеть вмещает в четыре раза больше серверов, надеемся, точно будет достаточно.
Вынесли PgBouncer отдельно
В качестве реляционной базы данных мы везде используем PostgreSQL, где-то небольшие инстансы-виртуалки, а где-то — установку из нескольких больших выделенных серверов под мастер и реплики. Очевидное узкое место такой архитектуры, это мастер, который в идеальном случае используется только для записи и не масштабируется горизонтально. С ростом трафика мы начали упираться в CPU.
В то же время для управления соединениями мы используем PgBouncer, который был установлен на мастере и на каждой реплике. На одном порту он может использовать не больше одного ядра процессора, поэтому на каждом сервере у нас было по несколько баунсеров. В какой-то момент стало ясно, что сам по себе PgBouncer отнимает у базы ощутимую часть CPU, а при максимальной нагрузке мы испытывали стремительный рост load average и падение производительности системы.
Мы вынесли баунсеры на отдельный сервер, что помогло нам сэкономить 20-25% CPU на каждом сервере баз данных.
Столкнулись с сюрпризами
Только одному инструменту нельзя доверять, особенно в кризис. Наоборот, избыточность инструментария помогает, потому что дает возможность увидеть более объективную картину. Привычные инструменты начинают отказывать по самым разным причинам. Например, обычно для оценки количества людей на сайте мы обычно используем real-time отчет Google Analytics, это чуткая и точная метрика. Но иногда он глючит и в этот раз нам пришлось смотреть на внутренние метрики вроде количества событий просмотра страницы и количества запросов в секунду.
Для централизованного логирования используем ELK. Наш конвейер доставки логов основан на Apache Kafka и Elastic Filebeat. Под высокой нагрузкой конвейер доставки логов перестал справляться, логи стали теряться или отставать. Мы увеличили скорость передачи логов и индексации хранилища за счет манипуляций с индексами Elasticsearch, увеличения количества партиций в Kafka и Filebeat, тонко настроили сжатие на всех этапах. Благодаря тому, что пайплайн сбора логов отделен от продакшена, проблемы с возросшим трафиком логов не оказывали никакого влияния на функционирование сайта.
Приняли правила игры
Невозможно подготовиться к каждому кризису заранее, но можно изначально стараться построить гибкую систему. Стартапу или компаниям, которые постепенно перестают быть стартапами, в спокойное время не всегда рационально готовиться к аномальному росту трафика: ресурсы команды ограничены. Если отвести их подготовке к тому, чего, возможно, никогда не произойдет, не останется сил на основной продукт. Гораздо важнее правильно среагировать в моменте и не бояться смелых решений. Как правило, выход их кризиса — это выход на качественно новый уровень.
Вот такая в этом году веселая весна. Когда кажется, что всё возможное сделано, порой оказывается, что это лишь начало.