Basso accoppiamento che elabora grandi quantità di dati

8

Di solito ottengo un accoppiamento basso creando classi che scambiano liste, insiemi e mappe tra di loro. Ora sto sviluppando un'applicazione batch Java e non riesco a inserire tutti i dati in una struttura dati perché non c'è abbastanza memoria. Devo leggere ed elaborare un blocco di dati e poi passare a quello successivo. Quindi avere un accoppiamento basso è molto più difficile perché devo verificare da qualche parte se ci sono ancora dati da leggere, ecc.

Quello che sto usando ora è:

Sorgente - > Processo - > Persistono

Le classi che elaborano devono chiedere le classi Source se ci sono più righe da leggere.

Quali sono le migliori pratiche e / o schemi utili in tali situazioni?

Spero di spiegarmi, se non lo dico.

    
posta Виталий Олегович 09.04.2012 - 11:05
fonte

2 risposte

7

Dai commenti vedo che stai usando Java. Dai un'occhiata alle varie implementazioni della coda . In particolare, BlockingQueue è utile per produttore-consumatore scenari. Potresti avere due code: una tra Source (produttore di dati) e Process (consumatore di dati), e un'altra tra Process (produttore di risultati) e Persist (consumatore di risultati).

Con code di blocco a capacità limitata è abbastanza facile implementare sistemi efficienti (la parte del collo di bottiglia, qualunque essa sia, viene alimentata con i dati il 100% delle volte), utilizzando ancora solo una quantità limitata di memoria, non importa quanti dati c'è.

    
risposta data 09.04.2012 - 12:15
fonte
2

Una coda bloccante (di Joonas Pulakka) è la risposta pesante. Una risposta più semplice potrebbe funzionare. Se si dispone di tutti i dati memorizzati nella sorgente, è sufficiente passare un riferimento al processore e può semplicemente prelevare i dati dall'origine. Certo, questo è probabilmente quello che stavi facendo in passato. Potresti non avere tutti i dati in memoria nella sorgente e potresti non ottenere l'accoppiamento basso che desideri.

Il passo successivo sarebbe utilizzare un'interfaccia Enumerator o Iterator. (Gli iteratori sono più comuni in Java, anche se la maggior parte delle volte che il metodo remove è solo un nusance.) Il processore otterrebbe l'Iterator dall'origine, quindi chiama i metodi fino al termine. Se la fonte sta estraendo da terra terrabyte di dati, ogni chiamata potrebbe richiedere un po 'di tempo. Ma se stai andando a dormire il processore fino a quando c'è qualcosa in coda comunque, lo farà automaticamente. E se la fonte supera il produttore, la sorgente attenderà automaticamente che il produttore chiami hasNext e next .

Se, d'altra parte, vuoi che la fonte raccolga i dati dalla sorgente il più velocemente possibile e lo stia accumulando fino a quando il processore non raggiunge, non seduto intorno in attesa che il processore venga elaborato, quindi la coda - e più thread - iniziano a sembrare un'idea buona, anche se più complicata. Ora la sorgente può accumulare i dati quando può correre più velocemente (il suo limite presumibilmente è qualcosa come I / O su disco), e il processore può ridurre le dimensioni della pila quando it può girare più velocemente, ( il suo limite è la velocità con cui il modulo di persistenza può mantenere i dati).

    
risposta data 09.04.2012 - 17:35
fonte