Al crear una tabla externa en hive, ¿puedo apuntar la ubicación a archivos específicos de un directorio?


He definido una tabla como tal:

create external table PageViews (Userid string, Page_View string)
partitioned by (ds string)
row format as delimited fields terminated by ','
stored as textfile location '/user/data';

No quiero que todos los archivos del directorio /user/data se usen como parte de la tabla. ¿Es posible para mí hacer lo siguiente?

location 'user/data/*.csv'
Author: Brian Tompsett - 汤莱恩, 2012-06-30

3 answers

Me encontré con este hilo cuando tenía un problema similar que resolver. Pude resolverlo usando un SerDe personalizado. Luego agregué propiedades SerDe que guiaban qué RegEx aplicar a los patrones de nombre de archivo para cualquier tabla en particular.

Un SerDe personalizado podría parecer excesivo si solo se trata de archivos CSV estándar, tenía un formato de archivo más complejo para tratar. Todavía esta es una solución muy viable si no alejarse de la escritura de Java. Es particularmente útil cuando no puede reestructurar los datos en su ubicación de almacenamiento y está buscando un patrón de archivo muy específico entre un conjunto de archivos desproporcionadamente grande.

> CREATE EXTERNAL TABLE PageViews (Userid string, Page_View string)  
> ROW FORMAT SERDE 'com.something.MySimpleSerDe' 
> WITH SERDEPROPERTIES ( "input.regex" = "*.csv")
> LOCATION '/user/data';
 11
Author: NG Algo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-15 03:08:43

Lo que kmosley dijo es cierto. A partir de ahora, no puede elegir selectivamente ciertos archivos para que formen parte de su tabla Hive. Sin embargo, hay 2 maneras de evitarlo.

Opción 1: Puede mover todos los archivos csv a otro directorio HDFS y crear una tabla de colmena encima de eso. Si funciona mejor para usted, puede crear un subdirectorio (por ejemplo, csv) dentro de su directorio actual que alberga todos los archivos CSV. A continuación, puede crear una tabla de colmena en la parte superior de este subdirectorio. Mantener en tenga en cuenta que cualquier tabla de colmena creada en la parte superior del directorio padre NO contendrá los datos del subdirectorio.

Opción 2: Puede cambiar sus consultas para hacer uso de una columna virtual llamada INPUT__FILE__NAME.

Su consulta se vería algo como:

SELECT 
   *
FROM
   my_table
WHERE
   INPUT__FILE__NAME LIKE '%csv';

El mal efecto de este enfoque es que la consulta Hive tendrá que alternar a través de datos completos presentes en el directorio a pesar de que solo se preocupó por archivos específicos. La consulta no filtraría los archivos basado en el predicado usando INPUT__FILE__NAME. Simplemente filtrará los registros que no provienen del predicado usando INPUT__FILE__NAME durante la fase de mapa (en consecuencia, filtrará todos los registros de archivos particulares), pero los mapeadores también se ejecutarán en archivos innecesarios. Le dará el resultado correcto, podría tener algunos, probablemente menor, sobrecarga de rendimiento.

El beneficio de este enfoque es que puede usar la misma tabla de colmena si tiene varios archivos en su tabla y desea capacidad de consultar todos los archivos de esa tabla (o su partición) en unas pocas consultas y un subconjunto de los archivos en otras consultas. Usted podría hacer uso de la columna virtual INPUT__FILE__NAME para lograr eso. Como ejemplo: si una partición en su directorio HDFS /user/hive/warehouse/web_logs/ se parece a:

/user/hive/warehouse/web_logs/dt=2012-06-30/
   /user/hive/warehouse/web_logs/dt=2012-06-30/00.log
   /user/hive/warehouse/web_logs/dt=2012-06-30/01.log
   .
   .
   .
   /user/hive/warehouse/web_logs/dt=2012-06-30/23.log

Digamos que la definición de la tabla se parece a:

CREATE EXTERNAL TABLE IF NOT EXISTS web_logs_table (col1 STRING)
PARTITIONED BY (dt STRING)
LOCATION '/user/hive/warehouse/web_logs';

Después de agregar las particiones apropiadas, puede consultar todos los registros de la partición utilizando una consulta como:

SELECT
   *
FROM
   web_logs_table w
WHERE
   dt='2012-06-30';

Sin embargo, si solo te importara acerca de los registros de la primera hora del día, puede consultar los registros de la primera hora usando una consulta como:

SELECT
   *
FROM
   web_logs_table w
WHERE 
   dt ='2012-06-30'
   AND INPUT__FILE__NAME='00.log';

Otro caso de uso similar podría ser un directorio que contiene registros web de diferentes dominios y varias consultas necesitan analizar registros en diferentes conjuntos de dominios. Las consultas pueden filtrar dominios usando la columna virtual INPUT__FILE__NAME.

En ambos casos de uso anteriores, tener una subpartición por hora o dominio resolvería el problema también, sin tener que utilice la columna virtual. Sin embargo, es posible que existan algunas compensaciones de diseño que requieran que no cree sub-particiones. En ese caso, podría decirse que el uso de INPUT__FILE__NAME columna virtual es su mejor apuesta.

Decidir entre las 2 opciones:

Realmente depende de su caso de uso. Si nunca le importarían los archivos que está tratando de excluir de la tabla de la Colmena, usar la opción 2 es probablemente una exageración y debería arreglar la estructura de directorios y crear una tabla de la colmena en parte superior del directorio que contiene los archivos que le interesan.

Si los archivos que está excluyendo actualmente siguen el mismo formato que los otros archivos (por lo que todos pueden ser parte de la misma tabla de la colmena) y podría verse escribiendo una consulta que analizaría todos los datos en el directorio, entonces vaya con la opción 2.

 19
Author: Mark Grover,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-01 00:11:29

No actualmente no se puede hacer eso. Hay un ticket JIRA abierto para permitir la selección de expresiones regulares de archivos incluidos para tablas Hive ( https://issues.apache.org/jira/browse/HIVE-951).

Por ahora su mejor opción es crear una tabla sobre un directorio diferente y simplemente copiar en los archivos que desea consultar.

 7
Author: kmosley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-29 22:26:55