Работа на реальном IT проекте не всегда происходит оптимально - порой, некоторые допущения, генерирующие излишнюю нагрузку на базу данных, сеть, или другие ресурсы работают достаточно длительное время, до того как до их оптимизации дойдут руки. Одна из причин оптимизации - это стоимость инфраструктуры.
Перед нашей DevOps командой была поставлена задача мониторить стоимость облачной инфраструктуры, и следить за оптимальным балансом, между производительностью и стоимостью.
Перед одним из важных релизов, в котором ожидался прилив новых пользователей, мы активно увеличивали выделенные ресурсы, поднимали реплики баз данных для “тяжелых” запросов, что увеличило стоимость инфраструктуры до 10k$ в месяц.
Поэтому решено было исследовать причины и оптимизировать стоимость.
Первым шагом, мы выделили основные сервисы в GCP, которые составляют существенную часть счета:
- Networking — это обозначение содержит в себе CDN, Cloud Armor, LB и прочие сервисы, которые необходимы для работы сети в GCP.
- Cloud DB —- сервис баз данных, сюда же относится и плата за ресурсы, выделяемые для базы (диск, ram, cpu).
- K8S engine — сервис который объединяет в себе всё необходимое для работы с облачным кластером k8s.
- Logging — сервис сбора логов, отправки уведомлений, создания и просмотра графиков
По каждому из этих 4 направлений, мы предприняли следующие действия:
NetworkingТе, кто работают с облаками знают, что сеть — это то, что может довольно легко опустошить баланс. В нашем случае после релиза большой фичи исходящий трафик стал очень быстро расти вверх. Это стало первым звоночком к исследованию проблемы и последующей оптимизации расходов.
Основной причиной выросшей стоимости трафика оказалась новая функциональность больших live-конференций, которая была реализована и выпущена в продакшн. Она была реализована через протокол http, а не Web Socket, и генерировало большое количество запросов, что в итоге отражалось на стоимость сети и счете за инфраструктуру вцелом.
Cloud DBВ этой части всё довольно просто. Мы проанализировали запросы в базу данных и передали разработке список неоптимальных запросов. Сделанный рефакторинг помог существенно снизить нагрузку на БД, отказаться от использования реплик, и уменьшить количество используемых ресурсов.
K8S engineМы провели анализ профиля нагрузки и подобрали самые оптимальные, на данный момент, по стоимости и производительности типы нод и заменили ими неоптимальные по конфигурации ноды. Дополнительно мы проверили запросы и лимиты у приложений, сравнили с накопленной статистикой, тем самым оптимизировав распределение подов.
LoggingК продукту за одну минуту может быть сделано более 20000 запросов, и каждый запрос порождал от одной до двадцати записей в лог, и все они хранились для отладки и поиска ошибок. Внутри подов, разработчики также выводили лог http-запросов, которые не отличались ничем от тех, что собирались из LB. Обсудив с разработчиками, мы отключили логи, которые собирались из подов, так как хранить дубликаты не имеет смысла.
Дополнительную экономию мы получили за счет настройки фильтрации принимаемых записей и настройки сэмплирования - это позволяет фиксировать только уникальные логи, а бОльшую часть не уникальных, а зачастую мусорных, просто не сохранять, и как следствие, не хранить. В нашем случае, мы таким образом отсеяли 90% таких логов, и, как показала практика, это не повлияло на возможность отладки.
Последнее, что мы настроили после обсуждения с разработчиками — это глубину хранения логов. До того как мы начали оптимизировать расходы, логи хранились на протяжении 14 дней. Мы сократили это значение до 7 дней.
Эти изменения позволили нам существенно уменьшить стоимость облачной инфраструктуры - стоимость уменьшили с 10k$ до 6k$ без потери в производительности и отказоустойчивости. Также, точки контроля стоимости инфраструктуры запланированы и регулярно проводятся не реже чем 1 раз в месяц.