2010-07-12 16 views
8

Sono stato incaricato di scaricare circa 100 milioni di righe di dati da Azure Table Storage. La cosa importante qui è la velocità.Come scaricare 100 milioni di righe da Azure Table FAST

Il processo che stiamo utilizzando sta scaricando 10.000 righe dall'archivio di Azure Table. Elaborali in un'istanza locale di Sql Server. Durante l'elaborazione delle righe, elimina 100 righe alla volta dalla tabella di Azure. Questo processo è threadato per avere 8 thread scaricando 10.000 righe alla volta.

L'unico problema con questo è quello secondo i nostri calcoli. Ci vorranno circa 40 giorni per scaricare ed elaborare i circa 100 milioni di file archiviati. Qualcuno sa un modo più veloce per svolgere questo compito?

Una domanda laterale: durante il processo di download, Azure restituirà xml che non ha alcun dato. Non restituisce un errore. Ma invia questo:

<?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 

Qualcun altro ha questo problema e ha una soluzione per questo?

+0

Quanti dati per riga? 400 byte, 400kb, un meg? –

+0

Al massimo ogni riga è 1k. – jWoose

+0

Non ho lavorato con Azure, quindi sto solo cercando di risolvere i problemi da una vista SQL/rete; tuttavia, sto leggendo alcuni blog e tutti dicono la stessa cosa: usare ATOM è molto prolisso e inefficiente per i grandi set di dati. Ora, non sono sicuro di quanto sia difficile cambiarlo; ma ecco un esempio di differenze velocità/dati http://weblogs.asp.net/rgillen/archive/2009/08/20/atompub-json-azure-and-large-datasets-part-2.aspx –

risposta

15

In aggiunta ai suggerimenti di Disabling Nagling, c'è un post estremamente bello su improving performance of Azure Table Storage. In realtà migliorare la velocità di ADO.NET Deserializzazione fornito 10x speed-up per Sqwarea (enorme gioco multiplayer online realizzato con il framework Lokad.Cloud).

Tuttavia, lo storage di tabella potrebbe non essere la soluzione migliore per scenari di archiviazione enormi (oltre milioni di record). La latenza è il fattore di omissione qui.Per ovviare a questo, ho utilizzato con successo archivi di file basati su file, dove le modifiche sono eseguite localmente (senza alcuna latenza di rete di CLAP) e sono impegnate in BLOB caricando il file indietro (la concorrenza e il ridimensionamento sono state applicate qui da Lokad.CQRS App Engine per Windows Azure).

Inserendo 10 milioni di record nel database SQLite in una volta (all'interno della transazione, dove ogni record è stato indicizzato da 2 campi e ha dati arbitrari senza schema serializzati tramite ProtoBuf) in media sono stati necessari solo 200 secondi. Caricamento/download del file risultante - in media circa 15 secondi. Letture casuali per indice: istantaneo (a condizione che il file sia memorizzato nella cache nella memoria locale e ETag corrisponda).

+0

Grazie per il vostro consiglio. Questo dovrebbe finire per aiutare molto. E volevo solo dire che sì, lo storage da tavolo non è l'ideale per questo numero di record. È stato un problema aggirare la limitazione di SQL Azure. Il problema di SQL Azure è stato corretto e non stiamo più memorizzando i dati nell'archivio della tabella, ma vogliamo comunque che i dati siano memorizzati lì. – jWoose

+0

Sono contento di aver aiutato.Lo storage di tabelle è buono (sebbene API potrebbe essere stato molto meglio) e insostituibile per cose come la memorizzazione di dati di visualizzazione di applicazioni web altamente scalabili. Tuttavia, in scenari che richiedono latenza estremamente bassa e throughput elevato, non è il migliore (proprio come SQL Azure) –

+1

Rinat e jWoose. L'archiviazione tabella di Azure NON è relazionale. È un database distribuito NoSQL, noschema, probabilmente implementato in modo simile a quello che descrivi. Azure Table Storage è progettato specificamente per Gazillions of records. –

0

Molto probabilmente, il fattore limitante è la larghezza di banda della rete, non l'elaborazione. In questo caso, l'unica vera speranza è quella di espandersi: più macchine eseguono più thread per scaricare i dati.

BTW, Azure non espone un meccanismo di "esportazione" che eliminerà la necessità di scaricare manualmente tutte le righe?

+0

Da cosa Posso dire che il fattore limitante non è la larghezza di banda. La latenza derivante dall'ottenere ed eliminare righe da Azure è il problema. – jWoose

+0

@jWoose: come lo stai determinando? Ho difficoltà a credere che tu NON sia I/O vincolato. –

7

Per quanto riguarda la tua domanda a margine, mi aspetto che tu stia ricevendo un "token di continuazione". Se stai utilizzando la libreria client di archiviazione .NET, prova ad aggiungere .AsTableServiceQuery() alla tua query.

Per quanto riguarda la domanda principale, smuovere la query è la cosa migliore che si possa fare. Sembra che tu stia accedendo allo spazio di archiviazione da un computer locale (non in Windows Azure). Se è così, immagino che tu possa accelerare un po 'distribuendo un piccolo servizio a Windows Azure che recupera i dati dall'archivio della tabella (molto più veloce, poiché c'è una maggiore larghezza di banda e una minore latenza all'interno del data center), e poi comprime risultati e li rimanda al computer locale. C'è un sacco di spese generali per il ritorno delle tabelle XML di Windows Azure, quindi spogliarlo e raggruppare le righe probabilmente farebbe risparmiare molto tempo.

+0

Sono d'accordo con l'approccio suggerito da Steve. Inoltre, considerare la possibilità di scrivere le immagini compresse nella memoria BLOB. Ciò li rende molto facili da recuperare dall'ambiente in loco. –

+0

Hai ragione riguardo alla mia domanda secondaria. Il token di continuazione viene restituito se la richiesta richiede più di 5 secondi. – jWoose

1

Oltre ai suggerimenti sui limiti di larghezza di banda, è possibile eseguire facilmente i limiti dell'account di archiviazione, poiché ogni partizione di tabella è limitata a circa 500 transazioni al secondo.

Inoltre: è stata implementata un'ottimizzazione (algoritmo di Nagle) che potrebbe rallentare le cose per le letture di piccole dimensioni (come le letture dei dati 1K). Ecco uno blog post about disabling Nagling, che potrebbe potenzialmente velocizzare notevolmente le letture, soprattutto se si sta eseguendo direttamente in un servizio di Azure senza la latenza di Internet nel modo.

0

Il fattore principale è il modo in cui i dati vengono distribuiti tra le partizioni. Una query che attraversa i limiti della partizione tornerà a ogni limite che richiede un nuovo invio, anche se la partizione in questione ha 0 righe. Se i dati sono 1 Partizione = 1 Riga, allora sarà lento, ma potresti aumentare il numero di thread ben oltre 8. Se i dati sono in n partizioni = m righe, le idee seguenti dovrebbero accelerarti.

Supponendo di avere più partizioni e ognuna con un numero di righe, il modo più veloce per andare sarà quello di far girare il maggior numero di thread possibile (se si utilizza .Net il PLINQ o Parallel.ForEach (partizione) o QueueWorkItem()) e avere una scansione del thread sua partizione per tutte le righe, elaborare, postare su SQL, & eliminare prima di tornare.

Considerate le latenze coinvolte (10 s di ms) e gli spostamenti multipli, anche con 8 thread probabilmente non siete così occupati come si potrebbe pensare. Inoltre, non si menziona quale VM si sta utilizzando, ma si potrebbe voler profilare diverse dimensioni.

In alternativa, un altro modo per fare ciò sarebbe sfruttare una coda e alcuni lavoratori "n". Per ogni partizione (o set di partizioni) inserisci un messaggio nella coda. Fai in modo che i lavoratori si spostino dalla coda (multi-thread) e query/process/post/repeat. Potresti far ruotare quanti più lavoratori hai bisogno ed essere distribuito su più data center (ad esempio più throughput, ecc.).

1

Il modo più veloce per ottenere i dati, supportato da Amazon ma non ancora da Azure, è quello di spedire loro un disco USB (anche una chiavetta USB), farli mettere i dati nel disco e spedirli a voi.

Un'altra opzione consiste nell'utilizzare il bus di servizio AppFabric per trasferire i dati su un altro sistema al momento della creazione, invece di attendere il download tutto in una volta.

Problemi correlati