Ich habe den Auftrag erhalten, ungefähr 100 Millionen Datenzeilen von Azure Table Storage herunterzuladen. Das Wichtigste ist hier Geschwindigkeit.
Der Prozess, den wir verwenden, lädt 10.000 Zeilen aus dem Azure Table-Speicher. Verarbeiten Sie sie in eine lokale Instanz von SQL Server. Während der Verarbeitung der Zeilen löscht es jeweils 100 Zeilen aus der Azure-Tabelle. Dieser Prozess ist so gethreaded, dass 8 Threads gleichzeitig 10.000 Zeilen herunterladen.
Das einzige Problem ist das nach unseren Berechnungen. Es dauert ungefähr 40 Tage, um die rund 100 Millionen Zeilen, die wir gespeichert haben, herunterzuladen und zu verarbeiten. Kennt jemand einen schnelleren Weg, um diese Aufgabe zu erfüllen?
Eine Nebenfrage: Während des Download-Vorgangs sendet Azure XML zurück, das gerade keine Daten enthält. Es sendet keinen Fehler zurück. Aber es sendet das:
%Vor%Hat jemand anderes dieses Problem und eine Lösung dafür?
Zusätzlich zu den Vorschlägen von Deaktivieren von Nagling , es gibt einen sehr netten Post auf Verbesserung der Leistung von Azure Table Storage . Eigentlich Verbesserung der Geschwindigkeit von ADO.NET Deserialization zur Verfügung gestellt 10x Beschleunigung für Sqwarea (massive Online-Multiplayer-Spiel gebaut mit Lokad.Cloud Framework).
Tabellenspeicher ist jedoch möglicherweise nicht die beste Lösung für große Speicherszenarien (mehr als Millionen von Datensätzen). Latenz ist der tödliche Faktor hier . Um das zu umgehen, habe ich erfolgreich dateibasierte Datenbankspeicher verwendet, bei denen Änderungen lokal (ohne Netzwerklatenz von CLAP) vorgenommen und durch Hochladen der Datei an BLOB übergeben werden (Parallelität und Skalierung wurden hier durch
Das gleichzeitige Einfügen von 10 Millionen Datensätzen in die SQLite-Datenbank (innerhalb der Transaktion, bei der jeder Datensatz durch zwei Felder indiziert wurde und über ProtoBuf serialisierte, beliebige schemanose Daten hatte) benötigte im Durchschnitt nur 200 Sekunden. Hochladen / Herunterladen der resultierenden Datei - ungefähr 15 Sekunden im Durchschnitt. Zufällige Lesevorgänge nach Index - momentan (vorausgesetzt, die Datei wird im lokalen Speicher zwischengespeichert und ETag stimmt überein).
Was Ihre Nebenfrage betrifft, erwarte ich, dass Sie ein "Fortsetzungstoken" erhalten. Wenn Sie die .NET-Speicherclientbibliothek verwenden, versuchen Sie, AsTableServiceQuery () zu Ihrer Abfrage hinzuzufügen.
Was Ihre Hauptfrage betrifft, ist das Auffächern der Abfrage das Beste, was Sie tun können. Es klingt, als ob Sie von einem lokalen Computer auf Speicher zugreifen (nicht in Windows Azure). Wenn ja, würde ich mir vorstellen, dass Sie die Dinge ein wenig beschleunigen können, indem Sie einen kleinen Dienst für Windows Azure bereitstellen, der die Daten aus dem Tabellenspeicher abruft (viel schneller, da es eine höhere Bandbreite und geringere Latenz im Rechenzentrum gibt) und dann komprimiert Ergebnisse und sendet sie zurück zu Ihrem lokalen Rechner. Die XML-Windows-Azure-Tabellen verursachen einen hohen Aufwand, da die Abstrahierung und Bündelung von Zeilen wahrscheinlich viel Zeit für die Übertragung spart.
Abgesehen von Vorschlägen zu Bandbreitenbeschränkungen könnten Sie leicht auf Speicherkontenlimits stoßen, da jede Tabellenpartition auf ungefähr 500 Transaktionen pro Sekunde beschränkt ist.
Außerdem: Es gibt eine Optimierung (Nagles Algorithmus), die die Vorgänge bei kleinen Lesevorgängen (z. B. beim Lesen von 1K-Daten) verlangsamen kann. Hier ist ein Blogpost zum Deaktivieren von Nagling , der Ihre Lesevorgänge erheblich beschleunigen könnte, insbesondere wenn Sie direkt in einem Azure-Dienst ohne Internetlatenz arbeiten.
Am schnellsten erhalten Sie Ihre Daten, die von Amazon, aber noch nicht von Azure unterstützt werden, indem Sie ihnen eine USB-Festplatte (sogar einen USB-Stick) schicken, sie auf die Diskette legen und an Sie zurückschicken.
Eine weitere Option ist die Verwendung von AppFabric Service Bus, um die Daten bei der Erstellung an ein anderes System zu senden, anstatt darauf zu warten, dass sie alle gleichzeitig heruntergeladen werden.
Höchstwahrscheinlich ist Ihr begrenzender Faktor die Netzwerkbandbreite und nicht die Verarbeitung. Wenn das der Fall ist, ist die einzige wirkliche Hoffnung, dass Sie expandieren: mehr Maschinen, auf denen mehr Threads laufen, um Daten herunterzuladen.
BTW, stellt Azure keinen "Export" -Mechanismus zur Verfügung, der das manuelle Herunterladen aller Zeilen überflüssig macht?
Der große Faktor hier ist, wie die Daten über Partitionen verteilt sind. Eine Abfrage, die sich über Partitionsgrenzen erstreckt, wird an jeder Grenze zurückgegeben, für die eine erneute Übergabe erforderlich ist - selbst wenn die fragliche Partition 0 Zeilen aufweist. Wenn die Daten 1 Partition = 1 Zeile sind, dann ist es langsam, aber Sie könnten die Thread-Anzahl weit über 8 erhöhen. Wenn die Daten in n Partitionen = m Zeilen sind, sollten Sie die folgenden Ideen beschleunigen.
>Wenn Sie davon ausgehen, dass Sie mehrere Partitionen mit einer bestimmten Anzahl von Zeilen haben, ist es am schnellsten, so viele Threads wie möglich hochzufahren (wenn Sie .Net PLINQ oder Parallel.ForEach (Partition) oder QueueWorkItem verwenden) ()) und haben einen Thread seine Partition für alle Zeilen scannen, verarbeiten, an SQL, & amp; Löschen vor dem Zurückgeben.
Angesichts der Latenzzeiten (10 ms) und der vielen Runden, sogar mit 8 Threads, sind Sie wahrscheinlich nicht so beschäftigt, wie Sie vielleicht denken. Außerdem erwähnen Sie nicht, welche VM Sie verwenden, aber Sie können verschiedene Größen profilieren.
Alternativ wäre eine andere Möglichkeit, eine Warteschlange und einige "n" Arbeiter zu nutzen. Platzieren Sie für jede Partition (oder Gruppe von Partitionen) eine Nachricht in die Warteschlange. Lassen Sie die Arbeiter aus der Warteschlange ziehen (Multithreading) und abfragen / bearbeiten / posten / wiederholen. Sie können so viele Mitarbeiter wie nötig anwerben und über mehrere Rechenzentren verteilen (d. H. Mehr Durchsatz usw.).
Tags und Links azure azure-storage azure-table-storage