Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Опыт эксплуатации большого проекта на Ruby

2 547 vues

Publié le

Publié dans : Technologie
  • Soyez le premier à commenter

Опыт эксплуатации большого проекта на Ruby

  1. 1. Опыт эксплуатации большого Ruby-проекта Александр Чистяков КупиКупон http://alexclear.livejournal.com
  2. 2. Докладчик?• PHP-программист• Администратор баз данных• Эксплуатационщик• Архитектор серверных приложений ^ WTF?• Добрый землянин• Занимает место в профессии
  3. 3. Аудитория?• Ruby-программисты• Администраторы баз данных?• Эксплуатационщики?• Архитекторы серверных приложений• Добрые земляне?
  4. 4. Цели• Разрушить мифы• Столкнуть с парохода современности• Я никого не хочу победить• «Не едь за мной – ты там не проедешь» (ворона птица сильная и на голову наглухо ушибленная)
  5. 5. Disclaimer• Все мертвые проекты мертвы одинаково, все живые проекты живы по-разному• «Кто не умеет работать – учит» – «Кодекс это набор рекомендаций»• Самое важное – верно определить граничные условия – А нужно ли вам именно это? А зачем? – А, может, ну его этот веб и в Тибет?
  6. 6. Большой проект• Купонный сервис, входит в top 3 в России• Что он должен уметь технически? – Рассылать много почты – Предоставлять пользователям возможность регистрироваться и покупать – Предоставлять продавцам возможность регистрироваться и управлять акциями – Предоставлять менеджерам возможность создавать аналитические отчеты
  7. 7. Моя роль в проекте• Системный администратор• Мне больше нравится слово «эксплуатационщик», но мне его не произнести• В свое время был привлечен для консультаций, да так и прижился
  8. 8. Исходное состояние• Проект на LAMP – MySQL 5.0.95 – Drupal• Хостинг: – OpenVZ контейнер большого размера – Доступа к хост-машине нет – Установлена Cpanel• ~20 RPS к бэкенду
  9. 9. Проблемы 1• Необходима новая функциональность, но – См. картинку – По моему опыту, это верно для многих PHP CMS – Тем не менее, стоит вопрос о расширении команды картинка взята с http://habrahabr.ru/post/144857
  10. 10. Проблемы 2• Drupal не справлялся с нагрузкой, так как – MySQL не справлялся с нагрузкой – Apache/PHP не справлялся с нагрузкой• Включение кэша Drupal не спасло – Отвалился геотаргетинг (все незалогиненные видят одно и то же) – Совсем отвалился геотаргетинг (выбор города вручную в меню не помогает)
  11. 11. Решение проблем с разработкой• Вне зоны моей ответственности, я занимался только эксплуатацией проекта• Если вкратце, три слова: Ruby on Rails• Если вам интересно мое мнение – Лучше сразу писать проект на RoR, чем сначала написать RoR на PHP/Drupal, а на этом уже – проект – И не забудьте про гемы, их все тоже придется написать на PHP – Переход выглядит более чем оправданным
  12. 12. Решение текущих проблем с эксплуатацией 1• Apache/PHP – Выкинули suPHP - избавились от форков – (Почти) выкинули cPanel (инвазивнейший монстр, протачивающий свои ходы по всей системе)• MySQL – Убрали MyISAM – перестали блокировать базу в момент дампа – Размер буфера, размер бинлога, flush_log_at_trx_commit – см. доклад Андрея Аксенова
  13. 13. Решение текущих проблем с эксплуатацией 2• MySQL – Включили query cache (меньшее зло) – Настроили slow log и mk-log-parser – Построили индексы там, где было необходимо• Платформа – etckeeper (спасал нас впоследствии) – Приведение в порядок cron-файлов и других конфигов – Не имея доступа к хост-машине много не натюнишь
  14. 14. Последствия• Кэш Drupal удалось отключить• Нагрузка на машину существенно снизилась• Когда через пару месяцев трафик возрос в два раза, это не вызвало никаких проблем
  15. 15. Ruby-версия: платформа• RHEL 5.5• Ruby 1.8.7 (REE), Rails 3• PostgreSQL вместо MySQL• (Единственное, на мой взгляд, преимущество PostgreSQL для таких проектов – наличие online alter прямо в поставке) – Это если вы не добавляете столбец с дефолтным значением
  16. 16. Ruby-версия: железо• Dell R710, 24 или 48 Gb, SAS-диски• RAID контроллеры с BBU• Production конфигурация: – Один сервер для базы данных – Один сервер для RoR – Сервер для бэкапа – Сервера для отдачи статики, телефонии, разработки – гораздо более скромные параметры
  17. 17. Ruby-версия: компоненты• RVM• Unicorn• god для управления Unicorn’ами• Периодические задачи – cron+rake• Обработчики очередей• Resque как сервер очередей• Изначально – god для управления обработчиками
  18. 18. Тем временем, PHP-версия• Менеджеры хотят считать статистику – вынос тяжелых запросов на R/O реплику, отдельное приложение (потом для Ruby-версии будет то же самое)• (Кстати, эта реплика постоянно отваливалась)• Трафик продолжает расти• Внезапно, DDoS
  19. 19. DDoS 1• Быстро выделили шаблон и собрали список «плохих» IP (~6000 адресов за первый час)• Доступа к хост-машине нет – ipset установить невозможно• Передали список «плохих» IP хостеру с просьбой сделать блокировку на их оборудовании• Поставили mod_evasive
  20. 20. DDoS 2• С утра передали еще один список ~8000 адресов• Поддержка хостера заблокировала все адреса на нашем же iptables• %$^#!• Арендовали сервер в другом месте, установили на нем ipset, сделали его фронтэндом к старому
  21. 21. Это еще не все с PHP-версией• Легитимный трафик со временем все больше• PHP-версия не справляется, разработчики вынуждены опять включить кэш Drupal’а• Не помогает, база время от времени «выносит» диск• Аренда еще одного сервера у того же хостера (сервер стоит дороже, лучше дисковая – выносим базу на него)
  22. 22. Запуск Ruby-версии• Запуск поэтапный, по странам• В России больше всего клиентов – ее запускали в последнюю очередь• Процедура запуска: остановка платежей, домиграция пользователей, проксирование сайта со старого места на новое, смена записей в DNS
  23. 23. Проблемы 1• Миграции с первого раза не проходят – не сходятся балансы, приходится править код и перезапускать миграцию• Миграции идут через Resque• Один пользователь – одно сообщение в очереди• Одно сообщение в очереди – один fork()• Fork rate ~80 forks/s
  24. 24. Проблемы 2• Приложение для России запустили в пятницу вечером (thank God), в субботу днем оно начало втыкать• Все это время мы бились за живучесть• Не забыли ли мы о нагрузочном тестировании?• Не забыли, но где-то ошиблись с оценкой
  25. 25. Битва за живучесть 1• Сразу было видно, что проблемы не на базе данных• Выкинули GlusterFS – не помогло• Переехали с KVM-based виртуалки на хост – не помогло• Увеличили количество воркеров – не помогло• Поставка нового сервера – 10 дней
  26. 26. Битва за живучесть 2• А как вообще понять, где втыкает приложение?• Сделать профайлинг?• Ограничение – профайлить надо прямо под нагрузкой• Я PHP-программист  и не имел опыта профайлинга Ruby-проектов под нагрузкой при помощи профайлера для Ruby• Но ясно, что нужно что-то неинвазивное
  27. 27. Битва за живучесть 3• А как бы я профайлил Java-приложение?• Очевидно: сделал бы сэмплинг стектрейсов• А что останавливает в случае Ruby?• Ничего не останавливает: – PMP, http://poormansprofiler.org• При помощи тривиального sh-скрипта gdb превращается в средство записи сэмплов с заданным интервалом• Я писал раз в секунду, 50-600 сэмплов за один запуск скрипта
  28. 28. PMP• Что хорошо – RVM собирает Ruby с debug info• Что плохо – стектрейсы приходится анализировать и классифицировать вручную• Сейчас я пытаюсь написать полуавтоматический классификатор, но даже до альфа-версии дело пока не дошло
  29. 29. Битва за живучесть - 4• Сэмплирование показало, что втыкает GC• Попытки настроить GC через переменные окружения провалились• Срочный переход REE 1.8.7 – MRI 1.9.3• После перехода GC заработал как надо• Тем временем, разработчики приделали фрагментарный кэш• Ура, белый господин разрешил нам немного поспать!
  30. 30. А сколько нужно воркеров?• Автор Unicorn рекомендует от 4 до 8 воркеров на ядро• Double facepalm• На самом деле, воркеров нужно столько, чтобы они могли держать нагрузку• Что же такое «держать нагрузку»?• 50-70% сэмплов должны быть «сижу на select(), жду запроса»• - Почему 50-70%? – А почему было 4-8 на ядро?
  31. 31. Когда в руках сэмплирующий профайлер• Все вокруг выглядит программным обеспечением• В норме воркеры Unicorn стоят на select() и ждут запрос от апстрима• Не в норме: – На вызовах GC – На записи в лог – На select() внутри EventMachine (вопросы не ко мне) – На обмене с БД
  32. 32. Помните, я говорил о рассылке почты?• Рассылкой почты занимается внешний провайдер, но запускает ее rake task• При миграции Ruby с 1.8.7 до 1.9.3 возникли проблемы с производительностью• Сэмплер показал что уперлись в старый добрый GC• В этот раз удалось настроить GC при помощи переменных окружения
  33. 33. Что еще было хорошего?• Запрос для построения аналитической таблицы: 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 и успокоиться• Есть fork bomb и archive bomb, а это – SQL bomb
  34. 34. Sinatra• Что занесло ее в проект сейчас не узнать – иных уж нет, а те далече• Может, кому-то не хватало строк в резюме?• Sinatra при ошибке приложения читает модели, для чего переопрашивает БД на предмет структуры базы• Это очень эффективный способ поставить базу на колени
  35. 35. Пруф или не было• На графике погода в Сахаре, но можно сделать оценочное суждение о том, что базе плохо• Мы в эту ловушку попадали дважды с большим промежутком, и во второй раз никто уже не помнил суть вопроса
  36. 36. Байки из склепа• Однажды мы забыли на продакшне mc с поиском по большому файлу, и он занял 16 гигабайт• Я знал, что этим кончится, поэтому не пользуюсь mc последние лет семь• Кстати, для расследования подобных инцидентов у нас запущен atop
  37. 37. Немного про настройку БД• Ежедневные отчеты pgfouine• Если где-то нет индекса, и он может помочь - строим• Настройка конфигурации движка: – А чего хотим? – Включаем log_checkpoints и следим, чтобы причиной выполнения checkpoint’а было истечение таймаута, а не переполнение лога – Таймаут, кстати, поднимаем – А также ставим checkpoint_completion_target поближе к 1 – Много сегментов хорошо для массовой записи и плохо для аварийного рестарта (адаптируйте под ситуацию)
  38. 38. Еще немного про настройку БД• Пробовали встроенную в 9.X hot standby репликацию – Все хорошо до того момента, пока данные в реплике не окажутся не такими, как в мастере• Пробовали Slony-I – DDL statements в миграциях нужно оборачивать в вызов команды, что очень неудобно• Вернулись к hot standby, ведем наблюдение
  39. 39. И про бэкап БД• Сначала делали pg_dumpall прямо с продакшна – Это быстро закончилось• Потом – pg_dumpall с реплики – Это тоже перестало работать• Теперь WAL archiving при помощи pg_rman• Хотим попробовать Amanda
  40. 40. Эволюция деплоймента• Вручную из git• Caplite (не спрашивайте в киосках города, это внутренний набор скриптов)• Capistrano• Я раньше не думал, что приложение на динамическом языке может деплоиться так долго (thank SASS, etc)
  41. 41. Эволюция процесса• Креативный хаос (очень быстро, но очень грязно)• Peer reviews• Unit tests• CI: – Bigtuna – <s>Bigtuna</s> Jenkins
  42. 42. Управление конфигурацией• Вручную• Chef• Каждому разработчику – свою виртуальную машину – Збс!
  43. 43. Мониторинг• NAGIOS• http://host-tracker.com• Airbrake• NewRelic• Smokeping• Мониторинг от хостера (много лишних срабатываний)• В большом проекте всегда кто-нибудь не спит
  44. 44. Человеческий фактор 1• Вам может показаться, что ваши коллеги не умеют работать• Не надо волноваться, так оно и есть• Google, Yandex, Островок, калифорнийские стартапы, …, … - все нанимают лучших• Если все нанимают лучших, кому же достаются худшие?• Кстати, а с чего вы взяли, что умеете работать?
  45. 45. Человеческий фактор 2• Лучшие, худшие, дайте хоть каких-нибудь!• ~15 Skype-собеседований, чтобы найти одного человека в команду эксплуатации• Люди из Yandex, Mail.Ru, Scalaxy…• Наняли того, кто хотя бы умеет пользоваться поисковиком (делайте выводы о качестве остальных)• И не ошиблись в выборе
  46. 46. Человеческий фактор 3• Что мешает простым людям в команде: – Микроменеджмент – Соревнования на пустом месте (поэтому не нанимайте в команду одних только «звезд») – Поиск виноватых в те моменты, когда надо чинить упавшее – Истерики в эти же моменты• К счастью, все эти вопросы можно решить
  47. 47. Планы на будущее• Стандартизация, унификация – Больше Chef’а – Консолидация серверов – Больше мониторинга и графиков• Автоматизация – Автоматический failover – Раннее обнаружение отказов, построение трендов• Уменьшение количества SPOF
  48. 48. Выводы• Who dares wins• Большой проект это <s>сложно</s> тяжело, но интересно• Ruby on Rails продукт эволюции, а не революции – стандартные практики все те же• Понимание происходящего в системе все так же важно, как и 10 лет назад
  49. 49. Вопросы?••••••
  50. 50. Спасибо за внимание!• С вами был Александр Чистяков• http://alexclear.livejournal.com• alexclear@gmail.com• http://github.com/alexclear

×