Архитектура	
  Яндекс.Фоток	
  
Алексей	
  Захаров	
  
Руководитель	
  группы	
  серверной	
  разработки	
  



Я.Субботник,	
  Москва,	
  28	
  июля	
  2012	
  года	
  
Яндекс.Фотки	
  -­‐	
  это	
  
	
  
—        Один	
  из	
  крупнейших	
  фотохостингов	
  рунета	
  
	
  
—  Хранение	
  оригиналов,	
  	
  неограниченное	
  пространство	
  
—  Более	
  270	
  млн	
  фотографий	
  
—  Каждый	
  день	
  более:	
  
         §    миллиона	
  уникальных	
  посетителей	
  
         §    одиннадцати	
  миллионнов	
  кликов	
  
         §    300	
  тысяч	
  новых	
  фоток	
  
—  Backend:	
  в	
  среднем	
  >	
  2000	
  RPS	
  

 2	
  
Технологии	
  в	
  крупную	
  клетку	
  
	
  
	
  
—       Frontend:	
  Xscript	
  (XSL-­‐шаблонизатор),	
  Nginx	
  
—  Backend:	
  Java;	
  Spring,	
  Jeoy	
  
—  Базы	
  Данных:	
  Mysql,	
  MongoDb	
  
—  Собственный	
  сторадж	
  для	
  хранения	
  изображений	
  	
  
—  Собственный	
  распределённый	
  scheduler	
  



3	
  
Загрузка	
  фотки	
  




4	
  
Загрузка	
  




5	
  
Загрузка:	
  основы	
  
	
  
	
  
—       HTTP	
  POST,	
  mul•part/form-­‐data	
  
—  Клиент	
  загрузчика	
  на	
  Flash	
  и	
  JS	
  
—  HTTP	
  сервер	
  Jeoy	
  
—  Несколько	
  загрузчиков	
  в	
  разных	
  датацентрах	
  
	
  



6	
  
Выбор	
  загрузчика	
  

        ZooKeeper!	
  




7	
  
Выбор	
  загрузчика	
  



        Up1	
     Up2	
          Up3	
      Up4	
     Up5	
  




                            ZooKeeper	
  

8	
  
Загрузка:	
  нарезка	
  скриншотов	
  
ImageMagick	
  
	
  convert -limit thread 1 $FILE -print 'orig-format:%mnorig-size:%wx%hn%
    [EXIF:*]' -rotate 90
     '(' +clone +profile '!icm,!icc,*' -resize '500x346!' -unsharp
    0.61x0.43+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/L -print 'L:%wx%h
    n' ')'
    '(' +clone +profile '!icm,!icc,*' -resize '300x208!' -unsharp
    0.61x0.43+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/M -print 'M:%wx%h
    n' +delete ')'
    '(' +clone +profile '!icm,!icc,*' -resize '150x104!' -unsharp
    1.1x0.9+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/S -print 'S:%wx%h
    n' +delete ')’
     '(' +clone +profile '!icm,!icc,*' -resize '100x69!' -unsharp
    1.1x0.9+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/XS -print 'XS:%wx%h
    n' +delete ')’
     '(' +clone +profile '!icm,!icc,*' -resize '75x75^' -gravity center -extent
    75x75 -unsharp 1.1x0.9+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/XXS
    -print 'XXS:%wx%hn' +delete ')’
     '(' +clone +profile '!icm,!icc,*' -resize '50x50^' -gravity center -extent
    50x50 -unsharp 1.1x0.9+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/XXXS
    -print 'XXXS:%wx%hn' +delete ')' null:


9	
  
Разбор	
  метаинформации	
  
	
  
	
  
—        Метаинформация	
  из	
  mul•part:	
  название,	
  
         описание,	
  теги,	
  имя	
  файла,	
  гео-­‐координаты	
  
—  Из	
  EXIF:	
  ориентация,	
  гео-­‐координаты,	
  теги,	
  
   название	
  
—  Агрегация	
  всего	
  и	
  создание	
  записи	
  в	
  БД	
  




10	
  
Хранение	
  метаинформации	
  
	
  	
  
	
  
—          Старый	
  добрый	
  MySql	
  
           Шардирование	
  на	
  уровне	
  приложения:	
  каждый	
  
	
  
— 
           пользователь	
  приписан	
  определённому	
  шарду	
  
—  Партицирование.	
  Борьба	
  c	
  большим	
  размером	
  
   индексов.	
  
—  Общие	
  для	
  всех	
  данные	
  –	
  в	
  отдельной	
  базе	
  




11	
  
Шардирование	
  и	
  партицирование	
  
	
  	
  
	
  
	
  




12	
  
Отказоустойчивость	
  
	
  
—        Система	
  нескольких	
  датацентров	
  
	
  
—        У	
  каждой	
  базы	
  –	
  мастер	
  и	
  реплики	
  в	
  разных	
  датацентрах	
  

—  При	
  выходе	
  из	
  строя	
  датацентра	
  сервис	
  переходит	
  в	
  режим	
  
   частичного	
  read-­‐only	
  

—  Учитывается,	
  что	
  часть	
  пользователей	
  может	
  находиться	
  в	
  
   read-­‐only	
  

—  Минимизация	
  видимых	
  эффектов	
  read-­‐only	
  

—  Движение	
  в	
  сторону	
  систем	
  с	
  mul•-­‐master	
  репликацией	
  


13	
  
Отказоустойчивость	
  
Другие	
  доклады	
  
	
   Павел	
  Пушкарёв:	
  "Отказоустойчивость	
  сервисов”,	
  
— 
         hop://download.yandex.ru/company/experience/subbotnik/
         piter_pushkarev.pdf	
  

—  Екатерина	
  Войденко:	
  "Горизонтальное	
  маcштабирование	
  
   MySql”,	
  hop://clubs.ya.ru/yasubbotnik/replies.xml?item_no=274	
  

	
  




14	
  
Сторадж	
  –	
  что	
  это?	
  
	
  	
  
	
  
	
  
	
  
                          	
  	
  	
  




15	
  
Сторадж	
  
	
  	
  
	
  
—          Оптимизирован	
  для	
  хранения	
  файлов	
  
           Основан	
  на	
  файловой	
  системе	
  
	
  
— 
—  Простой	
  HTTP-­‐протокол	
  доступа	
  
—  Данные	
  хранятся	
  в	
  двух	
  экземплярх	
  в	
  разных	
  
   датацентрах	
  




16	
  
Сторадж	
  
	
  	
  
	
  
—          Прозрачный	
  доступ	
  к	
  данным	
  через	
  специальные	
  
           proxy-­‐сервера	
  
	
  
—          Простая	
  и	
  надёжная	
  схема	
  
—  Разработан	
  внутри	
  Яндекса	
  




17	
  
Показ	
  фотки	
  




18	
  
 Страница	
  просмотра	
  фотки	
  




19	
  
Формирование	
  HTML-­‐страницы	
  
Всё	
  как	
  у	
  людей	
  
—  Frontend:	
  разбор	
  запроса,	
  выстраивание	
  цепочки	
  
   вызовов	
  backend’ов	
  
—  Backend:	
  взаимодействие	
  с	
  БД,	
  обработка	
  
   данных,	
  формирование	
  XML-­‐ответа	
  	
  
—  Frontend:	
  сбор	
  ответов	
  с	
  backend’ов,	
  наложение	
  
   XSL,	
  формирование	
  итоговой	
  HTML-­‐разметки	
  
—  Сторадж:	
  отдача	
  фоток	
  по	
  прямым	
  URL	
  



20	
  
Получение	
  фотки	
  со	
  стораджа	
  
	
  
	
   http://img-fotki.yandex.ru/get/6601/161556715.1c/
	
   0_7e678_a7812eef_XL
	
  
—        Запрос	
  приходит	
  на	
  proxy,	
  из	
  URL	
  однозначно	
  определяет	
  
         номер	
  стораджа	
  

—  Прокси	
  делает	
  запрос	
  на	
  доступные	
  копии	
  стораджа	
  

—  Сторадж	
  по	
  URL	
  определяет	
  номер	
  диска,	
  директорию	
  и	
  имя	
  
   файла	
  

—  Прокси	
  проксирует	
  через	
  себя	
  ответ	
  сторджа	
  и	
  отдаёт	
  
   пользователю	
  

21	
  
Прокси	
  и	
  стораджа	
  

                  Proxy01f	
                      Proxy02g	
  



         Storage01e	
            Storage03g	
            Storage05g	
  



         Storage01f	
            Storage03f	
            Storage05e	
  




22	
  
Механизм	
  асинхронного	
  
выполнения	
  заданий	
  




23	
  
Scheduler	
  




24	
  
Scheduler	
  
Задачи	
  по	
  расписанию	
  
—  Выбор	
  фото	
  дня	
  
—  Подготовка	
  данных	
  для	
  голосования	
  
—  Составление	
  ленты	
  новых	
  интересных	
  
—  Экспорты	
  в	
  картинки,	
  в	
  карты	
  




25	
  
Scheduler	
  
Одноразовые	
  задачи	
  
—  Удаление	
  фоток	
  альбома	
  
—  Пересчёт	
  счётчиков	
  
—  Распознавание	
  лиц	
  
—  Перестроение	
  облака	
  тегов	
  
—  Отсылка	
  почтовых	
  сообщений	
  




26	
  
Scheduler	
  
Что	
  внутри	
  
—  ZooKeeper:	
  выбор	
  мастер-­‐worker’а,	
  проверка	
  
   работоспособности,	
  балансировка	
  	
  
—  MongoDb:	
  хранение	
  параметров	
  задач	
  
—  Actor	
  поверх	
  neoy:	
  передача	
  параметров	
  задачи	
  
   на	
  конкретный	
  worker	
  и	
  чтение	
  результатов	
  




27	
  
Scheduler	
  
	
  	
  
                  Worker1	
  




  Worker2	
     ZooKeeper	
     Mongo
                                 Db	
  



                  Worker3	
  




28	
  
Внешнее	
  API	
  Фоток	
  




29	
  
Внешнее	
  API	
  
   	
  	
  
—  Другой	
  вид	
  frontend’а	
  
—  Отдельное	
  приложение	
  на	
  Python	
  &	
  Django	
  
—  Используется	
  выдача	
  обычных	
  backend’ов	
  	
  
—  Выходные	
  форматы:	
  ATOM	
  и	
  JSON	
  
—  Стабильное,	
  обратная	
  совместимость	
  
	
  


   30	
  
Внешнее	
  API	
  
	
  Что	
  можно	
  делать	
  
—  Получать	
  информацию	
  о	
  конкретной	
  фотке	
  
—  Получать	
  список	
  фоток	
  в	
  альбоме,	
  список	
  альбомов	
  
—  Изменять	
  информацию	
  о	
  конкретной	
  фотке	
  
—  Загружать	
  новые	
  фотки	
  
—  Получать	
  коллекции	
  фоток	
  дня,	
  популярных,	
  свежих	
  
   &	
  интересных	
  
—  Подробнее:	
  hop://api.yandex.ru/fotki/	
  

31	
  
Пример	
  JSON	
  выдачи	
  
	
  	
  




32	
  
Пример	
  использования	
  
	
  	
  




33	
  
Пример	
  использования	
  
	
  hap://fotker.fdzn.net/	
  
	
  




34	
  
Немного	
  цифр	
  напоследок	
  
	
  	
  
—  Frontend:	
  25	
  серверов	
  Intel	
  Xeon,	
  8-­‐12	
  ядра	
  
—  Backend:	
  25	
  серверов	
  Intel	
  Xeon,	
  8-­‐12	
  ядра	
  
—  API:	
  8	
  серверов	
  по	
  8	
  ядер	
  
—  Загрузчики:	
  8	
  серверов	
  по	
  8	
  ядер	
  
—  Стораджа:	
  72	
  сервера	
  Xeon	
  по	
  4-­‐12	
  ядра;	
  на	
  
   каждом	
  15-­‐30	
  дисков	
  объёмом	
  500Гб	
  –	
  2Тб	
  
—  MySql:	
  62	
  сервера	
  8-­‐12	
  ядер,	
  48-­‐96	
  Гб	
  ОЗУ	
  
	
  
35	
  
Всё!	
  
          	
  
          	
  


36	
  
Вопросы?	
  
             	
  



37	
  
Алексей	
  Захаров	
  
Руководитель	
  группы	
  серверной	
  
разработки	
  Яндекс.Фоток	
  

ayza@yandex-­‐team.ru	
  

	
  

Алексей Захаров "Архитектура Яндекс.Фоток"

  • 1.
    Архитектура  Яндекс.Фоток   Алексей  Захаров   Руководитель  группы  серверной  разработки   Я.Субботник,  Москва,  28  июля  2012  года  
  • 2.
    Яндекс.Фотки  -­‐  это     —  Один  из  крупнейших  фотохостингов  рунета     —  Хранение  оригиналов,    неограниченное  пространство   —  Более  270  млн  фотографий   —  Каждый  день  более:   §  миллиона  уникальных  посетителей   §  одиннадцати  миллионнов  кликов   §  300  тысяч  новых  фоток   —  Backend:  в  среднем  >  2000  RPS   2  
  • 3.
    Технологии  в  крупную  клетку       —  Frontend:  Xscript  (XSL-­‐шаблонизатор),  Nginx   —  Backend:  Java;  Spring,  Jeoy   —  Базы  Данных:  Mysql,  MongoDb   —  Собственный  сторадж  для  хранения  изображений     —  Собственный  распределённый  scheduler   3  
  • 4.
  • 5.
  • 6.
    Загрузка:  основы       —  HTTP  POST,  mul•part/form-­‐data   —  Клиент  загрузчика  на  Flash  и  JS   —  HTTP  сервер  Jeoy   —  Несколько  загрузчиков  в  разных  датацентрах     6  
  • 7.
  • 8.
    Выбор  загрузчика   Up1   Up2   Up3   Up4   Up5   ZooKeeper   8  
  • 9.
    Загрузка:  нарезка  скриншотов   ImageMagick    convert -limit thread 1 $FILE -print 'orig-format:%mnorig-size:%wx%hn% [EXIF:*]' -rotate 90 '(' +clone +profile '!icm,!icc,*' -resize '500x346!' -unsharp 0.61x0.43+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/L -print 'L:%wx%h n' ')' '(' +clone +profile '!icm,!icc,*' -resize '300x208!' -unsharp 0.61x0.43+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/M -print 'M:%wx%h n' +delete ')' '(' +clone +profile '!icm,!icc,*' -resize '150x104!' -unsharp 1.1x0.9+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/S -print 'S:%wx%h n' +delete ')’ '(' +clone +profile '!icm,!icc,*' -resize '100x69!' -unsharp 1.1x0.9+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/XS -print 'XS:%wx%h n' +delete ')’ '(' +clone +profile '!icm,!icc,*' -resize '75x75^' -gravity center -extent 75x75 -unsharp 1.1x0.9+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/XXS -print 'XXS:%wx%hn' +delete ')’ '(' +clone +profile '!icm,!icc,*' -resize '50x50^' -gravity center -extent 50x50 -unsharp 1.1x0.9+1.0+0.005 -quality 93 -write jpeg:/Users/ayza/tmp/XXXS -print 'XXXS:%wx%hn' +delete ')' null: 9  
  • 10.
    Разбор  метаинформации       —  Метаинформация  из  mul•part:  название,   описание,  теги,  имя  файла,  гео-­‐координаты   —  Из  EXIF:  ориентация,  гео-­‐координаты,  теги,   название   —  Агрегация  всего  и  создание  записи  в  БД   10  
  • 11.
    Хранение  метаинформации         —  Старый  добрый  MySql   Шардирование  на  уровне  приложения:  каждый     —  пользователь  приписан  определённому  шарду   —  Партицирование.  Борьба  c  большим  размером   индексов.   —  Общие  для  всех  данные  –  в  отдельной  базе   11  
  • 12.
  • 13.
    Отказоустойчивость     —  Система  нескольких  датацентров     —  У  каждой  базы  –  мастер  и  реплики  в  разных  датацентрах   —  При  выходе  из  строя  датацентра  сервис  переходит  в  режим   частичного  read-­‐only   —  Учитывается,  что  часть  пользователей  может  находиться  в   read-­‐only   —  Минимизация  видимых  эффектов  read-­‐only   —  Движение  в  сторону  систем  с  mul•-­‐master  репликацией   13  
  • 14.
    Отказоустойчивость   Другие  доклады     Павел  Пушкарёв:  "Отказоустойчивость  сервисов”,   —  hop://download.yandex.ru/company/experience/subbotnik/ piter_pushkarev.pdf   —  Екатерина  Войденко:  "Горизонтальное  маcштабирование   MySql”,  hop://clubs.ya.ru/yasubbotnik/replies.xml?item_no=274     14  
  • 15.
    Сторадж  –  что  это?                   15  
  • 16.
    Сторадж         —  Оптимизирован  для  хранения  файлов   Основан  на  файловой  системе     —  —  Простой  HTTP-­‐протокол  доступа   —  Данные  хранятся  в  двух  экземплярх  в  разных   датацентрах   16  
  • 17.
    Сторадж         —  Прозрачный  доступ  к  данным  через  специальные   proxy-­‐сервера     —  Простая  и  надёжная  схема   —  Разработан  внутри  Яндекса   17  
  • 18.
  • 19.
  • 20.
    Формирование  HTML-­‐страницы   Всё  как  у  людей   —  Frontend:  разбор  запроса,  выстраивание  цепочки   вызовов  backend’ов   —  Backend:  взаимодействие  с  БД,  обработка   данных,  формирование  XML-­‐ответа     —  Frontend:  сбор  ответов  с  backend’ов,  наложение   XSL,  формирование  итоговой  HTML-­‐разметки   —  Сторадж:  отдача  фоток  по  прямым  URL   20  
  • 21.
    Получение  фотки  со  стораджа       http://img-fotki.yandex.ru/get/6601/161556715.1c/   0_7e678_a7812eef_XL   —  Запрос  приходит  на  proxy,  из  URL  однозначно  определяет   номер  стораджа   —  Прокси  делает  запрос  на  доступные  копии  стораджа   —  Сторадж  по  URL  определяет  номер  диска,  директорию  и  имя   файла   —  Прокси  проксирует  через  себя  ответ  сторджа  и  отдаёт   пользователю   21  
  • 22.
    Прокси  и  стораджа   Proxy01f   Proxy02g   Storage01e   Storage03g   Storage05g   Storage01f   Storage03f   Storage05e   22  
  • 23.
  • 24.
  • 25.
    Scheduler   Задачи  по  расписанию   —  Выбор  фото  дня   —  Подготовка  данных  для  голосования   —  Составление  ленты  новых  интересных   —  Экспорты  в  картинки,  в  карты   25  
  • 26.
    Scheduler   Одноразовые  задачи   —  Удаление  фоток  альбома   —  Пересчёт  счётчиков   —  Распознавание  лиц   —  Перестроение  облака  тегов   —  Отсылка  почтовых  сообщений   26  
  • 27.
    Scheduler   Что  внутри   —  ZooKeeper:  выбор  мастер-­‐worker’а,  проверка   работоспособности,  балансировка     —  MongoDb:  хранение  параметров  задач   —  Actor  поверх  neoy:  передача  параметров  задачи   на  конкретный  worker  и  чтение  результатов   27  
  • 28.
    Scheduler       Worker1   Worker2   ZooKeeper   Mongo Db   Worker3   28  
  • 29.
  • 30.
    Внешнее  API       —  Другой  вид  frontend’а   —  Отдельное  приложение  на  Python  &  Django   —  Используется  выдача  обычных  backend’ов     —  Выходные  форматы:  ATOM  и  JSON   —  Стабильное,  обратная  совместимость     30  
  • 31.
    Внешнее  API    Что  можно  делать   —  Получать  информацию  о  конкретной  фотке   —  Получать  список  фоток  в  альбоме,  список  альбомов   —  Изменять  информацию  о  конкретной  фотке   —  Загружать  новые  фотки   —  Получать  коллекции  фоток  дня,  популярных,  свежих   &  интересных   —  Подробнее:  hop://api.yandex.ru/fotki/   31  
  • 32.
  • 33.
  • 34.
    Пример  использования    hap://fotker.fdzn.net/     34  
  • 35.
    Немного  цифр  напоследок       —  Frontend:  25  серверов  Intel  Xeon,  8-­‐12  ядра   —  Backend:  25  серверов  Intel  Xeon,  8-­‐12  ядра   —  API:  8  серверов  по  8  ядер   —  Загрузчики:  8  серверов  по  8  ядер   —  Стораджа:  72  сервера  Xeon  по  4-­‐12  ядра;  на   каждом  15-­‐30  дисков  объёмом  500Гб  –  2Тб   —  MySql:  62  сервера  8-­‐12  ядер,  48-­‐96  Гб  ОЗУ     35  
  • 36.
    Всё!       36  
  • 37.
  • 38.
    Алексей  Захаров   Руководитель  группы  серверной   разработки  Яндекс.Фоток   ayza@yandex-­‐team.ru