Жизнь проекта на
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 1
ip sla schedule 1 life forever start-time now
track 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 now
track 2 ip sla 2 reachability
mls ip cef load-sharing full
ip route 1.1.1.100 255.255.255.255 1.1.1.10 track 1
ip 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

Жизнь проекта на production советы по эксплуатации / Николай Сивко (okmeter.io)

  • 1.
  • 2.
    Постановка задачи • Унас есть сайт, он приносит нам деньги • Если он не работает — мы несем убытки • У нас есть небольшой бюджет на отказоустойчивость + мозг
  • 3.
    Всему есть предел •Датацентры: • Tier I: 99.671% (142 минуты в месяц) • Tier II: 99.749% (~109 минут в месяц) • Tier III: 99.982% (~8 минут в месяц) • Tier IV: 99.995% (~2 минуты в месяц) • Допустим, мы стоим в TIER III и закладываться на падение ДЦ пока не будем
  • 4.
    Реальность • Найти ДЦ“без единого разрыва” не сильно сложно • А железо ломается постоянно • Софт — тем более • Свой софт — ещё чаще
  • 5.
    Дано • У насесть сервер за 20000р/месяц • На нем: • Nginx (фронтенд) • Наше приложение (бэкенд) • Memcached • База данных • Очередь задач • Наши обработчики задач из очереди
  • 6.
    Алгоритм • Выписываем возможныепроблемы • Какие-то закрываем полностью • Какие-то — частично
  • 7.
  • 8.
    Фронтенд • Принимает запросы •Обслуживает “медленных” клиентов • Отдает статику: js/css/img • URL rewrites • Терминация TLS (https) • Проксирует запросы на бэкенды • Кэш
  • 9.
    Фронтенд: что можетпроизойти • Сломалась железка • Умер сервис (crash, oom killer, всякое бывает) • Тупит сервер, сайт тормозит
  • 10.
    Фронтенд: балансировка • Обычноfrontend – stateless, можем поставить несколько (защитимся от вылета железа + некоторых софтовых проблем) • Нужно обеспечить отказоустойчивость, масштабируемость • Как правило, уровень выше – не наша зона ответственности
  • 11.
    Фронтенд: балансировка • DNSround robin: не знает, работает ли конкретный сервер • Shared IP: VRRP, CARP (active + N passive, нужно отдельно дорабатывать переключение при проблемах с сервисами) • DNS round robin между shared ips
  • 12.
    Фронтенд: балансировка Если естьL3 железка перед фронтендами: • Cisco: равнозначные статические маршруты + IP SLA check • Juniper: равнозначные статические маршруты + BFDd + monit
  • 13.
    Фронтенд: балансировка ip sla1 tcp-connect 1.1.1.10 80 source-ip 1.1.1.1 control disable timeout 900 threshold 1000 tag front1 frequency 1 ip sla schedule 1 life forever start-time now track 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 now track 2 ip sla 2 reachability mls ip cef load-sharing full ip route 1.1.1.100 255.255.255.255 1.1.1.10 track 1 ip route 1.1.1.100 255.255.255.255 1.1.1.20 track 2
  • 14.
    Фронтенд: мониторинг • Количествозапросов • Количество ошибок (http-5xx, http-4xx) • Время ответа на запросы (гистограмма)
  • 15.
  • 16.
    Фронтенд: мониторинг • Critical:http-5xx > N в секунду • Critical: медленных запросов (> 1s) > M % N, M на ваш вкус, обычно для сайта с 200+ RPS: • N = 10 RPS • M = 5 %
  • 17.
    Фронтенд: что можетпроизойти • Сломалась железка • Умер сервис (crash, oom killer, всякое бывает) • Тупит сервер, сайт тормозит – мониторинг
  • 18.
    Бэкенд • Получает данныеиз БД, других сервисов • Производит вычисления над данными (шаблонизация, ...) • Отдает пользователю ответ
  • 19.
    Бэкенд: что можетпроизойти • Сломалась железка • Умер сервис (crash, oom killer, всякое бывает) • Проблемы с БД (совсем умерло, тупит, ошибки) • Проблемы с другими внешними ресурсами • Тормоза из-за нехватки ресурсов, кривого кода • Тормоза из-за бОльшего количества запросов
  • 20.
    Бэкенд • Не хранимна бэкенде данные, иначе сложная балансировка, проблемы при отказе (сессии на локальном диске, и т.д.) • Ставим несколько железок, балансировка на фронтенде
  • 21.
    Бэкенд • Выясняем, сколькозапросов одновременно бэкенд может обслужить, больше не берем (HTTP-503) • Фронтенд может в этом случае отправить запрос соседу • Определяемся со временем ответа, ставим правильные таймауты на фронтенде
  • 22.
    Бэкенд: балансировка • proxy_connect_timeout10ms; #для локалки • 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
  • 23.
    Бэкенд: мониторинг • Живостьсервиса (есть процесс, listen socket, отвечает на /status) • Потребление ресурсов процессом (cpu, mem, swap io, disk io, open fd) • Runtime специфичные метрики (GC, heap, размер кэшей, …)
  • 24.
    Бэкенд: мониторинг • Количествопринятых и обработанных запросов (лог, statsd) • Количество ошибок (можно снимать на фронтенде) • Время ответа (лог, statsd, можно снимать на фронтенде) • Работа с БД или сервисами (количество запросов, ошибок, время ответа) • Время, потраченное на вычисления
  • 25.
  • 26.
  • 27.
    Бэкенд: что можетпроизойти • Сломалась железка • Умер сервис (crash, oom killer, всякое бывает) • Проблемы с БД (совсем умерло, тупит, ошибки) - мониторинг • Проблемы с другими внешними ресурсами - мониторинг • Тормоза из-за нехватки ресурсов, кривого кода - мониторинг • Тормоза из-за бОльшего количества запросов
  • 28.
    БД • Хранит данные •Отвечает на запросы к данным OLTP + OLAP
  • 29.
    БД: что можетпроизойти • Сломалась железка • Потеря данных из-за железа, DELETE, … • Умер сервис (crash, oom killer, всякое бывает) • Тормоза из-за нехватки ресурсов • Тормоза из-за бОльшего количества запросов • Тормоза из-за кривых запросов (нет нужного индекса, …)
  • 30.
    БД: master-slave • Настраиваемрепликацию на другой сервер • Основная нагрузка большинства проектов – чтение, можно работать в read-only режиме при отказе мастера
  • 31.
    БД: master-slave • Нареплику можем отправить все SELECTы, которые не чувствительны к replication lag • Для таких запросов можно приложению дать отдельный endpoint – балансировщик, который распределит соединения между master и репликами (TCP) • Или научить приложение работать с несколькими серверами сразу – сможете контролировать таймауты, делать retry на другой сервер в случае проблем
  • 32.
    БД: переключение мастера •Принимаем решение о переключении (может, быстрее починить сервер?) • Переключаем запись на реплику (будут ошибки) • Если нужно, ждем, пока долетят изменения • Добиваем текущий мастер • Перенастраиваем slave->master • Если есть ещё реплики, переключаем их на новый master
  • 33.
    БД: переключение мастера •Переключаться на автомате сложно и стрёмно • Лучше минимизировать риски и взять под мастер БД более надежное железо (raid, БП и т.д.) • Пишем инструкцию, как переключить мастер (по шагам, с хорошей детализацией, чтобы включать мозг по минимуму) • Устраиваем учения и тестируем инструкцию, замеряем время простоя • Дополняем и уточняем инструкцию, пытаемся сократить время простоя • Тестируем снова
  • 34.
    БД: репликация !=бэкап • “DELETE from table” – убьет данные на реплике тоже • Регулярно делаем бэкап + копируем WAL • Можно держать реплику, специально отстающую на N минут (чтобы быстро отключить репликацию и успеть спасти данные) • Бэкап лучше копировать в другой ДЦ тоже
  • 35.
    БД: мониторинг • Живостьсервиса (есть процесс, listen socket) • Потребление ресурсов процессом (cpu, mem, swap io, disk io, open fd) • Какие запросы занимают CPU • Какие запросы нагружают диски • Отставание репликации, трафик репликации • Поток запросов (больше, меньше, как обычно) • Мониторинг наличия бэкапа
  • 36.
  • 37.
  • 38.
    БД: что можетпроизойти • Сломалась железка • Потеря данных из-за железа, DELETE, … мониторинг + инструкция по ручному вмешательству • Умер сервис (crash, oom killer, всякое бывает) • Тормоза из-за нехватки ресурсов - мониторинг • Тормоза из-за бОльшего количества запросов - мониторинг • Тормоза из-за кривых запросов (нет нужного индекса, …) - мониторинг
  • 39.
    Memcached • Распределенный кэшв памяти • Общий доступ по сети
  • 40.
    Memcached: что можетпроизойти • Сломалась железка • Умер сервис (crash, oom killer, всякое бывает) • Тормозит сеть • Тормоза из-за нехватки ресурсов
  • 41.
    Memcached • Ставим несколько •Клиенты умеют ходить сразу во все (шардинг) • Обязательно настраиваем таймауты • Проверяем логику инвалидации (expire все равно ставим)
  • 42.
    Memcached • Выдержит лиБД, если почистить все кэши? • А должна • Сколько нужно прогретых кэшей, чтобы сайт работал? • Проверяем, как клиент будет перераспределять данные и запросы (решардинг), чтобы вылет 1 сервера не испортил нам все • Эффективен ли кэш? • Может, его выкинуть?
  • 43.
  • 44.
    Memcached: что можетпроизойти • Сломалась железка • Умер сервис (crash, oom killer, всякое бывает) • Тормозит сеть – мониторинг на стороне бэкенда • Тормоза из-за нехватки ресурсов – мониторинг
  • 45.
    Message Queue • Хранитзадачи для отложенной обработки • Publisher – записывает сообщение в очередь • Consumer – получает сообщения и выполняет работу
  • 46.
    Message Queue: чтоможет произойти • Сломалась железка • Потеря данных (умерла железка с необработанной очередью) • Умер сервис (crash, oom killer, всякое бывает) • Умерли все обработчики (копятся сообщения) • Тормоза из-за нехватки ресурсов
  • 47.
    Message Queue • Некоторыеброкеры заявляют о кластерном режиме работы (мне не очень нравится, много вопросов) • Можно поставить несколько брокеров: писать в любой живой, обработчики должны выбирать сообщения из всех • Обязательно настраиваем таймауты
  • 48.
    Message Queue: оченьважные сообщения • Пишем одно и то же сообщение в несколько брокеров, убираем дубли на уровне обработчиков • Или имеем механизм проверки целостности и восстановления состояния по другим источникам (БД)
  • 49.
    Message Queue: мониторинг •Потребление ресурсов • Размеры очередей • Скорость приема/доставки сообщений
  • 50.
  • 51.
  • 52.
    Message Queue: чтоможет произойти • Сломалась железка • Потеря данных (умерла железка с необработанной очередью) • Умер сервис (crash, oom killer, всякое бывает) • Умерли все обработчики (копятся сообщения) - мониторинг • Тормоза из-за нехватки ресурсов - мониторинг
  • 53.
    Цена вопроса • Началис 1 dedicated сервера за 20тр/месяц • Минимум: ставим еще один такой же (40тр) • Норма: 2+ БД отдельно на хорошем железе, все остальное размазано по 2+ серверам
  • 54.
    А что в“облаках”? • Есть возможность поднять новую машину за N минут + API • Есть готовые балансировщики • Есть готовые MQ сервисы • Ресурсы дороже • Можно нарваться на latency (сеть, диск), недополучить ресурсов (cpu) • Готовые сервисы – черные ящики для вас
  • 55.
    Резервный ДЦ • Данные(репликация) • Актуальная конфигурация ПО • Актуальные версии вашего софта • План переключения трафика в резервный ДЦ: • DNS (помним про ttl) • PI адреса + BGP
  • 56.
    Самое главное • Составьтесписок возможных отказов • Исключайте (закрывайте) простые • Если сценарий сложный: • уменьшаем вероятность • закрываем часть • мониторинг + план на ручное вмешательство • Главное – иметь план действий, всё остальное — оптимизация
  • 57.