Как быстро загрузить 100 миллионов строк из хранилища таблиц Azure

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

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

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

побочный вопрос: во время процесса загрузки 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 ответов


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

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

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


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

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


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

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


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

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


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

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


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

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

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

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