Жизнь проекта на production советы по эксплуатации /...

Preview:

Citation preview

Жизнь проекта на productionНиколай Сивко

Постановка задачи• У нас есть сайт, он приносит нам деньги• Если он не работает — мы несем убытки• У нас есть небольшой бюджет на отказоустойчивость + мозг

Всему есть предел• Датацентры: • Tier I: 99.671% (142 минуты в месяц)• Tier II: 99.749% (~109 минут в месяц)• Tier III: 99.982% (~8 минут в месяц)• Tier IV: 99.995% (~2 минуты в месяц)

• Допустим, мы стоим в TIER III и закладываться на падение ДЦ пока не будем

Реальность• Найти ДЦ “без единого разрыва” не сильно сложно• А железо ломается постоянно• Софт — тем более• Свой софт — ещё чаще

Дано• У нас есть сервер за 20000р/месяц• На нем: • Nginx (фронтенд)• Наше приложение (бэкенд)• Memcached • База данных• Очередь задач• Наши обработчики задач из очереди

Алгоритм• Выписываем возможные проблемы• Какие-то закрываем полностью• Какие-то — частично

Стандартная архитектура простого проекта

Фронтенд• Принимает запросы• Обслуживает “медленных” клиентов• Отдает статику: js/css/img• URL rewrites• Терминация TLS (https)• Проксирует запросы на бэкенды• Кэш

Фронтенд: что может произойти• Сломалась железка• Умер сервис (crash, oom killer, всякое бывает)• Тупит сервер, сайт тормозит

Фронтенд: балансировка• Обычно frontend – stateless, можем поставить несколько

(защитимся от вылета железа + некоторых софтовых проблем)

• Нужно обеспечить отказоустойчивость, масштабируемость

• Как правило, уровень выше – не наша зона ответственности

Фронтенд: балансировка• DNS round robin: не знает, работает ли конкретный сервер

• Shared IP: VRRP, CARP (active + N passive, нужно отдельно дорабатывать переключение при проблемах с сервисами)

• DNS round robin между shared ips

Фронтенд: балансировкаЕсли есть L3 железка перед фронтендами:

• Cisco: равнозначные статические маршруты + IP SLA check

• Juniper: равнозначные статические маршруты + BFDd + monit

Фронтенд: балансировка

ip sla 1 tcp-connect 1.1.1.10 80 source-ip 1.1.1.1 control disable timeout 900 threshold 1000 tag front1 frequency 1ip sla schedule 1 life forever start-time nowtrack 1 ip sla 1 reachability

ip sla 2 tcp-connect 1.1.1.20 80 source-ip 1.1.1.1 control disable timeout 900 threshold 1000 tag front2 frequency 1 ip sla schedule 2 life forever start-time nowtrack 2 ip sla 2 reachability

mls ip cef load-sharing fullip route 1.1.1.100 255.255.255.255 1.1.1.10 track 1ip route 1.1.1.100 255.255.255.255 1.1.1.20 track 2

Фронтенд: мониторинг• Количество запросов• Количество ошибок (http-5xx, http-4xx)• Время ответа на запросы (гистограмма)

Фронтенд: мониторинг

Фронтенд: мониторинг

• Critical: http-5xx > N в секунду• Critical: медленных запросов (> 1s) > M %

N, M на ваш вкус, обычно для сайта с 200+ RPS:• N = 10 RPS• M = 5 %

Фронтенд: что может произойти• Сломалась железка• Умер сервис (crash, oom killer, всякое бывает)• Тупит сервер, сайт тормозит – мониторинг

Бэкенд• Получает данные из БД, других сервисов• Производит вычисления над данными (шаблонизация, ...)• Отдает пользователю ответ

Бэкенд: что может произойти• Сломалась железка• Умер сервис (crash, oom killer, всякое бывает)• Проблемы с БД (совсем умерло, тупит, ошибки)• Проблемы с другими внешними ресурсами• Тормоза из-за нехватки ресурсов, кривого кода• Тормоза из-за бОльшего количества запросов

Бэкенд• Не храним на бэкенде данные, иначе сложная балансировка,

проблемы при отказе (сессии на локальном диске, и т.д.)• Ставим несколько железок, балансировка на фронтенде

Бэкенд• Выясняем, сколько запросов одновременно бэкенд может

обслужить, больше не берем (HTTP-503)• Фронтенд может в этом случае отправить запрос соседу• Определяемся со временем ответа, ставим правильные

таймауты на фронтенде

Бэкенд: балансировка• proxy_connect_timeout 10ms; #для локалки• proxy_read_timeout 500ms; #настраиваем под себя• proxy_next_upstream error timeout invalid_header http_502

http_503 http_504;• proxy_next_upstream_tries 2;

* Nginx 1.9.13+ не будет ретраить POST

Бэкенд: мониторинг• Живость сервиса (есть процесс, listen socket, отвечает на /status)• Потребление ресурсов процессом (cpu, mem, swap io, disk io, open

fd)• Runtime специфичные метрики (GC, heap, размер кэшей, …)

Бэкенд: мониторинг• Количество принятых и обработанных запросов (лог, statsd)• Количество ошибок (можно снимать на фронтенде)• Время ответа (лог, statsd, можно снимать на фронтенде)• Работа с БД или сервисами (количество запросов, ошибок,

время ответа)• Время, потраченное на вычисления

Бэкенд: потребление cpu

Бэкенд: стадии бизнес логики

Бэкенд: что может произойти• Сломалась железка• Умер сервис (crash, oom killer, всякое бывает)• Проблемы с БД (совсем умерло, тупит, ошибки) - мониторинг• Проблемы с другими внешними ресурсами - мониторинг• Тормоза из-за нехватки ресурсов, кривого кода - мониторинг• Тормоза из-за бОльшего количества запросов

БД• Хранит данные• Отвечает на запросы к данным OLTP + OLAP

БД: что может произойти• Сломалась железка• Потеря данных из-за железа, DELETE, …• Умер сервис (crash, oom killer, всякое бывает)• Тормоза из-за нехватки ресурсов• Тормоза из-за бОльшего количества запросов• Тормоза из-за кривых запросов (нет нужного индекса, …)

БД: master-slave• Настраиваем репликацию на другой сервер• Основная нагрузка большинства проектов – чтение, можно

работать в read-only режиме при отказе мастера

БД: master-slave• На реплику можем отправить все SELECTы, которые не

чувствительны к replication lag• Для таких запросов можно приложению дать отдельный endpoint

– балансировщик, который распределит соединения между master и репликами (TCP)• Или научить приложение работать с несколькими серверами

сразу – сможете контролировать таймауты, делать retry на другой сервер в случае проблем

БД: переключение мастера• Принимаем решение о переключении (может, быстрее починить

сервер?)• Переключаем запись на реплику (будут ошибки)• Если нужно, ждем, пока долетят изменения• Добиваем текущий мастер• Перенастраиваем slave->master• Если есть ещё реплики, переключаем их на новый master

БД: переключение мастера• Переключаться на автомате сложно и стрёмно• Лучше минимизировать риски и взять под мастер БД более надежное

железо (raid, БП и т.д.)• Пишем инструкцию, как переключить мастер (по шагам, с хорошей

детализацией, чтобы включать мозг по минимуму)• Устраиваем учения и тестируем инструкцию, замеряем время

простоя• Дополняем и уточняем инструкцию, пытаемся сократить время

простоя• Тестируем снова

БД: репликация != бэкап• “DELETE from table” – убьет данные на реплике тоже• Регулярно делаем бэкап + копируем WAL• Можно держать реплику, специально отстающую на N минут

(чтобы быстро отключить репликацию и успеть спасти данные)• Бэкап лучше копировать в другой ДЦ тоже

БД: мониторинг• Живость сервиса (есть процесс, listen socket)• Потребление ресурсов процессом (cpu, mem, swap io, disk io, open

fd)• Какие запросы занимают CPU• Какие запросы нагружают диски• Отставание репликации, трафик репликации• Поток запросов (больше, меньше, как обычно)• Мониторинг наличия бэкапа

БД: мониторинг запросов

БД: мониторинг репликации

БД: что может произойти• Сломалась железка• Потеря данных из-за железа, DELETE, … мониторинг + инструкция

по ручному вмешательству• Умер сервис (crash, oom killer, всякое бывает)• Тормоза из-за нехватки ресурсов - мониторинг• Тормоза из-за бОльшего количества запросов - мониторинг• Тормоза из-за кривых запросов (нет нужного индекса, …) -

мониторинг

Memcached• Распределенный кэш в памяти• Общий доступ по сети

Memcached: что может произойти• Сломалась железка• Умер сервис (crash, oom killer, всякое бывает)• Тормозит сеть• Тормоза из-за нехватки ресурсов

Memcached• Ставим несколько• Клиенты умеют ходить сразу во все (шардинг)• Обязательно настраиваем таймауты• Проверяем логику инвалидации (expire все равно ставим)

Memcached• Выдержит ли БД, если почистить все кэши?• А должна• Сколько нужно прогретых кэшей, чтобы сайт работал?• Проверяем, как клиент будет перераспределять данные и

запросы (решардинг), чтобы вылет 1 сервера не испортил нам все• Эффективен ли кэш?• Может, его выкинуть?

Memcached: мониторинг

Memcached: что может произойти• Сломалась железка• Умер сервис (crash, oom killer, всякое бывает)• Тормозит сеть – мониторинг на стороне бэкенда• Тормоза из-за нехватки ресурсов – мониторинг

Message Queue• Хранит задачи для отложенной обработки• Publisher – записывает сообщение в очередь• Consumer – получает сообщения и выполняет работу

Message Queue: что может произойти• Сломалась железка• Потеря данных (умерла железка с необработанной очередью)• Умер сервис (crash, oom killer, всякое бывает)• Умерли все обработчики (копятся сообщения)• Тормоза из-за нехватки ресурсов

Message Queue• Некоторые брокеры заявляют о кластерном режиме работы (мне

не очень нравится, много вопросов)• Можно поставить несколько брокеров: писать в любой живой,

обработчики должны выбирать сообщения из всех• Обязательно настраиваем таймауты

Message Queue: очень важные сообщения• Пишем одно и то же сообщение в несколько брокеров, убираем

дубли на уровне обработчиков

• Или имеем механизм проверки целостности и восстановления состояния по другим источникам (БД)

Message Queue: мониторинг• Потребление ресурсов• Размеры очередей• Скорость приема/доставки сообщений

Message Queue: мониторинг

Message Queue: мониторинг

Message Queue: что может произойти• Сломалась железка• Потеря данных (умерла железка с необработанной очередью)• Умер сервис (crash, oom killer, всякое бывает)• Умерли все обработчики (копятся сообщения) - мониторинг• Тормоза из-за нехватки ресурсов - мониторинг

Цена вопроса• Начали с 1 dedicated сервера за 20тр/месяц

• Минимум: ставим еще один такой же (40тр)

• Норма: 2+ БД отдельно на хорошем железе, все остальное размазано по 2+ серверам

А что в “облаках”?• Есть возможность поднять новую машину за N минут + API• Есть готовые балансировщики• Есть готовые MQ сервисы

• Ресурсы дороже• Можно нарваться на latency (сеть, диск), недополучить ресурсов

(cpu)• Готовые сервисы – черные ящики для вас

Резервный ДЦ• Данные (репликация)• Актуальная конфигурация ПО• Актуальные версии вашего софта• План переключения трафика в резервный ДЦ:• DNS (помним про ttl)• PI адреса + BGP

Самое главное• Составьте список возможных отказов• Исключайте (закрывайте) простые• Если сценарий сложный:• уменьшаем вероятность• закрываем часть• мониторинг + план на ручное вмешательство

• Главное – иметь план действий, всё остальное — оптимизация

Спасибо за внимание!

Вопросы?

Николай Сивкоnsv@okmeter.io