Загрузка видео «без единого разрыва»
Видео – один из самых популярных сервисов на Одноклассниках. Чего только не грузят наши пользователи: от милых сюжетов с детского утренника до снятых на видеорегистратор аварий. Поэтому быстро и стабильно работающая загрузка видео важна нам не только как одна из самых востребованных пользователями функций, но и как необходимое условие для генерации контента.
- В процессе загрузки у пользователя может пропадать соединение с нашим порталом (закрыл ноут, вошел в планшетом в лифт, сел аккумулятор на телефоне и т.п.)
- Старые устройства не поддерживают современные технологии загрузки (а у нас миллионы пользователей имеют слабые смартфоны или древние браузеры)
- При том количестве пользователей, которые есть у нас, задача о стабильной заливке видео превращается в задачу о стабильной загрузке видео в огромных объемах.

В этой статье мы расскажем о том, как мы победили все эти проблемы, опишем архитектуру нашего решения и причины, по которым она получилась именно такой.
Цифры решают всё
Ежедневно пользователи Одноклассников загружают почти двести тысяч видеороликов, а с аудиосообщениями (да-да, мы хостим аудиосообщения на том же кластере, что и видео) количество ежедневных загрузок превышает миллион.
Каждый день к нам на серверы попадает 15-20 терабайт нового видео, пиковый входящий трафик до 5 гигабит/сек а исходящий достигает 500 гигабит/сек. Большинство загружаемых видео — это короткие ролики, снятые пользователями на смартфоны. В то же время по суммарному объему загрузок в терабайтах web все еще остается лидером.
Изменилось и качество видео — камера формата Full HD давно стала стандартом комплектации любого мобильного устройства. По мере выхода из обращения старых смартфонов и приобретения новых доля загружаемых пользователями видеороликов в высоком и сверхвысоком разрешении неумолимо растет. За последний год число загружаемых роликов в качестве выше чем Full HD выросло более чем вдвое.

Разумеется, вместе с повышением качества растет и размер загружаемых видеофайлов: при переходе в качестве на 1 шаг вверх (720p —> 1080p, 1080p —> 1440p и т.д.) объем дискового пространства, занимаемого видео, возрастает примерно в два с половиной раза.
Давайте посмотрим, как реализована загрузка видео на портал в наших клиентах: в браузере (веб-версия), в мобильных приложениях (iOS/Android/WinPhone) и на мобильном портале.
Web-версия
Десятки миллионов пользователей. Кроме высоких нагрузок эти три слова означают, что мы должны поддерживать весь имеющийся на сегодняшний день зоопарк браузеров начиная с IE 8 и заканчивая еще не вышедшими ночными сборками Firefox.
Новые версии браузеров выходят чаще, чем раз в день. И понятно, что далеко не все наши пользователи спешат обновляться.
Как же нам удалось добиться стабильной работы портала в таком зоопарке браузеров? Fallback, fallback и еще раз fallback!
Клиентская часть нашего загрузчика видео написана на JavaScript c использованием фреймворков RequireJS, jQuery и замечательной библиотеки FileAPI от RubaXa из Mail.Ru.
FileAPI определяет, поддерживает ли пользовательский браузер HTML5. Если поддерживает, то все процедуры выполняются с помощью HTML5. Если не поддерживает — то FileAPI сам переключается на Flash. Также от браузера пользователя зависит и размер отправляемых chunk’ов.
Загрузка файлов сделана максимально удобной для юзера. Поддерживается джентльменский набор функций: drag&drop, одновременная загрузка нескольких файлов, автоматически возобновляемая загрузка, кнопка паузы, индикатор хода выполнения и т.д. и т.п.
С точки зрения пользователя все это богатство проявляется примерно так: пока идет загрузка, пользователь может ввести название для своего видеоролика, заполнить описание, выбрать видеоканал, задать теги и выбрать обложку. И, естественно, параллельно ходить по порталу — слушать музыку, шарить фотки и общаться в личке с друзьями.

До кучи FileAPI не накладывает никаких ограничений на размер загружаемых пользователем файлов. При желании можно загрузить даже терабайтный файл — какое-нибудь многочасовое видео в разрешении 4К. Другое дело, что ждать окончания загрузки пользователю придётся довольно долго даже при широком канале.
Большое внимание мы уделили автоматическому возобновлению загрузки. Конечно, для пользователей с надежным широкополосным подключением это не столь актуально, но далеко не все находятся в таких комфортных условиях. Об этом свидетельствует распределение загрузок видео по регионам России.

Логика этого процесса очень проста. FileAPI отправляет на upload-сервер один чанк и ждёт ответа. Если ответ не приходит в течение некоторого времени, клиент отправляет этот чанк снова, потом еще раз и еще раз, до тех пор, пока сервер не подтвердит успешное принятие. В свое время переход на FileAPI позволил нам в несколько раз сократить число ошибок во время загрузки.

Мобильные устройства
Если говорить о количестве загрузок видео на портал, то картина получается такая:

Мобильные пользователи могут загружать видео двумя способами — из браузера и из приложения. В мобильных браузерах загрузка возобновляется при обрыве сети, а в мобильных приложениях — еще и после перезагрузки телефона (например, в случае разрядки батареи).
Клиентская часть мобильного загрузчика сначала пытается залить сразу весь файл от начала до конца, используя XMLHttpRequest.send() . В случае обрыва соединения загрузчик пытается восстановить связь с сервером, опрашивая статус загрузки. Если удаётся получить ответ от сервера, загрузчик использует Blob.slice() для того, чтобы получить блок данных, следующий за последним успешно загруженным байтом.
При этом у некоторых устройств возникают проблемы с загрузкой блока напрямую из файла, поэтому используется FileReader.readAsArrayBuffer . Блок данных загружается в массив, который отправляется на сервер. Мы используем блоки не больше одного мегабайта, чтобы не обрушить браузер.
Если браузер поддерживает HTML5 Web Worker API, то загрузка осуществляется в отдельном потоке, что помогает сделать нам интерфейс более отзывчивым.
Чтобы показать пользователю прогресс загрузки, мы используем событие XMLHttpRequest.onprogress . В браузерах это событие реализовано как попало: некоторые отправляют тысячи событий каждую секунду, другие не отправляют их вообще. Для первых реализован троттлинг — большая часть событий игнорируется. Для вторых — происходит периодический опрос сервера (раз в 5 секунд).
Бэкенд загрузки видео. Архитектура
- 240 серверов для хранения пользовательских видео. Дисков там более 7000 — суммарно около 30 петабайт;
- метаданные и кэш развёрнуты еще на 36 машинах;
- за трансформацию видеороликов в наш внутренний формат отвечают еще 150 серверов;
- наконец, еще 36 машин используются для раздачи и загрузки видео.
- возобновление загрузки в течение нескольких суток после потери соединения;
- работоспособность сервиса при программных ошибках и аппаратных отказах;
- гарантия сохранности загруженных данных при отказе сервера или потере целого датацентра;
- высокая производительность.
За загрузку видео в Одноклассниках отвечает подсистема из 6 серверов, распределённых по трем датацентрам. Перед каждой парой upload-серверов в ДЦ стоит кластер LVS серверов (Linux Virtual Server — это модуль ядра Linux, который позволяет распределять IP трафик на любое количество физических серверов).
Для балансировки запросов между ДЦ используется DNS-GSLB (Global Server Load Balancing). Это сервера, которые резолвят доменное имя в IP наиболее разгруженного/доступного датацентра. В случае отказа одного из датацентров DNS-GSLB равномерно перераспределит нагрузку по оставшимся.

- пользователь инициирует загрузку, и сервер выдает ему URL для загрузки: http(s)://vu.mycdn.me/upload.do.
- далее DNS-GSLB разрешает доменное имя vu.mycdn.me в IP одного из LVSов (на рисунке в ip1);
- DNS-GSLB партиционирует пользователей по первым трем октетам их IP адреса. Таким образом, одному пользователю при повторных DNS резолвах выдается IP одного и того же датацентра. Выдача IP-адреса другого ДЦ произойдет только при его отказе или смене IP пользователя, что случается редко;
- далее LVS внутри ДЦ уже перенаправляет запросы к менее загруженному и доступному серверу;
- на LVS настроен IP affinity, который обеспечивает отправку всех пользовательских запросов к одному серверу.
Таким образом, получился стабильный маршрут, по которому пользователь грузит данные на конкретный upload-сервер.
- открывается новый буфер;
- запускается асинхронная операция сброса старого буфера в промежуточное распределенное хранилище.
В случае выхода из ротации одного из серверов внутри ДЦ LVS передаст все запросы доступному upload-серверу внутри ДЦ. Доступный upload server восстанавливает состояния клиентской сессии по данным, имеющимся в распределенном хранилище, и пользователь незамедлительно продолжает загрузку, в худшем случае с retry последних загруженных 10 Мб.

Когда пользователь переключается на другой сервер, может появиться «дырка» в последовательности загружаемых байт. В этом случае сервер возвращает специальный код ошибки 416 — «Range is not acceptable error, recoverable» с заголовком «X-Last-Known-Byte». Если клиент поддерживает данный заголовок, то он возобновляет загрузку с места, указанного в этом заголовке, а если нет — идет на один чанк назад.
В случае выхода ДЦ из строя (ситуация более редкая, чем выход из строя сервера) клиентская библиотека загрузки файлов (например, FileAPI) будет в течение «ретрай-времени» пытаться возобновить загрузку по IP LVSа, расположенного в упавшем ДЦ. Все новые загрузки продолжатся через доступные ДЦ.

Отказоустойчивость бэкэнда
- сценарий с выходом датацентра из строя;
- сценарий с перегрузкой по диску;
- сценарий с перегрузкой по трафику.
В общем случае надо еще проверять сценарий с перегрузкой по CPU, но в нашем случае CPU хватает с большим запасом, поэтому его мы в данный момент всерьез не рассматриваем.
Сценарий с перегрузкой по входящему трафику для нас тоже малореален. Каналы, которые мы приобретаем в датацентрах, симметричны, и поскольку наш download трафик превосходит наш upload трафик примерно в 100 раз, то перегрузку по upload мы тоже всерьез не считаем за угрозу. Основная наша защита здесь — рубильники, которые отключают части пользователей загрузку видео. Таких частей (партиций) у нас 256, поэтому мы можем регулировать количество пользователей, которые могут загружать (или наоборот просматривать) видео, с шагом меньше, чем 0,4%.
Работоспособность системы на случай отказа любого датацентра регулярно тестируется методом имитации. В простейшем случае мы просто останавливаем работу наших приложений на серверах в одном из ДЦ и смотрим, как сервис работает на двух оставшихся в бою ДЦ.
Так же у нас случаются всплески активности пользователей, когда они начинают массово загружать видео. Обычно это происходит на праздники и в ходе спортивных и культурных событий.
Факап со шпинделями
В этом году нам представился случай оценить степень отказоустойчивости нашего сервиса.
После Парада Победы 9 мая начался резкий рост загрузок видеозаписей парада и салюта. Мы не ожидали трехкратного увеличения пикового трафика, поэтому дисковая подсистема временного хранилища очень быстро оказалась загруженной на 100%. Upload-сервера стали получать ошибки при попытке сбросить чанк во временное хранилище — хранилище не отвечало. У каждой сессии есть буфер, в который принимаются входящие данные. Буферы жрут место, поэтому место в оперативке для сессий на upload-серверах тоже быстро закончилось…
- клиентский загрузчик хотел загрузить чанк
- в буфере сессии не было места
- сервер возвращал клиенту возобновляемую ошибку.
В течение примерно двух часов upload-сервера сбрасывали загружаемые данные на предельной скорости последовательной записи на диски временного хранилища. Проблема амортизировалась за счет буфера сессии на upload-серверах. Иногда клиентские загрузчики получали ошибку и возобновляли загрузку через некоторый интервал.
Итоги были таковы: в целом скорость загрузки на портал просела примерно вдвое, но отказа сервиса не произошло, и все пользователи в итоге догрузили свое видео.
Оценка домена
Попробуйте полную версию Анализа сайта: найдите ошибки на главной и внутренних страницах и исправьте их с помощью советов сервиса. Ежедневный аудит и проверка позиций помогут оценить результаты.
Бесплатная версия:
Платная:
Важные события
Чек-лист
Параметры домена
Описание
Индекс качества сайта — это показатель того, насколько полезен ваш сайт для пользователей с точки зрения Яндекса.
При расчете индекса качества учитываются размер аудитории сайта, поведенческие факторы и данные сервисов Яндекса. Значение индекса регулярно обновляется.
Если у сайта есть зеркало, то показатель неглавного зеркала сайта будет равен показателю главного.
Показатель ИКС поддомена сайта, как правило, равен показателю основного домена.
Дополнительная информация
Статьи по теме
Данные теста были получены 17.12.2021 17:33
Выбор пользователей 5 из 5
Популярный сайт 4 из 5
Описание
Рядом с адресом сайта в результатах поиска Яндекса могут появляться знаки, основанные на данных о поведении пользователей. Такие знаки могут свидетельствовать об удовлетворенности пользователей и их доверии к сайту.
Популярный сайт — сайт получает этот знак, если имеет высокую посещаемость и постоянную аудиторию.
Выбор пользователей — знак получают сайты с высокой степенью вовлеченности и лояльности пользователей по данным Яндекса.
Статьи по теме
Данные теста были получены 17.12.2021 17:33
Описание
Примерное количество проиндексированных страниц в выдаче Яндекса можно посмотреть через оператор site:, что мы и делаем. Он покажет результат поиска по URL сайта, но точную цифру страниц в индексе выдавать не обязан.
Точные данные Яндекс отображает в Яндекс.Вебмастере. График изменений количества находится в разделе «Индексирование сайта» — «Страницы в поиске».
Данные теста были получены 17.12.2021 17:33
Описание
Сколько страниц сайта Google точно проиндексировал, узнать невозможно. Поисковик не ведет базу данных по URL-адресам.
Примерное количество страниц в выдаче покажет оператор site:, на который мы ориентируемся. Число может быть искажено страницами, которые запрещены к индексу в robots.txt, но попали в выдачу из-за внешних ссылок на них.
Чуть более точное количество покажет раздел «Статус индексирования» в Google Search Console, но и эти данные могут быть искажены из-за применения фильтров.
Данные теста были получены 17.12.2021 17:36
Описание
Примерное количество проиндексированных страниц в выдаче Яндекса можно посмотреть через оператор site:, что мы и делаем. Он покажет результат поиска по URL сайта, но точную цифру страниц в индексе выдавать не обязан.
Точные данные Яндекс отображает в Яндекс.Вебмастере. График изменений количества находится в разделе «Индексирование сайта» — «Страницы в поиске».
Данные теста были получены 17.12.2021 17:33
Рейтинг домена — 25 / 100
Описание
PR-CY Rank — рейтинг для оценки перспективности сайтов в качестве доноров для линкбилдинга. При формировании рейтинга мы анализируем трафиковые и трастовые параметры, а также ссылочный профиль сайта.
Влияние — потенциал влияния сайта на продвижение. Если влияние слабое, то слабым будет как отрицательный эффект (если рейтинг низкий), так и положительный (если рейтинг высокий) и наоборот. Потенциал влияния основан на размере постоянной аудитории сайта.
Ссылочный фактор — вычисляется на основе соотношения входящих и исходящих ссылок на сайт, значений Trust Rank, Domain Rank и др.
Трафиковый фактор — вычисляется на основании объёма и динамики трафика (отрицательная динамика портит рейтинг, положительная динамика — повышает).
Трастовый фактор — анализирует множество параметров, таких как “ИКС”, доля поискового трафика в общем трафике, адаптацию под мобильные устройства и множество других факторов, признанных поисковыми системами, как значимые для ранжирования.
Mycdn.me: что это за сайт?
В последнее время в интернете появилось огромное количество мошеннических сайтов. Причем не всегда, когда речь идет о сайтах, созданных мошенниками, имеется ввиду получение денежных средств обманным путем обычных пользователей. Иногда мошеннические сайты как бы “вымогают” конфиденциальную информацию пользователей, например, паспортные данные, логины и пароли для входа в социальные сети и так далее. И одним из таких мошеннических сайтов является mycdn.me.
Что такое mycdn.me?
Mycdn.me – сайт, который заражает компьютер обычного пользователя опасными вирусами, например, трояном, который впоследствии “шпионит” в интернете за человеком, ворует личные данные. Но в основном речь идет о данных для входа на страницы в социальных сетях, например, Вконтакте, Одноклассники, Инстаграм и так далее. 
Как происходит заражение вирусом через этот сайт?
Так как Mycdn.me не является популярной веб-страницей в интернете, то человеку крайне затруднительно самому найти его среди прочих страниц и зайти без особых целей, не зная, что это за сайт. Именно поэтому мошенники, которые и создали этот сайт, самостоятельно рассылают своим жертвам ссылку, ведущую на mycdn.me, под предлогом посмотреть смешной видеоролик.
Когда пользователь переходит по данной ссылке, его “перебрасывает” на сайт непонятного содержания, или наоборот, браузер выдает ошибку для входа. В любом случае, человек вскоре уходит с сайта, понимая, что его обманули, но не понимает, с какой целью. Однако осознание происходит позже, когда спустя время его страницы массово взламывают.

Когда человек переходит на Mycdn.me, на его компьютер скачивается вирус втайне от самого пользователя. Обычно этот вирус является трояном. Позже человек забывает об этой ситуации и как ни в чем не бывало заходит на свои страницы в социальных сетях, переписывается с друзьями, слушает музыку, листает ленту новостей – не важно.
Все это время вирус “следит” за пользователем, параллельно “передает” всю выслеженную информацию мошенникам. Дальше интернет-мошенники либо продают полученные данные другим людям, либо используют полученную информацию в корыстных целях. Например, взламывают аккаунты и перепродают их.

Как обезопасить себя от взлома?
На сегодняшний день существуют два способа спасти свой компьютер от вируса: скачать надежный антивирус и не заходить на незнакомые веб-страницы, не переходить по ссылкам, которые присылаются незнакомцами. Однако важно помнить, что антивирус – не панацея, вирусы постоянно совершенствуются, поэтому далеко не каждый антивирус может вовремя заметить потенциальную угрозу, спасти компьютер от вируса.