Quando creo una tabella esterna nell’hive posso indirizzare la posizione a file specifici in una directory?

Ho definito una tabella in quanto tale:

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

Non voglio che tutti i file nella directory / user / data siano usati come parte della tabella. È ansible che io faccia quanto segue?

 location 'user/data/*.csv' 

Mi sono imbattuto in questo thread quando ho avuto un problema simile da risolvere. Sono stato in grado di risolverlo usando un SerDe personalizzato. Ho quindi aggiunto le proprietà di SerDe che guidavano ciò che RegEx applicava ai pattern dei nomi dei file per ogni particolare tabella.

Un SerDe personalizzato potrebbe sembrare eccessivo se si hanno a che fare solo con file CSV standard, ho avuto un formato di file più complesso da gestire. Eppure questa è una soluzione molto valida se non si evita di scrivere qualcosa di Java. È particolarmente utile quando non si è in grado di ristrutturare i dati nella posizione di archiviazione e si sta cercando un modello di file molto specifico tra un set di file sproporzionatamente grande.

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

Quello che ha detto kmosley è vero. A partire da ora, non è ansible selezionare in modo selettivo determinati file come parte della tabella Hive. Tuttavia, ci sono 2 modi per aggirarlo.

Opzione 1: puoi spostare tutti i file csv in un’altra directory HDFS e creare una tabella Hive in aggiunta. Se funziona meglio per te, puoi creare una sottodirectory (ad esempio, csv) all’interno della tua directory attuale che contiene tutti i file CSV. È quindi ansible creare una tabella Hive in cima a questa sottodirectory. Tenere presente che qualsiasi tabella Hive creata in cima alla directory padre NON conterrà i dati dalla sottodirectory.

Opzione 2: puoi cambiare le tue query per utilizzare una colonna virtuale chiamata INPUT__FILE__NAME .

La tua richiesta sarà simile a qualcosa:

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

L’effetto negativo di questo approccio è che la query Hive dovrà sfogliare tutti i dati presenti nella directory anche se ci si preoccupa solo dei file specifici. La query non INPUT__FILE__NAME i file in base al predicato utilizzando INPUT__FILE__NAME . Solo filtrerà i record che non provengono dal match del predicato usando INPUT__FILE__NAME durante la fase della mappa (filtrando di conseguenza tutti i record da determinati file) ma i mapper verrebbero eseguiti anche su file non necessari. Ti darà il risultato corretto, potrebbe avere un sovraccarico di prestazioni probabilmente minore.

Il vantaggio di questo approccio è la possibilità di utilizzare la stessa tabella Hive se nella tabella sono presenti più file e si desidera poter interrogare tutti i file da quella tabella (o dalla sua partizione) in alcune query e un sottoinsieme di file in altre domande. Potresti utilizzare la colonna virtuale INPUT__FILE__NAME per ottenerlo. Ad esempio: se una partizione nella tua directory HDFS /user/hive/warehouse/web_logs/ assomigliava 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 

Supponiamo che la definizione della tabella sia simile a:

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

Dopo aver aggiunto le partizioni appropriate, è ansible interrogare tutti i registri nella partizione utilizzando una query come:

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

Tuttavia, se ti interessavano solo i log dalla prima ora del giorno, puoi interrogare i log per la prima ora utilizzando una query come:

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

Un altro caso di utilizzo simile potrebbe essere una directory che contiene registri Web di domini diversi e varie query devono analizzare i registri su diversi insiemi di domini. Le query possono filtrare i domini utilizzando la colonna virtuale INPUT__FILE__NAME .

In entrambi i casi d’uso di cui sopra, avere una sottocartella per ora o dominio risolverebbe anche il problema, senza dover utilizzare la colonna virtuale. Tuttavia, potrebbero esistere alcuni compromessi di progettazione che richiedono di non creare sotto-partizioni. In tal caso, probabilmente, usare la colonna virtuale INPUT__FILE__NAME è la soluzione migliore.

Decidere tra le 2 opzioni:

Dipende davvero dal tuo caso d’uso. Se non ti interessano mai i file che stai cercando di escludere dalla tabella Hive, l’uso dell’opzione 2 è probabilmente eccessivo e dovresti correggere la struttura delle directory e creare una tabella Hive in cima alla directory contenente i file che ti interessano .

Se i file che stai attualmente escludono seguono lo stesso formato degli altri file (in modo che possano essere tutti parte della stessa tabella Hive) e potresti vederti scrivere una query che analizzerebbe tutti i dati nella directory, quindi vai con Option 2.

No, non puoi farlo al momento. È disponibile un ticket JIRA per consentire la selezione regex dei file inclusi per le tabelle Hive ( https://issues.apache.org/jira/browse/HIVE-951 ).

Per ora la soluzione migliore è creare una tabella su una directory diversa e copiare semplicemente i file che si desidera interrogare.