Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Большой веб-проект:
  развитие, рост, проблемы, решения с точки зрения

  отдела эксплуатации


Александр Чистяков
Системный администратор
КупиКупон

http://www.kupikupon.ru
http://www.slideshare.net/alexclear
chistyakov@kupikupon.ru
Давайте познакомимся
Я:
✔
     Очень долго писал код
✔
     Пока не понял, что так я только увеличиваю
     энтропию
✔
     Не пишу свой код, а читаю и исправляю чужой
✔
     Строю инфраструктуры и управляю ими
✔
     Консультирую по разным вопросам
     (“мышки, станьте ежиками!”)



Александр Чистяков                             2/51
Давайте познакомимся
Вы:
✔
    Разрабатываете веб-приложения?
✔
    Работаете с базами данных?
✔
    Занимаетесь эксплуатацией веб-проектов?
✔
    Проектируете архитектуру приложений?
✔
    Живете в Сибири
    (кстати, я первый раз в жизни забрался на
    Восток дальше Казахстана)



Александр Чистяков                              3/51
Цели моего нахождения здесь

✔
    Осуществить обмен опытом:
     ✔
       Обрисовать ситуацию в статике и динамике
     ✔
         Рассказать о достижениях
     ✔
         Предостеречь от ошибок
✔
    Зачекиниться
✔
    Попробовать местное пиво
✔
    Обратить вас в свою веру



Александр Чистяков                           4/51
Отказ от ответственности

✔
    Мое мнение – это только мое мнение:
     ✔
       Не является официальной позицией моего
       работодателя
     ✔
         Не может быть применено при работе на
         ядерных и медицинских объектах
     ✔
         Вообще не может приниматься в расчет,
         пока вы самостоятельно не проведете
         эксперимент



Александр Чистяков                               5/51
Суть проекта
✔
    Купонный сервис, top 20 списка Forbes
✔
    Какие задачи должен решать?
     ✔
       Рассылать большое количество почты
     ✔
         Предоставлять пользователям сайт, где
         можно регистрироваться и покупать
     ✔
         Предоставлять партнерам возможность
         регистрироваться и управлять процессом
     ✔
         Предоставлять менеджерам возможность
         создавать аналитические отчеты


Александр Чистяков                                6/51
С чего все начиналось
✔
    Проект на LAMP:
     ✔
       MySQL 5.0.95 (!)
     ✔
         Drupal
✔
    Хостинг:
     ✔
       OpenVZ контейнер размером во весь хост
     ✔
         Доступа к хост-машине нет
     ✔
         Установлена cPanel (!!!)
✔
    Нагрузка - ~20 RPS к бэкенду



Александр Чистяков                              7/51
Что в проекте делал я
✔
    Год и семь месяцев назад зашел рассказать
    про мышек и ежиков
✔
    Да так и остался
✔
    Настраивал, мониторил, чинил, деплоил,
    документировал, собеседовал, консультировал
✔
    То есть, в составе отдела эксплуатации
    выполнял обычные для отдела эксплуатации
    задачи




Александр Чистяков                           8/51
Один переезд и два пожара
✔
    Проект переехал с PHP на Ruby почти год назад
✔
    Вопрос из зала: “Зачем?”
✔
    Неужели PHP настолько хуже Ruby?
✔
    ^ Я этого не говорил
✔
    Разговор про “лучше” и “хуже” возможен,
    только если есть какие-то метрики
✔
    Какие же тут могут быть метрики?




Александр Чистяков                             9/51
Как делаются веб-проекты
✔
    Один из десяти веб-проектов выживает и
    становится крупным
✔
    А, может, даже из двадцати
✔
    Мы имеем дело со случайным событием
✔
    Чудо: команда энтузиастов, какой-то движок и
    вполне реальная база пользователей
✔
    Я только что описал хаос
✔
    Управление хаосом возможно, но сильно
    сокращает жизнь и ведет к неврозам


Александр Чистяков                            10/51
Хаос (он же “Drupal”)
✔
    Проекту жизненно
    необходим
    постоянный
    прогнозируемый
    прирост новой
    функциональности,
    но:
     ✔
         см. картинку,
     ✔
         команда также
         должна расширяться
                              картинка взята с
                              http://habrahabr.ru/post/144857




Александр Чистяков                                              11/51
Что дает Ruby/RoR?
✔
    Фреймворк, а не “CMS”:
     ✔
       Сделано разработчиками для разработчиков
     ✔
         Best practices действительно хороши
     ✔
         Высокая расширяемость
✔
    Ruby это тренд
✔
    Ruby-разработчик: MB Pro, Converse, Github,
    Travis-CI, zsh
✔
    PHP-разработчик: угадать невозможно



Александр Чистяков                                12/51
Эксплуатационные проблемы
✔
    Drupal не справляется с нагрузкой, так как:
     ✔
       MySQL не справляется с нагрузкой
     ✔
         Apache/PHP не справляется с нагрузкой
✔
    Включение кэша Drupal не спасло:
     ✔
       Отвалился геотаргетинг (все
       незалогиненные видят одно и то же)
     ✔
         Совсем отвалился геотаргетинг (выбор
         города вручную в меню не помогает)



Александр Чистяков                                13/51
Первые принятые меры - 1
✔
    Apache/PHP:
     ✔
       Выкинули suPHP – избавились от форков
     ✔
         (Почти) выкинули cPanel (инвазивнейший
         монстр, внедрившийся по всей системе)
✔
    MySQL:
     ✔
       Убрали MyISAM – перестали блокировать
       базу при дампе
     ✔
         Размер буфера, размер биинлога и другие
         обычные действия (см. доклад Аксенова)


Александр Чистяков                                14/51
Первые принятые меры - 2
✔
    MySQL:
     ✔
       Включили query cache (зло, но меньшее)
     ✔
         slow log, mk-log-parser и индексы, где нужно
✔
    Платформа:
     ✔
       etckeeper (спасал нас впоследствии)
     ✔
         Приведение в порядок конфигов cron и
         других сервисов
     ✔
         Без доступа к хост-машине не настроить FS,
         swappiness, I/O priority, etc


Александр Чистяков                                 15/51
Первые результаты
✔
    Удалось избавиться от кэша Drupal
✔
    Нагрузка на машину существенно снизилась
✔
    Когда через пару месяцев трафик на сайте
    возрос в два раза, это не вызвало никаких
    срочных проблем




Александр Чистяков                              16/51
Тем временем, Ruby-версия
✔
    Платформа:
     ✔
       RHEL 5.5
     ✔
         Ruby 1.8.7 (REE), Rails 3
     ✔
         MySQL заменили на PostgreSQL
         ✔
             ^ Единственное с моей точки зрения
             преимущество для подобных проектов –
             наличие online ALTER, да и то не при
             любых условиях (при добавлении столбца
             с дефолтным значением все равно будет
             блокировка таблицы)

Александр Чистяков                              17/51
Ruby-версия, железо
✔
    Dell R710, 24 или 48 Gb, SAS-диски
✔
    HW RAID контроллеры с BBU
✔
    Production конфигурация:
     ✔
       Один сервер для БД
     ✔
         Один сервер для RoR
     ✔
         Сервер для бэкапа
     ✔
         Сервера для статики, телефонии,
         разработки – не Dell и параметры скромнее
✔
    Как видите, железо было взято с запасом

Александр Чистяков                              18/51
Ruby-версия, компоненты
✔
    RVM (да, и в продакшне тоже)
✔
    Unicorn
✔
    god для управления Unicorn'ами (not anymore)
✔
    Периодические задачи – cron+rake
✔
    Обработчики очередей
✔
    Resque как сервер очередей
✔
    god для управления обработчиками (сейчас
    заменен на runsv)




Александр Чистяков                             19/51
Тем временем, PHP-версия
✔
    Менеджерам нужна статистика – вынос
    “тяжелых” запросов на R/O реплику и
    отдельное backoffice приложение (так же
    будет и потом в Ruby-версии)
✔
    (Кстати, эта реплика все время дохла)
✔
    А трафик, тем временем, продолжает расти
✔
    Внезапно, DDoS




Александр Чистяков                             20/51
DDoS - 1
✔
    Быстро выделили шаблон и собрали список
    “плохих” IP (~6000 за первый час)
✔
    Доступа к хост-машине нет – ipset установить
    невозможно
✔
    Передали список “плохих” IP хостеру с
    просьбой сделать блокировку на их
    оборудовании
✔
    Поставили mod_evasive




Александр Чистяков                             21/51
DDoS - 2
✔
    С утра передали еще один список ~8000
    адресов
✔
    Техподдержка хостера заблокировала все
    адреса на нашем же iptables
✔
    %$^#!
✔
    Арендовали сервер в другом месте, установили
    на нем ipset, сделали его фронтэндом к
    старому




Александр Чистяков                           22/51
Это еще не конец PHP-версии
✔
    Легитимный трафик со временем все больше
✔
    PHP-версия не справляется, разработчики
    вынуждены опять включить кэш Drupal
✔
    Не помогает, база время от времени “выносит”
    диск
✔
    Аренда еще одного сервера у того же хостера
    (сервер стоит дороже, у него лучше дисковая
    подсистема – выносим базу на него)




Александр Чистяков                            23/51
Запуск Ruby-версии
✔
    Запуск поэтапный, по странам
✔
    В России больше всего клиентов – ее запускали
    в последнюю очередь
✔
    Процедура запуска: остановка платежей,
    домиграция пользователей, проксирование
    сайта со старого места на новое, смена
    записей в DNS




Александр Чистяков                            24/51
Один переезд = два пожара
✔
    Миграции с первого раза не проходят – не
    сходятся балансы, приходится править код и
    перезапускать миграцию
✔
    Миграции идут через Resque
✔
    Один пользователь – одно сообщение в
    очереди
✔
    Одно сообщение в очереди – один fork()
✔
    Fork rate - ~80 forks/s




Александр Чистяков                               25/51
Один переезд = два пожара
✔
    Приложение для России запустили в пятницу
    вечером (тем и спаслись), в субботу днем оно
    начало втыкать
✔
    Началась великая битва за живучесть
✔
    Не забыли ли мы о нагрузочном тестировании?
✔
    Не забыли, но где-то ошиблись с оценкой




Александр Чистяков                            26/51
Битва за живучесть
✔
    Сразу было видно, что проблемы не на базе
    данных
✔
    “Продать что-нибудь ненужное”:
     ✔
       Выкинули GlusterFS – не помогло
     ✔
         Переехали из KVM-based виртуалки на хост
         – не помогло
     ✔
         Увеличили количество воркеров Unicorn – не
         помогло
     ✔
         А поставка нового сервера на площадку
         хостера – 10 дней (да, мы заказали)

Александр Чистяков                               27/51
Битва за живучесть
✔
    А как понять, где втыкает приложение?
     ✔
       Сделать профайлинг?
✔
    Ограничение – профайлить надо под нагрузкой
✔
    Никто в команде не умеет толком профайлить
    Ruby-приложение под нагрузкой, в том числе, и
    я
✔
    Но ясно, что нужно что-то не очень инвазивное,
    чтобы сам профайлер не мешал работе сайта



Александр Чистяков                             28/51
Битва за живучесть
✔
    А вот если бы я был джавистом...
     ✔
       ...стоп, так я уже! Я сделал бы сэмплинг
       стектрейсов jstack'ом
✔
    Но под Ruby нет jstack!..
     ✔
         ...зато есть PMP, http://poormansprofiler.org
✔
    При помощи тривиального sh-скрипта gdb
    превращается в сэмплирующий профайлер
✔
    Я записывал сэмпл в секунду партиями по 50-
    600 сэмплов за один запуск скрипта


Александр Чистяков                                       29/51
PMP
✔
    Что хорошо – RVM собирает Ruby с debug info
✔
    Что плохо – стектрейсы приходится
    анализировать и классифицировать вручную
✔
    Сейчас я все еще пытаюсь написать
    автоматический сборщик и классификатор, но
    он пока не готов для публичного показа




Александр Чистяков                            30/51
Победа
✔
    Сэмплирование показало, что втыкает GC
✔
    Попытки настроить GC через переменные
    окружения почему-то провалились
✔
    Срочный переезд REE 1.8.7 – MRI 1.9.3
✔
    После переезда GC заработал как надо
✔
    Тем временем, разработчики приделали
    фрагментарный кэш
✔
    Ура, белый господин разрешил нам немного
    поспать!


Александр Чистяков                             31/51
А сколько нужно воркеров?
✔
    Автор Unicorn рекомендует от 4 до 8 воркеров
    на ядро
✔
    Double facepalm
✔
    На самом деле, воркеров нужно столько, чтобы
    они могли держать нагрузку
✔
    Что же такое “держать нагрузку”?
✔
    50-70% сэмплов должны быть “сижу на select(),
    жду работу”
✔
    Почему 50-70%? а) А мне так нравица! б) А
    почему было 4-8 на ядро? :)

Александр Чистяков                             32/51
Когда в руках PMP...
✔
    ...все вокруг выглядит как программное
    обеспечение
✔
    В норме воркеры Unicorn стоят на select() и
    ждут запроса от nginx
✔
    А что бывает не в норме?
      ✔
        Стоят на вызовах GC
     ✔
         Стоят на записи в лог (GlusterFS!!!)
     ✔
         На select() внутри EventMachine (да, у нас
         была Sinatra)
     ✔
         На обмене с БД

Александр Чистяков                                    33/51
Помните о рассылке почты?
✔
    Мы аутсорсим рассылку, но запускаем ее через
    rake task
✔
    При миграции 1.8.7 – 1.9.3 возникли проблемы
    с его производительностью
✔
    Сэмплер показал, что уперлись в старый
    добрый GC
✔
    В этот раз настройка через переменные
    окружения удалась




Александр Чистяков                            34/51
Хотим еще баек из склепа!
✔
    Запрос для построения аналитической
    таблицы:
     UPDATE purchases SET user_created_at =

     us.created_at FROM purchases p
     INNER JOIN users us ON us.id = p.user_id
     AND p.user_id >= 2000000 AND p.user_id < 2100000;
✔
    На первый взгляд все окей
✔
    По идее, ему просто нужно сделать один full
    scan
✔
    В реальности это SQL bomb (as in “fork bomb”)

Александр Чистяков                                       35/51
И еще!
✔
    Sinatra:
     ✔
       Штука клевая, но в чем была ее немдленная
       польза для Республики?
     ✔
         Кому-то не хватало строк в резюме?
✔
    Суть проблемы:
     ✔
         Sinatra при ошибке приложения
         перестраивает модели путем опроса базы
     ✔
         Если 1/10 трафика – ошибки (в JS косячок),
         то база встает на колени


Александр Чистяков                                36/51
Proof or did not happen!
✔
    На графике какая-то чушь, вощемта:




✔
    Одно ясно: базе очень плохо
✔
    Мы в эту ловушку попали дважды, так как не
    вели бортжурнал

Александр Чистяков                               37/51
Британские ученые открыли ад
✔
    Однажды мы забыли на продакшне mc с
    поиском по большому файлу, и он отъел 16Gb
    RAM
✔
    Я знал, что этим кончится, поэтому не
    использую mc последние лет семь
✔
    Кстати, для расследования подобных
    инцидентов мы используем atop, чего и вам
    желаем




Александр Чистяков                           38/51
Как мы готовили БД
✔
    Ежедневные отчеты pgfouine
✔
    Если индекса нет, а нужен – строим
✔
    Как настраивать сам движок?
     ✔
       Зависит от потребностей
     ✔
         Включаем log_checkpoints и следим, чтобы
         чекпойнты начинались по таймауту, а не по
         нехватке места в логах
     ✔
         Таймаут, кстати, ставим минут 20
     ✔
         Много сегментов для массовой записи, мало
         – если нужно быстрое восстановление

Александр Чистяков                              39/51
Как еще мы готовили БД
✔
    Hot standby репликация (9.0 и выше)
     ✔
       Умеет отваливаться молча, просто теряя
       данные на реплике
✔
    Попробовали Slony-I
     ✔
       Не дружит с миграциями Rails
✔
    Однажды вернулись на hot standby, а там все
    окей (нет, в чудеса не верим)
✔
    Как я уже говорил, с реплики считается долгая
    аналитика


Александр Чистяков                              40/51
Как мы бэкапили БД
✔
    Первое время – pg_dumpall прямо с продакшн
     ✔
       Но недолго музыка играла
✔
    pg_dumpall с реплики
     ✔
       Реплика не может отставать надолго и
       просто канселит бэкапные SELECT'ы
✔
    WAL archiving при помощи pg_rman
     ✔
       Японские разработчики такие японские
✔
    И тут кто-то сказал “ZFS!”
✔
    Вот, думаем...


Александр Чистяков                            41/51
Эволюция деплоймента
✔
    Из git вручную
✔
    Caplite (homemade рецепты для Capistrano)
✔
    Собственно Capistrano в полный рост
✔
    Jabber-бот
✔
    Кстати, мы деплоимся минут по 6-8, что для
    старого джависта привычно, но несколько
    необычно (“спасибо” SASS и прекомпиляции
    эссетов)




Александр Чистяков                               42/51
Эволюция процесса разработки
✔
    Креативный хаос (быстро, грязно, все бегают и
    орут)
✔
    Peer reviews
✔
    Unit tests
✔
    CI:
     ✔
        Bigtuna
     ✔
         ^ долго не проплавала
     ✔
         Jenkins (греет сердце джависта)
✔
    Итог: рутина и всем макбук, пацаны!


Александр Чистяков                             43/51
Управление конфигурацией
✔
    Вручную
✔
    Chef (пока на начальном этапе)
✔
    У каждого разработчика – своя виртуальная
    машина
✔
    ^ чему они очень рады
✔
    Вот только дамп базы для разработчика очень
    большой...




Александр Чистяков                           44/51
Церковь Графиков и ее адепты
✔
    Munin
✔
    NAGIOS
✔
    http://host-tracker.com
✔
    Airbrake
✔
    NewRelic
✔
    Smokeping
✔
    Мониторинг от хостера (100% useless)
✔
    A big project never sleeps (just like Moscow)



Александр Чистяков                                  45/51
Как мы нанимали
✔
    Из десяти человек
     ✔
       Один устраивает ~полностью
     ✔
         Семеро не знают разницу между Apache и
         nginx
     ✔
         У всех серьезные места работы в резюме и
         неплохие аппетиты
✔
    Берите тех, кто хотя бы умеет пользоваться
    поисковиком
     ✔
         Не ошибетесь, мы не ошиблись (Дима,
         привет и удачи на новом месте!)

Александр Чистяков                                46/51
Проблемы
✔
    “Я разработчик, я не хочу думать, я хочу
    разрабатывать”
     ✔
       Что такое “план SQL запроса”?
     ✔
         Почти 50% времени – не на БД (WTF?)
✔
    Хостер становится обузой:
     ✔
         Хостерская экспертиза нерелевантна
     ✔
         Нам не хватает ручек и рычагов
     ✔
         Машины тяжеловаты, причем, не там, где
         надо


Александр Чистяков                                47/51
Планы на будущее
✔
    Мировое господство
✔
    Стандартизация, унификация:
     ✔
       Довнедрение Chef
     ✔
         Консолидация сервисов и серверов
     ✔
         Еще больше графиков
✔
    Уменьшение количества SPOF
✔
    Больше рутины и макбуков




Александр Чистяков                          48/51
Выводы
✔
    Мы можем многое
✔
    Вы тоже все это можете
✔
    Большой проект это всегда интересно
✔
    Ruby on Rails – продукт эволюции, а не
    революции (хороший продукт, кстати)
✔
    Понимание происходящего в системе все еще
    важно, несмотря на уровни абстракции (и
    всегда будет важно)




Александр Чистяков                          49/51
Вопросы
✔
    Почему нет автоматического деплоймента?
     ✔
       ШТОА?!
✔


✔


✔


✔




Александр Чистяков                            50/51
Спасибо, с вам был...
✔
    ...Александр Чистяков
      ✔
        http://alexclear.livejournal.com
     ✔
         http://github.com/alexclear
     ✔
         alexclear@gmail.com
     ✔
         Первый раз в Сибири
     ✔
         Моя первая презентация в OpenOffice
     ✔
         Еще раз спасибо организаторам!




Александр Чистяков                             51/51

More Related Content

Big web project @happydev Omsk

  • 1. Большой веб-проект: развитие, рост, проблемы, решения с точки зрения отдела эксплуатации Александр Чистяков Системный администратор КупиКупон http://www.kupikupon.ru http://www.slideshare.net/alexclear chistyakov@kupikupon.ru
  • 2. Давайте познакомимся Я: ✔ Очень долго писал код ✔ Пока не понял, что так я только увеличиваю энтропию ✔ Не пишу свой код, а читаю и исправляю чужой ✔ Строю инфраструктуры и управляю ими ✔ Консультирую по разным вопросам (“мышки, станьте ежиками!”) Александр Чистяков 2/51
  • 3. Давайте познакомимся Вы: ✔ Разрабатываете веб-приложения? ✔ Работаете с базами данных? ✔ Занимаетесь эксплуатацией веб-проектов? ✔ Проектируете архитектуру приложений? ✔ Живете в Сибири (кстати, я первый раз в жизни забрался на Восток дальше Казахстана) Александр Чистяков 3/51
  • 4. Цели моего нахождения здесь ✔ Осуществить обмен опытом: ✔ Обрисовать ситуацию в статике и динамике ✔ Рассказать о достижениях ✔ Предостеречь от ошибок ✔ Зачекиниться ✔ Попробовать местное пиво ✔ Обратить вас в свою веру Александр Чистяков 4/51
  • 5. Отказ от ответственности ✔ Мое мнение – это только мое мнение: ✔ Не является официальной позицией моего работодателя ✔ Не может быть применено при работе на ядерных и медицинских объектах ✔ Вообще не может приниматься в расчет, пока вы самостоятельно не проведете эксперимент Александр Чистяков 5/51
  • 6. Суть проекта ✔ Купонный сервис, top 20 списка Forbes ✔ Какие задачи должен решать? ✔ Рассылать большое количество почты ✔ Предоставлять пользователям сайт, где можно регистрироваться и покупать ✔ Предоставлять партнерам возможность регистрироваться и управлять процессом ✔ Предоставлять менеджерам возможность создавать аналитические отчеты Александр Чистяков 6/51
  • 7. С чего все начиналось ✔ Проект на LAMP: ✔ MySQL 5.0.95 (!) ✔ Drupal ✔ Хостинг: ✔ OpenVZ контейнер размером во весь хост ✔ Доступа к хост-машине нет ✔ Установлена cPanel (!!!) ✔ Нагрузка - ~20 RPS к бэкенду Александр Чистяков 7/51
  • 8. Что в проекте делал я ✔ Год и семь месяцев назад зашел рассказать про мышек и ежиков ✔ Да так и остался ✔ Настраивал, мониторил, чинил, деплоил, документировал, собеседовал, консультировал ✔ То есть, в составе отдела эксплуатации выполнял обычные для отдела эксплуатации задачи Александр Чистяков 8/51
  • 9. Один переезд и два пожара ✔ Проект переехал с PHP на Ruby почти год назад ✔ Вопрос из зала: “Зачем?” ✔ Неужели PHP настолько хуже Ruby? ✔ ^ Я этого не говорил ✔ Разговор про “лучше” и “хуже” возможен, только если есть какие-то метрики ✔ Какие же тут могут быть метрики? Александр Чистяков 9/51
  • 10. Как делаются веб-проекты ✔ Один из десяти веб-проектов выживает и становится крупным ✔ А, может, даже из двадцати ✔ Мы имеем дело со случайным событием ✔ Чудо: команда энтузиастов, какой-то движок и вполне реальная база пользователей ✔ Я только что описал хаос ✔ Управление хаосом возможно, но сильно сокращает жизнь и ведет к неврозам Александр Чистяков 10/51
  • 11. Хаос (он же “Drupal”) ✔ Проекту жизненно необходим постоянный прогнозируемый прирост новой функциональности, но: ✔ см. картинку, ✔ команда также должна расширяться картинка взята с http://habrahabr.ru/post/144857 Александр Чистяков 11/51
  • 12. Что дает Ruby/RoR? ✔ Фреймворк, а не “CMS”: ✔ Сделано разработчиками для разработчиков ✔ Best practices действительно хороши ✔ Высокая расширяемость ✔ Ruby это тренд ✔ Ruby-разработчик: MB Pro, Converse, Github, Travis-CI, zsh ✔ PHP-разработчик: угадать невозможно Александр Чистяков 12/51
  • 13. Эксплуатационные проблемы ✔ Drupal не справляется с нагрузкой, так как: ✔ MySQL не справляется с нагрузкой ✔ Apache/PHP не справляется с нагрузкой ✔ Включение кэша Drupal не спасло: ✔ Отвалился геотаргетинг (все незалогиненные видят одно и то же) ✔ Совсем отвалился геотаргетинг (выбор города вручную в меню не помогает) Александр Чистяков 13/51
  • 14. Первые принятые меры - 1 ✔ Apache/PHP: ✔ Выкинули suPHP – избавились от форков ✔ (Почти) выкинули cPanel (инвазивнейший монстр, внедрившийся по всей системе) ✔ MySQL: ✔ Убрали MyISAM – перестали блокировать базу при дампе ✔ Размер буфера, размер биинлога и другие обычные действия (см. доклад Аксенова) Александр Чистяков 14/51
  • 15. Первые принятые меры - 2 ✔ MySQL: ✔ Включили query cache (зло, но меньшее) ✔ slow log, mk-log-parser и индексы, где нужно ✔ Платформа: ✔ etckeeper (спасал нас впоследствии) ✔ Приведение в порядок конфигов cron и других сервисов ✔ Без доступа к хост-машине не настроить FS, swappiness, I/O priority, etc Александр Чистяков 15/51
  • 16. Первые результаты ✔ Удалось избавиться от кэша Drupal ✔ Нагрузка на машину существенно снизилась ✔ Когда через пару месяцев трафик на сайте возрос в два раза, это не вызвало никаких срочных проблем Александр Чистяков 16/51
  • 17. Тем временем, Ruby-версия ✔ Платформа: ✔ RHEL 5.5 ✔ Ruby 1.8.7 (REE), Rails 3 ✔ MySQL заменили на PostgreSQL ✔ ^ Единственное с моей точки зрения преимущество для подобных проектов – наличие online ALTER, да и то не при любых условиях (при добавлении столбца с дефолтным значением все равно будет блокировка таблицы) Александр Чистяков 17/51
  • 18. Ruby-версия, железо ✔ Dell R710, 24 или 48 Gb, SAS-диски ✔ HW RAID контроллеры с BBU ✔ Production конфигурация: ✔ Один сервер для БД ✔ Один сервер для RoR ✔ Сервер для бэкапа ✔ Сервера для статики, телефонии, разработки – не Dell и параметры скромнее ✔ Как видите, железо было взято с запасом Александр Чистяков 18/51
  • 19. Ruby-версия, компоненты ✔ RVM (да, и в продакшне тоже) ✔ Unicorn ✔ god для управления Unicorn'ами (not anymore) ✔ Периодические задачи – cron+rake ✔ Обработчики очередей ✔ Resque как сервер очередей ✔ god для управления обработчиками (сейчас заменен на runsv) Александр Чистяков 19/51
  • 20. Тем временем, PHP-версия ✔ Менеджерам нужна статистика – вынос “тяжелых” запросов на R/O реплику и отдельное backoffice приложение (так же будет и потом в Ruby-версии) ✔ (Кстати, эта реплика все время дохла) ✔ А трафик, тем временем, продолжает расти ✔ Внезапно, DDoS Александр Чистяков 20/51
  • 21. DDoS - 1 ✔ Быстро выделили шаблон и собрали список “плохих” IP (~6000 за первый час) ✔ Доступа к хост-машине нет – ipset установить невозможно ✔ Передали список “плохих” IP хостеру с просьбой сделать блокировку на их оборудовании ✔ Поставили mod_evasive Александр Чистяков 21/51
  • 22. DDoS - 2 ✔ С утра передали еще один список ~8000 адресов ✔ Техподдержка хостера заблокировала все адреса на нашем же iptables ✔ %$^#! ✔ Арендовали сервер в другом месте, установили на нем ipset, сделали его фронтэндом к старому Александр Чистяков 22/51
  • 23. Это еще не конец PHP-версии ✔ Легитимный трафик со временем все больше ✔ PHP-версия не справляется, разработчики вынуждены опять включить кэш Drupal ✔ Не помогает, база время от времени “выносит” диск ✔ Аренда еще одного сервера у того же хостера (сервер стоит дороже, у него лучше дисковая подсистема – выносим базу на него) Александр Чистяков 23/51
  • 24. Запуск Ruby-версии ✔ Запуск поэтапный, по странам ✔ В России больше всего клиентов – ее запускали в последнюю очередь ✔ Процедура запуска: остановка платежей, домиграция пользователей, проксирование сайта со старого места на новое, смена записей в DNS Александр Чистяков 24/51
  • 25. Один переезд = два пожара ✔ Миграции с первого раза не проходят – не сходятся балансы, приходится править код и перезапускать миграцию ✔ Миграции идут через Resque ✔ Один пользователь – одно сообщение в очереди ✔ Одно сообщение в очереди – один fork() ✔ Fork rate - ~80 forks/s Александр Чистяков 25/51
  • 26. Один переезд = два пожара ✔ Приложение для России запустили в пятницу вечером (тем и спаслись), в субботу днем оно начало втыкать ✔ Началась великая битва за живучесть ✔ Не забыли ли мы о нагрузочном тестировании? ✔ Не забыли, но где-то ошиблись с оценкой Александр Чистяков 26/51
  • 27. Битва за живучесть ✔ Сразу было видно, что проблемы не на базе данных ✔ “Продать что-нибудь ненужное”: ✔ Выкинули GlusterFS – не помогло ✔ Переехали из KVM-based виртуалки на хост – не помогло ✔ Увеличили количество воркеров Unicorn – не помогло ✔ А поставка нового сервера на площадку хостера – 10 дней (да, мы заказали) Александр Чистяков 27/51
  • 28. Битва за живучесть ✔ А как понять, где втыкает приложение? ✔ Сделать профайлинг? ✔ Ограничение – профайлить надо под нагрузкой ✔ Никто в команде не умеет толком профайлить Ruby-приложение под нагрузкой, в том числе, и я ✔ Но ясно, что нужно что-то не очень инвазивное, чтобы сам профайлер не мешал работе сайта Александр Чистяков 28/51
  • 29. Битва за живучесть ✔ А вот если бы я был джавистом... ✔ ...стоп, так я уже! Я сделал бы сэмплинг стектрейсов jstack'ом ✔ Но под Ruby нет jstack!.. ✔ ...зато есть PMP, http://poormansprofiler.org ✔ При помощи тривиального sh-скрипта gdb превращается в сэмплирующий профайлер ✔ Я записывал сэмпл в секунду партиями по 50- 600 сэмплов за один запуск скрипта Александр Чистяков 29/51
  • 30. PMP ✔ Что хорошо – RVM собирает Ruby с debug info ✔ Что плохо – стектрейсы приходится анализировать и классифицировать вручную ✔ Сейчас я все еще пытаюсь написать автоматический сборщик и классификатор, но он пока не готов для публичного показа Александр Чистяков 30/51
  • 31. Победа ✔ Сэмплирование показало, что втыкает GC ✔ Попытки настроить GC через переменные окружения почему-то провалились ✔ Срочный переезд REE 1.8.7 – MRI 1.9.3 ✔ После переезда GC заработал как надо ✔ Тем временем, разработчики приделали фрагментарный кэш ✔ Ура, белый господин разрешил нам немного поспать! Александр Чистяков 31/51
  • 32. А сколько нужно воркеров? ✔ Автор Unicorn рекомендует от 4 до 8 воркеров на ядро ✔ Double facepalm ✔ На самом деле, воркеров нужно столько, чтобы они могли держать нагрузку ✔ Что же такое “держать нагрузку”? ✔ 50-70% сэмплов должны быть “сижу на select(), жду работу” ✔ Почему 50-70%? а) А мне так нравица! б) А почему было 4-8 на ядро? :) Александр Чистяков 32/51
  • 33. Когда в руках PMP... ✔ ...все вокруг выглядит как программное обеспечение ✔ В норме воркеры Unicorn стоят на select() и ждут запроса от nginx ✔ А что бывает не в норме? ✔ Стоят на вызовах GC ✔ Стоят на записи в лог (GlusterFS!!!) ✔ На select() внутри EventMachine (да, у нас была Sinatra) ✔ На обмене с БД Александр Чистяков 33/51
  • 34. Помните о рассылке почты? ✔ Мы аутсорсим рассылку, но запускаем ее через rake task ✔ При миграции 1.8.7 – 1.9.3 возникли проблемы с его производительностью ✔ Сэмплер показал, что уперлись в старый добрый GC ✔ В этот раз настройка через переменные окружения удалась Александр Чистяков 34/51
  • 35. Хотим еще баек из склепа! ✔ Запрос для построения аналитической таблицы: UPDATE purchases SET user_created_at = us.created_at FROM purchases p INNER JOIN users us ON us.id = p.user_id AND p.user_id >= 2000000 AND p.user_id < 2100000; ✔ На первый взгляд все окей ✔ По идее, ему просто нужно сделать один full scan ✔ В реальности это SQL bomb (as in “fork bomb”) Александр Чистяков 35/51
  • 36. И еще! ✔ Sinatra: ✔ Штука клевая, но в чем была ее немдленная польза для Республики? ✔ Кому-то не хватало строк в резюме? ✔ Суть проблемы: ✔ Sinatra при ошибке приложения перестраивает модели путем опроса базы ✔ Если 1/10 трафика – ошибки (в JS косячок), то база встает на колени Александр Чистяков 36/51
  • 37. Proof or did not happen! ✔ На графике какая-то чушь, вощемта: ✔ Одно ясно: базе очень плохо ✔ Мы в эту ловушку попали дважды, так как не вели бортжурнал Александр Чистяков 37/51
  • 38. Британские ученые открыли ад ✔ Однажды мы забыли на продакшне mc с поиском по большому файлу, и он отъел 16Gb RAM ✔ Я знал, что этим кончится, поэтому не использую mc последние лет семь ✔ Кстати, для расследования подобных инцидентов мы используем atop, чего и вам желаем Александр Чистяков 38/51
  • 39. Как мы готовили БД ✔ Ежедневные отчеты pgfouine ✔ Если индекса нет, а нужен – строим ✔ Как настраивать сам движок? ✔ Зависит от потребностей ✔ Включаем log_checkpoints и следим, чтобы чекпойнты начинались по таймауту, а не по нехватке места в логах ✔ Таймаут, кстати, ставим минут 20 ✔ Много сегментов для массовой записи, мало – если нужно быстрое восстановление Александр Чистяков 39/51
  • 40. Как еще мы готовили БД ✔ Hot standby репликация (9.0 и выше) ✔ Умеет отваливаться молча, просто теряя данные на реплике ✔ Попробовали Slony-I ✔ Не дружит с миграциями Rails ✔ Однажды вернулись на hot standby, а там все окей (нет, в чудеса не верим) ✔ Как я уже говорил, с реплики считается долгая аналитика Александр Чистяков 40/51
  • 41. Как мы бэкапили БД ✔ Первое время – pg_dumpall прямо с продакшн ✔ Но недолго музыка играла ✔ pg_dumpall с реплики ✔ Реплика не может отставать надолго и просто канселит бэкапные SELECT'ы ✔ WAL archiving при помощи pg_rman ✔ Японские разработчики такие японские ✔ И тут кто-то сказал “ZFS!” ✔ Вот, думаем... Александр Чистяков 41/51
  • 42. Эволюция деплоймента ✔ Из git вручную ✔ Caplite (homemade рецепты для Capistrano) ✔ Собственно Capistrano в полный рост ✔ Jabber-бот ✔ Кстати, мы деплоимся минут по 6-8, что для старого джависта привычно, но несколько необычно (“спасибо” SASS и прекомпиляции эссетов) Александр Чистяков 42/51
  • 43. Эволюция процесса разработки ✔ Креативный хаос (быстро, грязно, все бегают и орут) ✔ Peer reviews ✔ Unit tests ✔ CI: ✔ Bigtuna ✔ ^ долго не проплавала ✔ Jenkins (греет сердце джависта) ✔ Итог: рутина и всем макбук, пацаны! Александр Чистяков 43/51
  • 44. Управление конфигурацией ✔ Вручную ✔ Chef (пока на начальном этапе) ✔ У каждого разработчика – своя виртуальная машина ✔ ^ чему они очень рады ✔ Вот только дамп базы для разработчика очень большой... Александр Чистяков 44/51
  • 45. Церковь Графиков и ее адепты ✔ Munin ✔ NAGIOS ✔ http://host-tracker.com ✔ Airbrake ✔ NewRelic ✔ Smokeping ✔ Мониторинг от хостера (100% useless) ✔ A big project never sleeps (just like Moscow) Александр Чистяков 45/51
  • 46. Как мы нанимали ✔ Из десяти человек ✔ Один устраивает ~полностью ✔ Семеро не знают разницу между Apache и nginx ✔ У всех серьезные места работы в резюме и неплохие аппетиты ✔ Берите тех, кто хотя бы умеет пользоваться поисковиком ✔ Не ошибетесь, мы не ошиблись (Дима, привет и удачи на новом месте!) Александр Чистяков 46/51
  • 47. Проблемы ✔ “Я разработчик, я не хочу думать, я хочу разрабатывать” ✔ Что такое “план SQL запроса”? ✔ Почти 50% времени – не на БД (WTF?) ✔ Хостер становится обузой: ✔ Хостерская экспертиза нерелевантна ✔ Нам не хватает ручек и рычагов ✔ Машины тяжеловаты, причем, не там, где надо Александр Чистяков 47/51
  • 48. Планы на будущее ✔ Мировое господство ✔ Стандартизация, унификация: ✔ Довнедрение Chef ✔ Консолидация сервисов и серверов ✔ Еще больше графиков ✔ Уменьшение количества SPOF ✔ Больше рутины и макбуков Александр Чистяков 48/51
  • 49. Выводы ✔ Мы можем многое ✔ Вы тоже все это можете ✔ Большой проект это всегда интересно ✔ Ruby on Rails – продукт эволюции, а не революции (хороший продукт, кстати) ✔ Понимание происходящего в системе все еще важно, несмотря на уровни абстракции (и всегда будет важно) Александр Чистяков 49/51
  • 50. Вопросы ✔ Почему нет автоматического деплоймента? ✔ ШТОА?! ✔ ✔ ✔ ✔ Александр Чистяков 50/51
  • 51. Спасибо, с вам был... ✔ ...Александр Чистяков ✔ http://alexclear.livejournal.com ✔ http://github.com/alexclear ✔ alexclear@gmail.com ✔ Первый раз в Сибири ✔ Моя первая презентация в OpenOffice ✔ Еще раз спасибо организаторам! Александр Чистяков 51/51