sql >> Base de Datos >  >> NoSQL >> HBase

Uso de Hive para interactuar con HBase, Parte 1

Esta entrada de blog se publicó en Hortonworks.com antes de la fusión con Cloudera. Es posible que algunos enlaces, recursos o referencias ya no sean precisos.

Esta es la primera de dos publicaciones que examinan el uso de Hive para la interacción con tablas HBase. La segunda publicación está aquí.

Una de las cosas que me preguntan con frecuencia es cómo usar HBase de Apache Hive. No solo cómo hacerlo, sino qué funciona, qué tan bien funciona y cómo hacer un buen uso de él. Investigué un poco en esta área, así que espero que esto sea útil para alguien además de mí. Este es un tema que no cubrimos en HBase en acción, quizás estas notas se conviertan en la base para la 2.ª edición 😉 Estas notas se aplican a Hive 0.11.x junto con HBase 0.94.x. Deberían ser aplicables en gran medida a 0.12.x + 0.96.x, aunque todavía no lo he probado todo.

El proyecto Hive incluye una biblioteca opcional para interactuar con HBase. Aquí es donde se implementa la capa puente entre los dos sistemas. La interfaz principal que utiliza cuando accede a HBase desde las consultas de Hive se llama  BaseStorageHandler . También puede interactuar con las tablas de HBase directamente a través de los formatos de entrada y salida, pero el controlador es más simple y funciona para la mayoría de los usos.

Tablas HBase de Hive

Usa el HBaseStorageHandler para registrar tablas de HBase con Hive metastore. Opcionalmente, puede especificar la tabla HBase como EXTERNAL , en cuyo caso Hive no creará para colocar esa tabla directamente; tendrá que usar el shell de HBase para hacerlo.

[sql]
CREATE [EXTERNAL] TABLE foo(…)
ALMACENADO POR 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
TBLPROPERTIES ('hbase.table.name' =' barra');
[/sql]

La declaración anterior registra la tabla HBase llamada bar en la metatienda de Hive, accesible desde Hive con el nombre foo .

Bajo el capó, HBaseStorageHandler está delegando la interacción con la tabla HBase a
HiveHBaseTableInputFormatHiveHBaseTableOutputFormat . Puede registrar su tabla HBase en Hive usando esas clases directamente si lo desea. La declaración anterior es más o menos equivalente a:

[sql]
CREATE TABLE foo(…)
ALMACENADO COMO
INPUTFORMAT 'org.apache.hadoop.hive.hbase.HiveHBaseTableInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive .hbase.HiveHBaseTableOutputFormat'
TBLPROPERTIES ('hbase.table.name' ='bar');
[/sql]

También se proporciona el HiveHFileOutputFormat lo que significa que también debería ser posible generar HFiles para la carga masiva desde Hive. En la práctica, no he logrado que esto funcione de principio a fin (consulte HIVE-4627).

Asignación de esquemas

Registrar la mesa es solo el primer paso. Como parte de ese registro, también debe especificar una asignación de columnas. Así es como se vinculan los nombres de las columnas de Hive con la clave de fila y las columnas de la tabla HBase. Hazlo usando hbase.columns.mapping SerDe propiedad.

[sql]
CREATE TABLE foo(rowkey STRING, a STRING, b STRING)
ALMACENADO POR 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
CON SERDEPROPERTIES ('hbase.columns .mapping' =':clave,f:c1,f:c2')
TBLPROPERTIES ('hbase.table.name' ='bar');

[/sql]

Los valores proporcionados en la propiedad de mapeo se corresponden uno a uno con los nombres de las columnas de la tabla Hive. Los nombres de las columnas de HBase están completamente calificados por familia de columnas y se usa el token especial :key para representar la clave de fila. Lo anterior

ejemplo crea filas de la tabla HBase bar disponible a través de la tabla Hive foo . El foo columna rowkey se asigna a la clave de fila de la tabla de HBase, ac1 en el f familia de columnas y b a c2 , también en el f familia.

También puede asociar el MAP de Hive estructuras de datos a familias de columnas HBase. En este caso, solo el STRING Se utiliza el tipo colmena. El otro tipo de Hive admitido actualmente es BINARY . Consulte la página wiki para obtener más ejemplos.

Interactuar con los datos

Con las asignaciones de columnas definidas, ahora puede acceder a los datos de HBase como lo haría con cualquier otro dato de Hive. Actualmente, solo se admiten predicados de consulta simples.

[sql]
SELECCIONE * DESDE foo DONDE...;
[/sql]

También puede llenar una tabla HBase usando Hive. Esto funciona tanto con INTO y OVERWRITE cláusulas.

[sql]
DESDE source_hive_table INSERT INTO TABLE my_hbase_table
SELECCIONE source_hive_table.* DONDE …;
[/sql]

Tenga en cuenta que hay una regresión en Hive 0.12.0 que rompe esta característica, consulte HIVE-5515.

En la práctica

Todavía se requiere un poco de delicadeza para conectar todo correctamente en tiempo de ejecución. El módulo de interacción de HBase es completamente opcional, por lo que debe asegurarse de que tanto él como sus dependencias de HBase estén disponibles en el classpath de Hive.

[bash]
$ export HADOOP_CLASSPATH=…
$ hive -e “CREATE TABLE… ALMACENADA POR ‘org.apache…HBaseStorageHandler'”
[/bash]

El entorno de instalación podría hacer un mejor trabajo al manejar esto para los usuarios, pero por el momento debe administrarlo usted mismo. Idealmente, la hive bin script puede detectar la presencia de HBase y automáticamente hacer el CLASSPATH necesario ajustes Esta mejora parece estar rastreada en HIVE-2055. La distribución misma proporciona la última milla, asegurando que las variables de entorno estén configuradas para hive . BIGTOP-955 proporciona esta función.

También debe asegurarse de que los archivos jar necesarios se envíen a los trabajos de MapReduce cuando ejecute las declaraciones de Hive. Hive proporciona un mecanismo para enviar dependencias de trabajo adicionales a través de la función auxjars.

[bash]
$ export HIVE_AUX_JARS_PATH=…
$ hive -e “SELECCIONAR * DESDE…”
[/bash]

Descubrí un pequeño error en las compilaciones HDP-1.3 que enmascara los valores especificados por el usuario de HIVE_AUX_JARS_PATH . Con derechos administrativos, esto se soluciona fácilmente corrigiendo la línea en hive-env.sh respetar un valor existente. La
solución alternativa en los scripts de usuario es usar el SET declaración para proporcionar un valor una vez que haya lanzado la CLI de Hive.

[bash]
SET hive.aux.jars.ruta =…
[/bash]

Hive debería poder detectar qué frascos son necesarios y agregarlos por sí mismo. HBase proporciona  TableMapReduceUtils#addDependencyJars  métodos para este propósito. Parece que esto se hace en hive-0.12.0, al menos según HIVE-2379.

Trabajo futuro

Mucho se ha hablado sobre el soporte adecuado para la inserción de predicados (HIVE-1643, HIVE-2854, HIVE-3617,
HIVE-3684) y el conocimiento del tipo de datos (HIVE-1245, HIVE-2599). Estos van de la mano ya que la semántica de predicados se define en términos de los tipos sobre los que operan. Se podría hacer más para mapear los tipos de datos complejos de Hive, como Maps y Structs, en familias de columnas HBase también (HIVE-3211). La compatibilidad con las marcas de tiempo de HBase es un poco complicada; no están disponibles para las aplicaciones de Hive con ningún nivel de granularidad (HIVE-2828, HIVE-2306). La única interacción que tiene un usuario es a través de la configuración del controlador de almacenamiento para escribir una marca de tiempo personalizada con todas las operaciones.

Desde una perspectiva de rendimiento, hay cosas que Hive puede hacer hoy (es decir, no depender de los tipos de datos) para aprovechar HBase. También existe la posibilidad de un Hive compatible con HBase para hacer uso de las tablas de HBase como ubicación de almacenamiento intermedia (HIVE-3565), lo que facilita las uniones del lado del mapa con las tablas de dimensiones cargadas en HBase. Hive podría hacer uso de la estructura indexada natural de HBase (HIVE-3634, HIVE-3727), lo que podría ahorrar escaneos enormes. Actualmente, el usuario no tiene (¿ningún?) control sobre los escaneos que se ejecutan. La configuración por trabajo, o al menos por tabla, debe estar habilitada (HIVE-1233). Eso permitiría a un usuario experto en HBase proporcionar a Hive sugerencias sobre cómo debería interactuar con HBase. La compatibilidad con el muestreo dividido simple de tablas HBase (HIVE-3399) también se puede realizar fácilmente porque HBase ya administra particiones de tablas.

Otros canales de acceso

Todo lo discutido hasta ahora ha requerido que Hive interactúe con HBase RegionServers en línea. Es posible que las aplicaciones obtengan un rendimiento significativo y disfruten de una mayor flexibilidad al interactuar directamente con los datos de HBase almacenados en HDFS. Esto también tiene la ventaja de evitar que las cargas de trabajo de Hive interfieran con las aplicaciones HBase vinculadas a SLA en línea (al menos, hasta que veamos mejoras de HBase en el aislamiento de QOS entre tareas, HBASE-4441).

Como se mencionó anteriormente, existe el HiveHFileOutputFormat . Resolver HIVE-4627 debería hacer que Hive sea una forma sencilla de generar HFiles para la carga masiva. Una vez que haya creado los HFiles usando Hive, todavía queda el último paso para ejecutar
LoadIncrementalHFiles utilidad para copiarlos y registrarlos en las regiones. Para ello, el HiveStorageHandler  la interfaz necesitará algún tipo de enlace para influir en el plan de consulta a medida que se crea, lo que le permitirá agregar pasos. Una vez en su lugar, debería ser posible SET un indicador de tiempo de ejecución, cambiando un INSERT  operación para usar carga masiva.

HBase introdujo recientemente la función de instantánea de tabla. Esto permite que un usuario cree una vista persistente de un punto en el tiempo de una tabla, persistente en HDFS. HBase puede restaurar una tabla desde una instantánea a un estado anterior y crear una tabla completamente nueva a partir de una instantánea existente. Actualmente, Hive no admite la lectura de una instantánea de HBase. De hecho, HBase aún no admite trabajos MapReduce sobre instantáneas, aunque la función es un trabajo en progreso (HBASE-8369).

Conclusiones

La interfaz entre HBase y Hive es joven, pero tiene un buen potencial. Hay muchas frutas maduras que se pueden recoger para hacer las cosas más fáciles y rápidas. El problema más evidente que impide el desarrollo de aplicaciones reales es la falta de coincidencia de impedancia entre el esquema denso tipificado de Hive y el esquema disperso no tipificado de HBase. Esto es tanto un problema cognitivo como una cuestión técnica. Las soluciones aquí permitirían que se produzcan una serie de mejoras, incluidas muchas mejoras en el rendimiento. Espero que el trabajo continuo para agregar tipos de datos a HBase (HBASE-8089) pueda ayudar a cerrar esta brecha.

Las operaciones básicas funcionan en su mayoría, al menos de forma rudimentaria. Puede leer datos y volver a escribirlos en HBase mediante Hive. Configurar el entorno es un proceso opaco y manual, que probablemente impide que los novatos adopten las herramientas. También está la cuestión de las operaciones masivas:en este momento falta por completo la compatibilidad para escribir HFiles y leer instantáneas de HBase usando Hive. Y, por supuesto, hay errores esparcidos por todas partes. La mayor mejora reciente es la desaprobación de la interfaz de HCatalog, lo que elimina la necesaria decisión inicial sobre qué interfaz usar.

Hive proporciona una interfaz SQL muy útil además de HBase, que se integra fácilmente en muchos flujos de trabajo ETL existentes. Esa interfaz requiere simplificar parte de la semántica de BigTable que proporciona HBase, pero el resultado será abrir HBase a una audiencia mucho más amplia de usuarios. La interoperabilidad de Hive complementa extremadamente bien la experiencia proporcionada por Phoenix. Hive tiene la ventaja de no requerir las complejidades de implementación que actualmente requiere ese sistema. Con suerte, la definición común de tipos permitirá un futuro complementario.