Как загрузить 100 миллионов строк из хранилища таблиц Azure FAST - PullRequest
9 голосов
/ 12 июля 2010

Мне было поручено загрузить около 100 миллионов строк данных из хранилища таблиц Azure. Здесь важна скорость.

Процесс, который мы используем, загружает 10 000 строк из хранилища таблиц Azure. Обработайте их в локальный экземпляр Sql Server. При обработке строк он одновременно удаляет 100 строк из таблицы Azure. Этот процесс состоит из 8 потоков, загружающих 10 000 строк одновременно.

Единственная проблема с этим заключается в том, что согласно нашим расчетам. Загрузка и обработка около 100 миллионов строк, которые мы сохранили, займет около 40 дней. Кто-нибудь знает более быстрый способ выполнить эту задачу?

Дополнительный вопрос. В процессе загрузки Azure отправит обратно xml, в котором просто нет данных. Это не отправляет обратно ошибку. Но он отправляет это:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xml:base="azure-url/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
  <title type="text">CommandLogTable</title>
  <id>azure-url/CommandLogTable</id>
  <updated>2010-07-12T19:50:55Z</updated>
  <link rel="self" title="CommandLogTable" href="CommandLogTable" />
</feed>
0

Кто-нибудь еще имеет эту проблему и есть решение для нее?

Ответы [ 6 ]

16 голосов
/ 13 июля 2010

В дополнение к предложениям Отключение Nagling , есть очень приятный пост на , улучшающий производительность хранилища таблиц Azure . На самом деле повышение скорости десериализации ADO.NET обеспечило 10-кратное ускорение для Sqwarea (масштабная многопользовательская онлайн-игра, построенная на основе Lokad.Cloud ).

Однако табличное хранилище может оказаться не лучшим решением для сценариев с огромным хранилищем (более миллионов записей). Задержка является фактором убийства здесь . Чтобы обойти это, я успешно использую файловые хранилища базы данных, где изменения выполняются локально (без какой-либо задержки в сети CLAP) и фиксируются в BLOB путем загрузки файла обратно (параллелизм и масштабирование здесь принудительно выполняются Lokad.CQRS App Engine для Windows Azure).

Одновременная вставка 10 миллионов записей в базу данных SQLite (в рамках транзакции, где каждая запись была проиндексирована двумя полями и имела произвольные данные без схемы, сериализованные через ProtoBuf), в среднем заняла всего 200 секунд. Загрузка / выгрузка полученного файла - в среднем около 15 секунд. Случайное чтение по индексу - мгновенное (если файл кэшируется в локальном хранилище и ETag совпадает).

7 голосов
/ 13 июля 2010

Что касается вашего побочного вопроса, я ожидаю, что вы получаете «жетон продолжения».Если вы используете клиентскую библиотеку хранения .NET, попробуйте добавить .AsTableServiceQuery () к вашему запросу.

Что касается вашего основного вопроса, то разветвление запроса - лучшее, что вы можете сделать.Похоже, вы получаете доступ к хранилищу с локального компьютера (не в Windows Azure).Если это так, я думаю, вы можете немного ускорить процесс, развернув небольшой сервис в Windows Azure, который извлекает данные из табличного хранилища (намного быстрее, поскольку в центре обработки данных имеется более высокая пропускная способность и меньшая задержка), а затем сжимаетрезультаты и отправляет их обратно на локальный компьютер.Отправка обратно таблиц XML в Windows Azure сопряжена с большими накладными расходами, поэтому их извлечение и объединение строк, вероятно, сэкономят много времени на передачу.

1 голос
/ 31 июля 2010

Самый быстрый способ получить ваши данные, поддерживаемые Amazon, но еще не Azure, - это отправить им USB-диск (даже USB-флешку), попросить их поместить данные на диск и отправить их вам.

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

1 голос
/ 13 июля 2010

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

Далее: развернута оптимизация (алгоритм Нейгла), которая на самом деле может замедлить процесс при небольших чтениях (например, при чтении данных из 1 КБ). Вот сообщение в блоге об отключении Nagling , которое потенциально может значительно ускорить чтение, особенно если вы работаете непосредственно в службе Azure без задержек в Интернете.

0 голосов
/ 15 июля 2010

Важным фактором здесь является то, как данные распределяются по разделам. Запрос, который охватывает границы раздела, будет возвращаться на каждой границе, требующей повторной отправки, даже если рассматриваемый раздел имеет 0 строк. Если данные равны 1 Partition = 1 Row, то это будет медленно, но вы можете увеличить количество потоков намного выше 8. Если данные в n разделах = m строках, то приведенные ниже идеи должны ускорить вас.

Предполагая, что у вас есть несколько разделов и каждый с некоторым количеством строк, самый быстрый способ - это увеличить количество потоков (если вы используете .Net, PLINQ или Parallel.ForEach (раздел) или QueueWorkItem. ()) и попросить поток просканировать свой раздел на наличие всех строк, обработать, опубликовать в SQL и удалить перед возвратом.

Учитывая задержки (10 с мс) и множественные циклы, даже с 8 потоками вы, вероятно, не так заняты, как вы думаете. Кроме того, вы не упоминаете, какую виртуальную машину вы используете, но вы можете профилировать различные размеры.

В качестве альтернативы, другой способ сделать это - использовать очередь и некоторых «n» работников. Для каждого раздела (или набора разделов) поместите сообщение в очередь. Пусть рабочие вытянут из очереди (многопоточные) и запросят / обрабатывают / публикуют / повторяют. Вы можете набрать столько рабочих, сколько вам нужно, и распределить их по большому количеству центра обработки данных (т. Е. Увеличить пропускную способность и т. Д.).

0 голосов
/ 13 июля 2010

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

Кстати, разве Azure не предоставляет какой-то механизм "экспорта", который устранит необходимость загрузки всех строк вручную?

...