company_banner

Как устроен Яндекс.Диск: загрузчик

    Мы уже рассказывали о том, как был сделан выбор в пользу протокола WebDAV, а также о проблемах, возникающих на серверной стороне, и их решении.

    Сегодня — о том, как устроен загрузчик файлов на сервис, и о чём нужно не забывать, когда пишешь его для сервисов масштаба Яндекс.Диска.

    image

    Для начала рассмотрим архитектуру сервиса в целом. В основе сервиса лежит mpfs – Магическая проксирующая файловая система. Это бэкэнд, который содержит в себе всю бизнес-логику по работе с файлами, папками, каталогами: все операции по копированию или созданию новых файлов идут через эту систему. Эта же система отвечает и за хранение метаданных.

    Синхронизация с клиентами происходит по протоколу WebDAV. На его основе мы создали клиенты под Windows, OS X и мобильные платформы. Но при необходимости с помощью WebDAV можно настроить синхронизацию с любым приложением, поддерживающим данный протокол.

    Рисунок 1. Архитектура Яндекс.Диска

    Через веб-интерфейс пользователям доступны те же функции, что и через клиенты: загрузка, скачивание и просмотр файлов. Кроме того, через наш внутренний API производится взаимодействие с другими сервисами Яндекса. На данный момент это Народ, Почта, Музыка и Браузер. Например, через мобильный клиент Яндекс.Музыки можно получить доступ к загруженным в Диск аудиофайлам.

    Меч-кладенец

    Но вернемся к нашей основной теме – загрузчику. У нас он проходит под кодовым названием «Кладун». Мы долго не могли подобрать подходящего русскоязычного аналога для пары uploader-downloader, но в итоге остановились на сочетании Кладун-Заберун.

    Рисунок 2. Архитектура загрузчика

    Нетрудно догадаться, что основной задачей Кладуна является загрузка и размещение файлов с метаданными в хранилища. Начинается все с того, что пользователь через клиент или веб-интерфейс добавляет в папку на Диске файл. На сервер посылается запрос, который передается в mpfs. Файловая система возвращает назад ссылку на конкретную машину из кластера загрузчиков, после чего на нее заливается файл. В итоге он попадает в хранилище, далее статус загрузки передается в mpfs, и она сохраняет все метаданные. На каждой машине-загрузчике хранится своя локальная очередь. Это позволяет повысить надежность процесса загрузки. При отключении одного из дата-центров или какаой-нибудь машины в кластере, на всех остальных машинах файлы продолжат заливаться. А на выключавшихся машинах процесс заливки продолжится сразу после их перезапуска.
    Помимо наиболее очевидной своей функции – забрать файл у пользователя и положить его в хранилище – загрузчик умеет также переносить файлы между сервисами Яндекса.

    Стадии задач

    Каждая задача, выполняемая загрузчиком делится на несколько стадий. Первым делом после получения файла от пользователя или сервиса производится подсчет контрольных сумм. В дальнейшем они будут использоваться при синхронизации файла для отслеживания изменений. Так как наш Кладун поддерживает загрузку изменений патчами, каждый файл разбивается на несколько блоков, для каждого из которых генерируется отдельная контрольная сумма. Если файл после заливки был слегка отредактирован, то при синхронизации перезалит он будет не целиком: заново будут загружены только те блоки, в которых произошли изменения и контрольные суммы перестали совпадать. Нечто подобное используется в системах управления версиями.

    Использование хэш-сумм также позволяет избежать повторной загрузки уже залитых другими пользователями файлов. К примеру, если вы хотите залить на Диск какой-либо популярный видеоролик или установочный файл, а в хранилище Диска уже есть файл с идентичной контрольной суммой, использоваться будет он. Таким образом, даже очень крупные файлы могут быть помещены в хранилище буквально за пару секунд. Это выгодно обеим сторонам: пользователь получает очень быструю загрузку, а мы экономим ресурсы. Всего повторяющиеся файлы составляют около 12 процентов от всех заливаемых.

    После заливки файла на машину загрузчика и подсчета хэш-суммы необходимо переместить файл в хранилище и отправить статус загрузки в mpfs. С этого момента файлы становятся доступны пользователю: они отображаются в веб-интерфейсе и могут синхронизироваться при помощи клиентов. Но на этом работа загрузчика не заканчивается, наступает черед двух стадий пост-обработки: создание превью и проверка на вирусы.

    Каждая стадия проходит через определенный набор состояний. Изначально все они находятся в исходном состоянии (initial). Некоторым стадиям на выполнение требуется совсем немного времени, они практически сразу переходят в статус успешно завершенных (success). Но на пути к успеху могут случаться сбои. Они бывают двух видов: временные и окончательные. Например, когда при передаче данных в mpfs случается сбой сети или перестает отвечать один из дата-центров, стадия переходит в состояние временного сбоя (temp fail) и через какое-то время запрос повторяется. Если через определенное количество повторений успешно завершить стадию так и не удается, она переходит в состояние окончательного сбоя (fail).
    Рисунок 3. Состояния стадий

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

    Кроме того, у каждой стадии есть максимальное время выполнения. Если стадии для успешного завершения требуется много времени, она может переходить в состояние «в процессе» (in progress). Обычно это происходит при получении файла от пользователя, так как загружаемые файлы бывают достаточно большими (максимальный объем файла на Диске – 10 ГБ), а скорость подключения – низкой.

    Только не дисконнект! Только не дисконнект!

    При передаче файла на машину загрузчика может случиться всякое. Например, может пропасть соединение с пользователем. В этом случае стадии присваивается статус temp fail, а после восстановления соединения закачка возобновляется.
    Яндекс
    Как мы делаем Яндекс

    Comments 48

      +11
      Слежу за Вашим проектом с первого анонса. Стилистически и технически он очень сильно радует. Пользуюсь Яндекс.Диском для синхронизации личных файлов, а для рабочих — Дропбоксом.

      По этому топику — Кладун/Заберун доставили. Даже представились какие-то монстрики которые относят файлы на облако и утаскивают с него, в стиле Adventure Time.
        +2
        Напомнило однажды встреченное обсуждение того, как перевести на русский upvote и downvote. Предлагался вариант «надголосовать» и «подголосовать». :)
          –1
          Чуров бы сказал что это одно и то же действие.
        0
        Какая вероятность коллизий контрольных сумм? Сервис-то массовым может стать.
          +3
          Мы изначально проектировали наш сервис, как массовый. Уже сейчас в диск за день заливают миллионы файлов, и у нас есть уверенность, что коллизий нет.
          • UFO just landed and posted this here
            0
            У вас всё действительно так правильно, красиво и радужно?
            Или всё-таки код уже начал потихоньку обрастать костылями? API справа наверняка потребовало некоторого количества костылей?
            • UFO just landed and posted this here
                +3
                Конечно, в реальности все несколько сложней, но мы стараемся прикладывать все усилия, чтобы архитектура оставалась целостной и не порастала костылями. Пока получается;)
                0
                >>Первым делом после получения файла от пользователя
                >>Это выгодно обеим сторонам: пользователь получает очень быструю загрузку
                как же пользователь получает быструю загрузку если вы узнаёте, контрольную сумму только когда файл уже залит на сервер?
                  +3
                  Контрольная сумма считается и на клиенте, и на сервере. Сначала клиент посылает контрольную сумму, если mpfs понимает, что такой файл уже есть, то файл не заливается заново. Если такого файла нет, то заливается и контрольная сумма пересчитывается на сервере. Пересчитываем на сервере, т.к. не все клиенты умеют подсчитывать контрольную сумму (например, при загрузке через браузер).
                    0
                    в случае работы через свою программу, то конечно проблем нету.
                    а если не секрет: каково деление в процентах между загрузкой из браузеров и из приложения?

                    и когда уже будет платная версия с местом в 100Гбайт хотя бы.(а то гугл драйв нивкакую не хочет работать у меня под вин2008)
                      +1
                      Специально выжидал, чтобы можно было вместо абстрактных планов, поделиться с вами этой ссылкой. Вот и появилась платная версия)
                  0
                  Когда появится возможность в веб интерфейсе загружать сразу папки?
                  Когда в веб интерфейсе будет показываться место занимаемое выделенной папкой?
                    0
                    Подсчет места, занимаемого папкой, довольно тяжелая операция, поэтому мы решили не делать ее на каждое выделение папки. Но мы постараемся учесть Вашe пожелание и придумать дешевый способ показа.

                    Про загрузку папкой тоже пока не могу ничего обещать, но мы подумаем в эту сторону.
                      0
                      А в чём проблема? Создается отдельное поле, в которое будет записываться вес папки в момент создания. Т.е. 0. При IO операциях (загрузка\удаление файла) поле будет также изменяться. При удалении — уменьшаться на File.Length, при загрузке — увеличиваться на File.Length.
                      При этом подсчет при каждом обращении не нужен.

                      Это если я правильно понял суть проблемы.
                        0
                        Есть несколько вариантов решить эту задачу: первый — предложен вами, второй — подсчитывать размер каждый раз при обращении (так делают операционные системы).

                        Первый вариант дорогой, т.к. IO-операций много, и на одну IO операцию нужно обновлять всю иерархию папок до корня. Кроме того, для избежания неконсистентных данных при параллельных IO-операциях нужно будет ставить локи, что не убыстряет работу.

                        Второй вариант проще в реализации, но обходить все дерево папки — дорого.
                  • UFO just landed and posted this here
                      0
                      Спасибо, за предложение. Уже сейчас можно просматривать содержимое архива через просмоторщик документов, возможно, частично это решит вашу задачу. Если нет, то расскажите, что вы предполагаете дальше делать с распакованными файлами?)
                        0
                        Положить распакованные файлы куда-нибудь в папку (по своему усмотрению), а исходный ZIP-архив удалить за ненадобностью.
                      0
                      Подскажите пожалуйста,
                      А какими алгоритмами генерится хэш функция на блоки и подтверждается уникальность данных?
                        0
                        Про свои алгоритмы не расскажем, но вы с легкостью найдете в интернете множества алгоритмов подсчета контрольных сумм)
                          0
                          Интересует вот что, общепринятые ли это алгоритмы, или что то своё, уникальное?
                            0
                            Общепринятые)
                        0
                        Мои замечания по поводу яндекс диска.
                        Установил, не могу изменить папку по умолчанию. Приложение постоянно отваливается. В папке приложения несколько исполняемых файлов, которые не запускаются.
                        Делал данные манипуляции на двух компьютерах, windows 7, потом 8 на одном и XP на другом. Может у меня руки растут не оттуда?
                          0
                          Сообщите, пожалуйста, об этой проблеме в нашу службу поддержки (для этого, нажмите по иконке Диска в трее, затем «Справка» — «Сообщить в Яндекс об ошибке»). Это позволит нам разобраться с проблемой, как можно быстрее.
                            0
                            Дело в том что диск отваливается моментально. Иконка в трее более пары секунд не задерживается.
                              0
                              Тогда напишите, пожалуйста, письмом на disk@support.yandex.ru, при этом указав ваш логин на яндексе.
                          0
                          А если я удаляю файлы на своём компе в папке связанной с Яндекс.Диском — они удалятся и в Яндекс.Диске?
                            +1
                            Да, но вы можете настроить выборочную синхронизацию, если хотите какие-то файлы держать только в облаке: help.yandex.ru/disk/desktop/windows.xml#sync-win
                              0
                              Спасибо за разъяснения!
                            0
                            Когда будет автономная работа с файлами? едешь на дачу, летишь в самолете — хотелось бы почитать чего-нибудь, ан нет…
                              0
                              Кладункус-Заберункус! (с) самизнаетекто
                                0
                                «Сторонние клиенты» — интересно, а много ли таких таких сейчас?
                                  0
                                  Мы ведем списочек тех, про которых знаем help.yandex.ru/disk/apps.xml. Можно дополнять, если кто-то еще знает)
                                  0
                                  С самого начала пытаюсь пользоваться Я.Диском и сменить буржуйские аналоги на отечественный. В облака загнаны рабочие директории с проектами, над которыми тружусь и трудился. К сожалению, до сих пор любое изменение любого файла приводит к переиндексации всей файловой структуры (судя по требуемому времени). А переиндексация всей структуры — это несколько часов почти полного висяка системы без возможности что-либо делать ещё. Да, компьютер слабенький по современным меркам (одно ядро, 2 гига оперативы, win XP), но конкуренты-то работают вполне адекватно и почти незаметно. Приходится запускать Я.Диск по праздникам на ночь, когда компьютер не нужен…

                                  В саппорт писал, после того, как ответили, что программа не рассчитана на работу с таким большим количеством файлов (что-то около 30-50к файлов), писать перестал.
                                    0
                                    Действительно, при работе с большим количеством файлов скорость синхронизации может быть небольшой. Сейчас мы занимаемся решением данной проблемы.
                                    0
                                    Почему разница в скорости аплоада файлов между веб интерфейсом и webdav?
                                    Через веб в районе 1 мегабайта/с, а по webdav 150-200 кбайт/с. Можно это как-то исправить?
                                      0
                                      Кладун/заберун это отлично. Сразу вспоминается Логалище… из другого проекта ;)
                                        0
                                        Как вы реализовали прогресс-бар на клиенте?
                                        Показываете пользователю объем, который ушел в сеть (а точнее в ядро ОС), или же получаете реальные цифры с сервера?
                                          0
                                          Клиенты показывают объем, который ушел в сеть. Но если соединение порвалось, то клиент спрашивает у сервера, сколько сервер успел закачать и продолжает закачку уже с этого места.
                                          0
                                          Как все знакомо. Только мы не только предпросмотр генерировали, но и поддерживаемые форматы, вроде офисных документов в XPS и PDF конвертировали и потом показывали в встроенном просмотрщике. Именно конвертация и генерация привью самая «тяжёлая» операция. Кстати позже после обновления библиотеки конвертации мы могли повторно попробовать сгенерировать превью и документ сконвертировать для документов которые не были сконвертированы на предыдущей версии. К сожалению не взлетело, остался только памятник былой роскоши libreeze.com/
                                            0
                                            Есть шанс на появление платного расширения места?
                                              +1
                                              Да, шансы есть;) Уже можно покупать здесь.
                                              0
                                              Android клиент не загружает файлы, пока их не откроешь. Это совершенно непрозрачно для пользователя. Особенно для обывателя. По сути клиент не синхронизирует, а просто предоставляет ссылки на файлы.
                                                0
                                                По-моему, Dropbox работает так же, и в принципе, это нормально — я не хотел бы в телефоне хранить всё, что у меня есть в Dropbox.
                                                  0
                                                  Да, мы думаем в сторону опциональной возможности синхронизации файлов для android.
                                                  0
                                                  А можно нечто подобное прочитать про то, как устроена Яндекс.Метрика?
                                                  Было бы интересно узнать про то, как работает бэкенд.

                                                  Only users with full accounts can post comments. Log in, please.