Пакетная загрузка огромных наборов изображений в хранилище BLOB-объектов Azure - PullRequest
9 голосов
/ 11 октября 2011

На моем жестком диске локально хранится около 110 000 изображений различных форматов (jpg, png и gif) и размеров (2-40 КБ). Мне нужно загрузить их в хранилище BLOB-объектов Azure. При этом мне нужно установить некоторые метаданные и тип содержимого BLOB-объекта, но в остальном это массовая загрузка.

В настоящее время я использую следующее для обработки загрузки одного изображения за раз (параллельно с 5-10 одновременными Задачами).

static void UploadPhoto(Image pic, string filename, ImageFormat format)
{
    //convert image to bytes
    using(MemoryStream ms = new MemoryStream())
    {
        pic.Save(ms, format);
        ms.Position = 0;

        //create the blob, set metadata and properties
        var blob = container.GetBlobReference(filename);
        blob.Metadata["Filename"] = filename;
        blob.Properties.ContentType = MimeHandler.GetContentType(Path.GetExtension(filename));

        //upload!
        blob.UploadFromStream(ms);
        blob.SetMetadata();
        blob.SetProperties();
    }
}

Мне было интересно, есть ли другой способ, который я мог бы использовать для обработки загрузки, чтобы сделать ее максимально быстрой. Этот конкретный проект включает в себя импорт большого количества данных из одной системы в другую и для по причинам клиента это должно произойти как можно быстрее.

Ответы [ 6 ]

7 голосов
/ 12 октября 2011

Хорошо, вот что я сделал.Я возился с запуском BeginUploadFromStream (), затем BeginSetMetadata (), затем BeginSetProperties () в асинхронной цепочке, параллельно 5-10 потокам (комбинация предложений ElvisLive и knightpfhor).Это сработало, но все, что для 5 потоков имело ужасную производительность, для завершения каждого потока требовалось более 20 секунд (работая на странице из десяти изображений одновременно).

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

  • Асинхронный: 5 потоков, каждый из которых выполняет асинхронную цепочку, каждый из которых работает с десятью изображениями одновременно (разбит на страницы по статистическим причинам): ~ 15,8 секунд (на поток).
  • Синхронный: 1 поток, десять изображений одновременно (разбит на страницы по статистическим причинам): ~ 3,4 секунды

Хорошо, это довольно интересно.В одном подходе загрузка двоичных объектов синхронно выполнялась в 5 раз лучше, чем каждый поток в другом подходеИтак, даже при наилучшем асинхронном балансе из 5 потоков обеспечивает практически одинаковую производительность .

Итак, я настроил импорт файлов изображений, чтобы разделить изображения на папки, содержащие по 10 000 изображений в каждой.Затем я использовал Process.Start (), чтобы запустить экземпляр моего загрузчика BLOB-объектов для каждой папки.У меня есть 170 000 изображений для работы в этом пакете, что означает 17 экземпляров загрузчика.При запуске всех из них на моем ноутбуке производительность на всех них нивелируется на ~ 4,3 секунды на набор .

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

  • Асинхронные попытки: 14-16 часов , основанные на среднем времени выполнения при работе в течение часа или двух.
  • Синхронный с 17 отдельными экземплярами: ~ 1 час, 5 минут.
3 голосов
/ 12 октября 2011

Вы должны определенно загружать параллельно в нескольких потоках (т. Е. Публиковать несколько файлов одновременно), но прежде чем делать какой-либо эксперимент, показывающий (ошибочно), что это не приносит пользы, убедитесь, что вы действительно увеличиваете значение ServicePointManager.DefaultConnectionLimit:

Максимальное количество одновременных подключений, разрешенное ServicePoint объект. Значение по умолчанию: 2.

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

1 голос
/ 01 февраля 2014

Если параллельный метод загружается в 5 раз больше, чем последовательный, то у вас либо

  • есть ужасная пропускная способность
  • у вас очень медленный компьютер
  • сделать что-то не так

Моя утилита командной строки значительно ускоряется при параллельной работе, даже несмотря на то, что я не использую потоки памяти и другие подобные вещи, я просто генерирую строковый массивимена файлов, затем загрузите их с помощью Parallel.ForEach.

Кроме того, вызов Properties.ContentType, вероятно, отбросит вас назад.Лично я никогда не использую их, и я думаю, что они не должны иметь никакого значения, если вы не хотите просматривать их прямо в браузере по прямым URL-адресам.

1 голос
/ 13 октября 2011

Возможно, вы захотите увеличить ParallelOperationThreadCount, как показано ниже.Я не проверял последний SDK, но в 1.3 ограничение было 64. Не установка этого значения приводила к снижению числа одновременных операций.

CloudBlobClient blobStorage = new CloudBlobClient(config.AccountUrl, creds);
// todo: set this in blob extensions
blobStorage.ParallelOperationThreadCount = 64
1 голос
/ 12 октября 2011

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

Я подозреваю, что для достижения максимальной пропускной способности нужно найти правильное количество потоков для вашего оборудования, вашего соединения и размера файла. Вы можете попробовать использовать Azure Throughput Analyzer , чтобы упростить поиск этого баланса.

Группа Microsoft Extreme Computing также имеет тесты и предложения по улучшению пропускной способности . Он ориентирован на пропускную способность рабочих ролей, развернутых в Azure, но он даст вам представление о том, на что вы могли надеяться.

0 голосов
/ 11 октября 2011

Вы всегда можете попробовать асинхронные методы загрузки.

public override IAsyncResult BeginUploadFromStream (
Stream source,
AsyncCallback callback,
Object state

)

http://msdn.microsoft.com/en-us/library/windowsazure/ee772907.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...