210 likes | 447 Views
От стартапа до highload: Эволюция веб-проекта, или Как победить нагрузку. Антон Терехов Ведущий инженер - программист отдела фотосервисов ООО "Медиа Мир" (РБК). PhotoFile. Начало. Проект получен в 2005 году Проект состоял из 2-х серверов: www + DB, fileserver Количество записей в БД:
E N D
От стартапа до highload: Эволюция веб-проекта, или Как победить нагрузку Антон ТереховВедущий инженер - программист отдела фотосервисов ООО "Медиа Мир" (РБК)
PhotoFile. Начало. • Проект получен в 2005 году • Проект состоял из 2-х серверов: www + DB, fileserver • Количество записей в БД: • Пользователи: ~80 000 • Альбомы: ~290 000 • Фото: ~6 500 000 • Нагрузка: хиты ~2 000 000 хосты: ~55 000 • Файловый сервер заполнен на 3/4 • Что делать?
PhotoFile. Начало. Улучшили, то, что можно улучшить быстро: • Вынос DB на отдельный сервер • Регистрация пользователей на новом fileserver’е • Включение Smarty caching • И, конечно же, начали делать версию 2
Новый движок • Это – фотохостинг. Мы не меняем URL изображения.(Только если пользователь сам не сделает что-то с фото) URL вида photofile.ru/photo/userlogin/albumid/photoid.jpg • ЧПУ – залог удобства ресурсаphotofile.ru/users/userlogin/… • Все фото пользователя хранятся на 1 сервере, что исключает работы по переносу файлов между машинами • При отказе сервера внешние ссылки не изменяются • nginx разпределяет запросы к fileserver’ам (regexp) • Появляется отдельный proxy-server
Реклама – зло! • HTTP 1.1 500 Нагрузка растет • Введение MySQL Master-Slaves • Код не готов - введение отдельного сервера для авторизованных пользователей http://a.photofile.ru/ • Временное неправильное решение • Нет отказоустойчивости • Разные ссылки для авторизованного и анонимного пользователей • Но зато оно работает!
Новый движок. Часть 2. • Старые URL фото видаff01.photofile.ru/photo/056/290/1239173/128169725442ea9efd115a.jpg • Новые URL фото вида photofile.ru/photo/UserLogin/AlbumID/Photo.jpg • Уменьшается количество полей в таблице • Упрощение ссылок • Более четкая дисковая структура photo/U/Us/UserLogin/ • Мы можем выделить на подмножество пользователей (Us) отдельный fileserver! • URL фото в альбоме можно подобрать (Bruteforce). Нужна новая система паролирования альбомов.ngnix: X-Accel-Redirect и md5(то, что меняется между клиентами)
Проблемы с версией 2(которые можно было предусмотреть) • Smarty cache – «неидеальное» решение для нескольких frontends + fileservers • Некогерентен • Невозможно удаление «по событию» • NFS на файлы Smarty cache является SPOF (и не используется) • БД «не держит» нагрузку • Слишком большая таблицаальбомов • Слишком много сортировок и условий • Таблица типа MRG + Cron script(album_new – за последние 2 месяца, album_old – все остальные)
These Aren't the Droids You're looking For • «Старые» ссылки на файлы при переносе = symlinks • «Старые» ссылки на страницы и файлы= денормализованные таблицы + «правильные» индексы • При кажущейся непервоочередности проблемы – пользователи не почувствовали себя «лишними»
Что делать? • Cache Smarty не эффективен • Очевидное решение – memcached • Данные не связаны между собой • Не гарантирует хранение • Необходим дополнительный уровень абстракции - метаданные
Memcached with METAinformation • Реализация SQL limit • Уменьшение данных для сериализации • Единовременное устаревание коллекции данных • Самостоятельная обработка устаревания • Дополнительные операции get/set
Файловые транзакции • Выросший объем файлов в альбоме • Необходимы real-time операции • Обернем каждую файловую операцию в транзакцию (SQL и диск) • Сократим дисковые операции путем введения флага «удален» • nginx: set $flag /...../.deleted if ( -f $flag ) { return 404; }
Предел MySQL Master-Slaves • Данных меньше не становится • Эффективное количество Slaves конечно • Решение – разделить данные на несколько порций • Управляющая часть (список пользователей, сессии) • Данные пользователя (альбомы, фотографии) • Общие данные (форум, конкурсы) • Справочники (пункты печати) • Вопросы: • Как сохранить существующий формат ID • Как организовать Autoincrement • Балансировканагрузки
Сквозой autoincrement по нескольким mysqld 4 294 967 295 : например M = 50 частей, по 85 899 345 20 INSERT/сек Заполнение части: 49 дней
Работа с разделенными данными • На каждую порцию данных есть 2 Slaves • При подключении указываем режим работы Rили RW • Балансировка путем анализа нагрузки и размещения на сервере нескольких баз или же демонов (разные порты, репликация)
Распределение файлов по серверам • Более 40 fileservers x 1.4Tb • REGEXP слишком сложен • Часть данных превышает 1.4Tb • Dynamic DNS – наш выбор • Nginx.conf: resolver 127.0.0.1; resolver_timeout1s; … set $username $1; proxy_pass http://$username.photofile$request_uri;
Сервера: Proxy: 2 www (php):7 MySQL: 13 Fileserver 55 Backup 55 Прочие 3 Итого: 135 Посещаемость: Хиты: 4 500 000 Хосты: 200 000 В базе: Пользователей: 1000 000 Альбомов: 2 100 000 Фото: 70 000 000 Photofile в цифрах и фактах
Что еще используется: CARP – разделение IP для резервного проксирования mod_accel – для кеширования частых URL nginx кеширует популярные фото MySQL Master-Slaves для разделения запросов на «запись-чтение» Cron & rsync – для генерации статического контента Что планируется: Ввод дополнитетельных файлов-флагов «запаролен», «защищен» Переработка отдачи картинок (вынос preview на отдельные сервера) Вместо итогов
От стартапа до highload: Эволюция веб-проекта, илиКак победить нагрузку Вопросы? Антон Терехов, ведущий инженер-программистaterehov@rbc.ru