2012-01-22 20 views
10

Ho bisogno di scrivere un processo MapReduce che ottenga tutte le righe in un determinato intervallo di date (ad esempio l'ultimo mese). Sarebbe stato un gioco da ragazzi con My Row Key iniziato con Date. Ma le mie frequenti query su Hbase riguardano i valori iniziali della chiave.Come eseguire la scansione HBase Righe in modo efficiente

Il mio tasto Riga è esattamente A | B | C | 20120121 | D. Laddove la combinazione di A/B/C con la data (nel formato YearMonthDay) crea un ID riga univoco.

Le mie tabelle Hbase potrebbero avere fino a pochi milioni di righe. Il mio Mapper dovrebbe leggere tutta la tabella e filtrare ogni riga se rientra in un dato intervallo di date o Scan/Filter può aiutare a gestire questa situazione?

Qualcuno potrebbe suggerire (o uno snippet di codice) un modo per gestire questa situazione in modo efficace?

Grazie -Panks

+0

Perché non copiare il contenuto del tavolo in uno nuovo con la chiave riorganizzata e scartare quella precedente? – Mario

+0

@ Mario cosa succede se il tavolo ha un trilione di chiavi? E ha bisogno di farlo spesso? – markg

risposta

5

È possibile utilizzare uno RowFilter con un RegexStringComparator. Dovresti trovare un RegEx che filtra le date in modo appropriato. This page ha un esempio che include l'impostazione di un filtro per uno scanner MapReduce.

+1

Se Rowkey è a portata di mano, la migliore prestazione è con Get. Se il risultato restituito è troppo vasto per una riga, quindi Scan con get e batchSize è l'opzione migliore/più sicura. –

0

sto appena iniziato con HBase, bloom filters potrebbe aiutare.

+1

I filtri di fioritura non aiutano qui se non conosce la chiave esatta. –

+0

Grazie a Chris, il filtro bloom memorizza il digest dei dati anziché i dati effettivi per utilizzare la memoria in modo efficiente, quindi non dovrebbe essere possibile la corrispondenza dei pattern. –

0

È possibile modificare la scansione che si invia nel Mapper per includere un filtro. Se la data è anche il timestamp di record, è facile:

Scan scan = new Scan(); 
scan.setTimeRange(minTime, maxTime); 
TableMapReduceUtil.initTableMapperJob("mytable", scan, MyTableMapper.class, 
    OutputKey.class, OutputValue.class, job); 

Se la data nella chiave di fila è diverso, si dovrà aggiungere un filtro per la scansione. Questo filtro può operare su una colonna o una chiave di riga. Penso che sarà complicato solo con il tasto di riga. Se si inserisce la data in una colonna, è possibile creare uno FilterList in cui tutte le condizioni devono essere vere e utilizzare uno CompareOp.GREATER e uno CompareOp.LESS. Quindi utilizzare scan.setFilter(filterList) per aggiungere i filtri alla scansione.

+0

setTimeRange filtri su timestamp, non riga chiave. –

10

Un RowFilter con un filtro RegEx funzionerebbe, ma non sarebbe la soluzione ottimale. In alternativa puoi provare a utilizzare gli indici secondari.

Un'altra soluzione è provare il FuzzyRowFIlter. Un FuzzyRowFilter utilizza una sorta di inoltro veloce, quindi salta molte righe nel processo di scansione generale e sarà quindi più veloce di una scansione RowFilter. Puoi leggere di più a riguardo here.

In alternativa, BloomFilters potrebbe anche aiutare a seconda del proprio schema. Se i tuoi dati sono enormi, dovresti fare un'analisi comparativa sull'indice secondario e sui filtri Bloom.

Problemi correlati