2012-01-22 10 views
10

Muszę napisać zadanie MapReduce, które pobiera wszystkie wiersze w danym zakresie dat (powiedzmy ostatni miesiąc). Byłby to chwyt z "My Row Key" z Datą. Ale Moje częste zapytania Hbase są na wartościach początkowych klucza.Jak skutecznie skanować linie HBase

Klucz mojego rzędu to dokładnie A | B | C | 20120121 | D. Gdzie kombinacja A/B/C wraz z datą (w formacie YearMonthDay) tworzy niepowtarzalny identyfikator rzędu.

Moje tabele Hbase mogą mieć kilka milionów wierszy. Czy mój Mapper powinien odczytać całą tabelę i przefiltrować każdy wiersz, jeśli mieści się w podanym zakresie dat, czy Skan/Filtr może pomóc w radzeniu sobie z tą sytuacją?

Czy ktoś mógłby zasugerować (lub fragment kodu) sposób skutecznego radzenia sobie z tą sytuacją?

Dzięki -Panks

+0

Dlaczego nie skopiujesz zawartości tabeli do nowej z kluczem uporządkowanym i zgarniesz starą? – Mario

+0

@Mario co jeśli tabela ma tryliona klawiszy? I musi to często robić? – markg

Odpowiedz

5

Możesz użyć RowFilter z RegexStringComparator. Musisz wymyślić RegEx, który odpowiednio filtruje twoje daty. This page ma przykład, który obejmuje ustawienie filtru dla skanera MapReduce.

+1

Jeśli Rowkey jest przydatny, najlepszą wydajnością jest Get. Jeśli zwracany wynik jest zbyt duży dla wiersza, wówczas opcja Skanuj za pomocą get i batchSize jest lepsza/bezpieczniejsza. –

0

ja dopiero się rozpoczął z HBase, bloom filters może pomóc.

+1

Filtry Bloom nie pomogą tutaj, chyba że zna dokładny klucz. –

+0

Dzięki Chris-bloom filtr przechowuje dane zamiast rzeczywistych danych, aby efektywnie wykorzystywać pamięć - więc dopasowywanie wzorca nie powinno być możliwe. –

0

Możesz zmodyfikować skan, który wysyłasz do Mappera, aby dołączyć filtr. Jeśli data jest także datownik rekord, to proste:

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

Jeśli data w swoim kluczem wiersza jest inny, trzeba będzie dodać filtr do skanowania. Ten filtr może działać na kolumnie lub kluczu wiersza. Myślę, że to będzie nieporządne z tylko kluczem rzędu. Jeśli umieścisz datę w kolumnie, możesz wprowadzić FilterList, gdzie wszystkie warunki muszą być prawdziwe i użyć CompareOp.GREATER i CompareOp.LESS. Następnie użyj scan.setFilter(filterList), aby dodać filtry do skanowania.

+0

setTimeRange filtruje na sygnaturze czasowej, a nie w wierszu. –

10

Filtr RowFiltra z filtrem RegEx działałby, ale nie byłby najbardziej optymalnym rozwiązaniem. Alternatywnie możesz spróbować użyć indeksów wtórnych. Kolejnym rozwiązaniem jest wypróbowanie FuzzyRowFIlter. FuzzyRowFilter wykorzystuje pewien rodzaj szybkiego przewijania do przodu, pomijając wiele wierszy w całym procesie skanowania, a zatem będzie szybszy niż skanowanie RowFilter. Możesz przeczytać więcej na ten temat here.

Alternatywnie BloomFilters może również pomóc w zależności od twojego schematu. Jeśli twoje dane są ogromne, powinieneś wykonać analizę porównawczą dla drugiego indeksu i Bloom Filters.