1. История одного pet-project
или
Как мы строили распределенное хранилище файлов для веба и что из этого вышло
Данила Штань, 66.ru
danila@shtan.ru
2. Было: инфраструктура
• Много NFS
• Разные проекты — разные решения, legacy
• Проблемы с деплоем
• Разработчики не всегда понимают, что можно, а чего нельзя
• Резервные копии
3. Задача: инфраструктура
• Унификация
• Масштабирование
• Резервные копии
• Отказаться от NFS
• Постараться не покупать новое оборудование
4. Было: разработка
• У каждого свой подход
• Много раз решаем одну и ту же задачу
• Иногда очень странно решаем одну и ту же задачу
5. Задача: разработка
• “Защита от дурака”
• Унификация подходов
• Избавление от рутины
6. О чем мы, собственно?
• 6.5 терабайт
• Файлы от 10кб до 300мб
• 180rps, 200 мегабит — стандартный фон в рабочие часы
• 800rps, 700 мегабит — пиковые нагрузки
10. Подытожим требования
• Больше одной копии файла
• Горизонтально-масштабируемая
• Основное предназначение — отдавать файлы по http
11. Подытожим желания
• Прибрать рутинные операции
• “Черный ящик”
• Небольшое количество компонентов
• Знакомый нам или широко используемый стек технологий
14. Давайте писать своё?
• GlusterFS — в новой версии есть Object Storage, но beta
• MogileFS — похоже на правду, но Perl
• HDFS — совсем не для наших целей и нет HA
• CloudStore — HDFS на C
• Lustre — энтерпрайз такой энтерпрайз
16. Сервис
• Python+MongoDB
• Ограничение доступа
• Плюшки для разработчиков — r/o аккаунты к production данным
• RESTful API:
• POST / — добавить файл
• GET /<id> — получить метаданные, ссылку и время жизни ссылки
17. DFS и http-сервер
• nginx — нужны веские причины, чтобы отказаться
• GlusterFS как наиболее вероятный кандидат
• не самая тривиальная настройка
• как делать off-site бэкап?
18. DFS и http-сервер
• У нас уже есть MongoDB!
• replica set
• off-site replica
• У MongoDB есть спецификация GridFS
• Для nginx есть модуль nginx_gridfs
19. Тесты, попытки применить
• Стандартный storage-сервер через nginx-gridfs — 600rps
• Проблема не в Mongo, C-драйвер не умеет работать асинхронно
• nginx-gridfs — не очень активно развивается
• nginx-gridfs — не поддерживает HTTP Range запросы
• Мы не готовы использовать собственный C-код в production
20. И снова напишем сами
• WSGI-приложение, 300 строк кода
• Werkzeug
• Берет ObjectID и отдает файл, умеет отвечать 200, 206, 404
• Умеет работать с replica set
• Тесты — 400 rps, двух только-только хватит на пиковые нагрузки
21. nginx наше все
• proxy_pass, proxy_cache
• требует отдельного железа, но у нас уже есть
• тесты
• 2.5 k rps при размере кэша в 20 gb
• 2.5 k rps при размере кэша в 3 gb
22. nginx наше все
• proxy_pass, proxy_cache
• требует отдельного железа, но у нас уже есть
• тесты (после “прогрева” кэша)
• 2.5 k rps при размере кэша в 20 gb
• 2.5 k rps при размере кэша в 3 gb
• 2.5 k rps это гигабит на тестовых данных
23. Получилось хорошо
• Знакомый стек технологий
• Достаточно быстро
• Достаточно гибко
• Достаточно изолировано
• Компонент раздающий файлы можно не трогать
24. Что дальше
• Вынести рутинные операции — ресайз картинок, конвертацию
• GET /<id>?height=<newheight>
• GET /<id>?encode=png или даже GET /<id>?encode=flv
• Главное вовремя остановиться