2012-01-22 31 views
10

Necesito escribir un trabajo de MapReduce que obtiene todas las filas en un intervalo de fechas determinado (por ejemplo, el último mes). Habría sido un juego de niños si My Row Key comenzara con Date. Pero mis frecuentes consultas Hbase están en los valores iniciales de la clave.Cómo escanear filas de HBase eficientemente

Mi clave de fila es exactamente A | B | C | 20120121 | D. Donde la combinación de A/B/C junto con la fecha (en el formato YearMonthDay) hace una identificación de fila única.

Mis tablas de Hbase podrían tener hasta unos pocos millones de filas. ¿Debería mi Mapper leer toda la tabla y filtrar cada fila si cae en un rango de fechas determinado o Scan/Filter puede ayudar a manejar esta situación?

¿Alguien podría sugerir (o un fragmento de código) una forma de manejar esta situación de manera efectiva?

Gracias -Panks

+0

¿Por qué no copias el contenido de la tabla en una nueva con la clave reorganizada y desecha la anterior? – Mario

+0

@Mario, ¿y si la mesa tiene un trillón de llaves? Y él tiene que hacer esto a menudo? – markg

Respuesta

5

Puede usar un RowFilter con un RegexStringComparator. Tendría que proponer un RegEx que filtre las fechas de forma adecuada. This page tiene un ejemplo que incluye la configuración de un filtro para un escáner MapReduce.

+1

Si Rowkey es útil, el mejor rendimiento es con Get. Si el resultado devuelto es demasiado grande para una fila, entonces Escanear con get y batchSize es una opción mejor/más segura. –

0

estoy acaba de empezar con HBase, bloom filters podría ayudar.

+1

Los filtros Bloom no son útiles aquí a menos que sepa la clave exacta. –

+0

Gracias Chris - bloom filter almacena el resumen de datos en lugar de los datos reales para hacer uso de la memoria de manera eficiente, por lo que no debería ser posible la coincidencia de patrones. –

0

Puede modificar la exploración que envía al asignador para incluir un filtro. Si la fecha es también la fecha y hora de grabación, es fácil:

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

Si la fecha en la clave de fila es diferente, tendrá que añadir un filtro a la imagen escaneada. Este filtro puede operar en una columna o una tecla de fila. Creo que va a ser complicado con solo la tecla de fila. Si coloca la fecha en una columna, puede hacer un FilterList donde todas las condiciones deben ser verdaderas y usar un CompareOp.GREATER y un CompareOp.LESS. Luego use scan.setFilter(filterList) para agregar sus filtros al escaneo.

+0

setTimeRange filtra el sello de tiempo, no la clave de fila. –

10

Un RowFilter con un filtro RegEx funcionaría, pero no sería la solución más óptima. Alternativamente, puede intentar usar índices secundarios.

Una solución más es probar el FuzzyRowFIlter. Un FuzzyRowFilter usa un tipo de reenvío rápido, omitiendo así muchas filas en el proceso de escaneo general y, por lo tanto, será más rápido que un escaneo RowFilter. Puede leer más al respecto here.

Alternativamente, BloomFilters también podría ayudar dependiendo de su esquema. Si sus datos son enormes, debe hacer un análisis comparativo sobre el índice secundario y los filtros Bloom.