2012-01-22 3 views
10

Мне нужно написать MapReduce Job, которое получает все строки в заданном диапазоне дат (скажем, последний месяц). Это был бы прозвище, когда My Row Key начинался с Date. Но мои частые запросы Hbase начинаются с значений ключа.Как эффективно сканировать строки HBase

Моя строка с ключом точно равна A | B | C | 20120121 | D. Если комбинация A/B/C вместе с датой (в формате YearMonthDay) делает уникальный идентификатор строки.

Мои таблицы Hbase могут иметь до нескольких миллионов строк. Должен ли мой Mapper читать всю таблицу и фильтровать каждую строку, если она попадает в заданный диапазон дат или Scan/Filter, может помочь справиться с этой ситуацией?

Может ли кто-нибудь предложить (или фрагмент кода) способ эффективно справиться с этой ситуацией?

Благодаря -Panks

+0

Почему вы не копируете содержимое таблицы в новую с измененным ключом и записью старого? – Mario

+0

@Mario Что делать, если таблица имеет триллион ключей? И ему нужно делать это часто? – markg

ответ

5

Вы можете использовать RowFilter с RegexStringComparator. Вам нужно придумать RegEx, который соответствующим образом фильтрует ваши даты. This page имеет пример, который включает настройку фильтра для сканера MapReduce.

+1

Если Rowkey удобен, лучшая производительность с Get. Если возвращенный результат слишком велик для строки, тогда Scan with get и batchSize лучше/безопаснее. –

0

Я просто начать работу с HBase, bloom filters может помочь.

+1

Блум-фильтры не помогут здесь, если он не знает точного ключа. –

+0

Благодаря фильтру Chris-bloom хранятся данные, а не фактические данные, чтобы эффективно использовать память - поэтому сопоставление шаблонов не должно быть возможным. –

0

Вы можете изменить Сканирование, которое вы отправляете в Mapper, чтобы включить фильтр. Если дата и запись метка время, это легко:

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

Если дата в вашем ключе строк различна, вам придется добавить фильтр сканирования. Этот фильтр может работать с столбцом или строкой. Я думаю, что это будет беспорядочно с ключом строки. Если вы поместите дату в колонку, вы можете сделать FilterList, где должны быть все условия, и используйте CompareOp.GREATER и CompareOp.LESS. Затем используйте scan.setFilter(filterList), чтобы добавить фильтры к сканированию.

+0

setTimeRange фильтры по метке времени, а не строка. –

10

RowFilter с RegEx Filter будет работать, но не будет оптимальным решением. В качестве альтернативы вы можете попробовать использовать вторичные индексы.

Еще одно решение - попробовать FuzzyRowFIlter. FuzzyRowFilter использует своего рода ускоренную пересылку, поэтому пропускает много строк в общем процессе сканирования и, таким образом, будет быстрее, чем сканирование RowFilter. Вы можете узнать больше об этом here.

Альтернативно, BloomFilters могут также помочь в зависимости от вашей схемы. Если ваши данные огромны, вы должны провести сравнительный анализ вторичного индекса и Bloom Filters.

Смежные вопросы