web-dev-qa-db-fra.com

Lors de la création d'une table externe dans Hive, puis-je pointer l'emplacement vers des fichiers spécifiques dans un répertoire?

J'ai défini une table comme telle:

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';

Je ne veux pas que tous les fichiers du répertoire/user/data soient utilisés dans le cadre de la table. Est-il possible pour moi de faire ce qui suit?

location 'user/data/*.csv'
23
George TeVelde

Je suis tombé sur ce fil quand j'ai eu un problème similaire à résoudre. J'ai pu le résoudre en utilisant un SerDe personnalisé. J'ai ensuite ajouté des propriétés SerDe qui ont guidé quel RegEx appliquer aux modèles de nom de fichier pour une table particulière.

Un SerDe personnalisé peut sembler exagéré si vous ne traitez qu'avec des fichiers CSV standard, j'avais un format de fichier plus complexe à gérer. C'est toujours une solution très viable si vous n'avez pas peur d'écrire du Java. Il est particulièrement utile lorsque vous ne parvenez pas à restructurer les données dans votre emplacement de stockage et que vous recherchez un modèle de fichier très spécifique parmi un ensemble de fichiers disproportionné.

> CREATE EXTERNAL TABLE PageViews (Userid string, Page_View string)  
> ROW FORMAT SERDE 'com.something.MySimpleSerDe' 
> WITH SERDEPROPERTIES ( "input.regex" = "*.csv")
> LOCATION '/user/data';
11
NG Algo

Ce que kmosley a dit est vrai. Pour l'instant, vous ne pouvez pas choisir de manière sélective certains fichiers pour faire partie de votre table Hive. Cependant, il existe 2 façons de le contourner.

Option 1: Vous pouvez déplacer tous les fichiers csv dans un autre répertoire HDFS et créer une table Hive en plus de cela. Si cela fonctionne mieux pour vous, vous pouvez créer un sous-répertoire (par exemple, csv) dans votre répertoire actuel qui abrite tous les fichiers CSV. Vous pouvez ensuite créer une table Hive au-dessus de ce sous-répertoire. Gardez à l'esprit que les tables Hive créées au-dessus du répertoire parent NE contiendront PAS les données du sous-répertoire.

Option 2: Vous pouvez modifier vos requêtes pour utiliser une colonne virtuelle appelée INPUT__FILE__NAME.

Votre requête ressemblerait à quelque chose comme:

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

Le mauvais effet de cette approche est que la requête Hive devra parcourir toutes les données présentes dans le répertoire même si vous ne vous souciez que de fichiers spécifiques. La requête ne filtrerait pas les fichiers en fonction du prédicat à l'aide de INPUT__FILE__NAME. Il filtrera simplement les enregistrements qui ne proviennent pas de la correspondance avec le prédicat à l'aide de INPUT__FILE__NAME pendant la phase de mappage (filtrant par conséquent tous les enregistrements de fichiers particuliers), mais les mappeurs s'exécuteraient également sur les fichiers inutiles. Il vous donnera le résultat correct, peut avoir des frais généraux de performance, probablement mineurs.

L'avantage de cette approche est que vous pouvez utiliser la même table Hive si vous aviez plusieurs fichiers dans votre table et que vous vouliez pouvoir interroger tous les fichiers de cette table (ou de sa partition) dans quelques requêtes et un sous-ensemble des fichiers dans d'autres requêtes. Vous pouvez utiliser le INPUT__FILE__NAME colonne virtuelle pour y parvenir. Par exemple: si une partition dans votre répertoire HDFS /user/Hive/warehouse/web_logs/ ressemblait à:

/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

Disons que votre définition de table ressemblait à:

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

Après avoir ajouté les partitions appropriées, vous pouvez interroger tous les journaux de la partition à l'aide d'une requête comme:

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

Cependant, si vous vous souciez uniquement des journaux de la première heure de la journée, vous pouvez interroger les journaux de la première heure en utilisant une requête comme:

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

Un autre cas d'utilisation similaire pourrait être un répertoire qui contient des journaux Web de différents domaines et diverses requêtes doivent analyser les journaux sur différents ensembles de domaines. Les requêtes peuvent filtrer les domaines à l'aide de INPUT__FILE__NAME colonne virtuelle.

Dans les deux cas d'utilisation ci-dessus, avoir une sous-partition pour l'heure ou le domaine résoudrait également le problème, sans avoir à utiliser la colonne virtuelle. Cependant, il peut exister certains compromis de conception qui vous obligent à ne pas créer de sous-partitions. Dans ce cas, sans doute, en utilisant INPUT__FILE__NAME la colonne virtuelle est votre meilleur choix.

Décider entre les 2 options:

Cela dépend vraiment de votre cas d'utilisation. Si vous ne vous souciez jamais des fichiers que vous essayez d'exclure de la table Hive, l'utilisation de l'option 2 est probablement une exagération et vous devez corriger la structure du répertoire et créer une table Hive au-dessus du répertoire contenant les fichiers qui vous intéressent. .

Si les fichiers que vous excluez actuellement suivent le même format que les autres fichiers (afin qu'ils puissent tous faire partie de la même table Hive) et que vous pourriez vous voir écrire une requête qui analyserait toutes les données du répertoire, alors allez avec Option 2.

20
Mark Grover

Non, vous ne pouvez pas faire cela actuellement. Un ticket JIRA est ouvert pour permettre la sélection regex des fichiers inclus pour les tables Hive ( https://issues.Apache.org/jira/browse/Hive-951 ).

Pour l'instant, votre meilleur pari est de créer une table sur un répertoire différent et de simplement copier les fichiers que vous souhaitez interroger.

7
kmosley