Tworząc zewnętrzną tabelę w hive czy mogę wskazać lokalizację na konkretne pliki w katalogu?

Zdefiniowałem tabelę jako taką:

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

Nie chcę, aby wszystkie pliki w katalogu /user/data były używane jako część tabeli. Czy Mogę zrobić co następuje?

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

3 answers

Natknąłem się na ten wątek, kiedy miałem podobny problem do rozwiązania. Udało mi się to rozwiązać za pomocą niestandardowego SerDe. Następnie dodałem właściwości SerDe, które wskazywały, jakie wyrażenia regularne zastosować do wzorców nazw plików dla konkretnej tabeli.

Niestandardowy SerDe może wydawać się przesadą, jeśli masz do czynienia tylko ze standardowymi plikami CSV, miałem do czynienia z bardziej złożonym formatem plików. Mimo to jest to bardzo realne rozwiązanie, jeśli nie unikasz pisania Javy. Jest to szczególnie przydatne, gdy nie są w stanie zrestrukturyzować danych w lokalizacji przechowywania i szukasz bardzo konkretnego wzorca plików wśród nieproporcjonalnie dużego zestawu plików.

> 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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-15 03:08:43

To, co powiedział kmosley, jest prawdą. Na razie nie można selektywnie wybrać niektórych plików, aby być częścią tabeli Hive. Istnieją jednak 2 sposoby, aby go obejść.

Wariant 1: Możesz przenieść wszystkie pliki csv do innego katalogu HDFS i utworzyć na nim tabelę Hive. Jeśli to działa lepiej dla ciebie, możesz utworzyć podkatalog (powiedzmy csv) w obecnym katalogu, który zawiera wszystkie pliki CSV. Następnie możesz utworzyć tabelę Hive na górze tego podkatalogu. Keep in należy pamiętać, że tabele Hive utworzone na wierzchu katalogu nadrzędnego nie będą zawierały danych z podkatalogu.

Wariant 2: Możesz zmienić swoje zapytania, aby korzystać z wirtualnej kolumny o nazwie INPUT__FILE__NAME.

Twoje zapytanie wyglądałoby mniej więcej tak:

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

Zły efekt tego podejścia polega na tym, że zapytanie Hive będzie musiało przechodzić przez całe dane obecne w katalogu, nawet jeśli zależy Ci tylko na konkretnych plikach. Zapytanie nie odfiltrowałoby plików na podstawie predykatu INPUT__FILE__NAME. Po prostu odfiltruje rekordy, które nie pochodzą z dopasowania do predykatu za pomocą INPUT__FILE__NAME podczas fazy mapowania (w konsekwencji odfiltrowując wszystkie rekordy z poszczególnych plików), ale maperzy również będą działać na niepotrzebnych plikach. Da ci to prawidłowy wynik, może mieć pewne, prawdopodobnie niewielkie, nadmiarowe wyniki.

Zaletą tego podejścia jest to, że możesz użyć tej samej tabeli Hive, jeśli masz wiele plików w tabeli i chcesz możliwość odpytywania wszystkich plików z tej tabeli (lub jej partycji) w kilku zapytaniach i podzbioru plików w innych zapytaniach. Możesz skorzystać z wirtualnej kolumny INPUT__FILE__NAME, aby to osiągnąć. Jako przykład: jeśli partycja w katalogu HDFS /user/hive/warehouse/web_logs/ wyglądała następująco:

/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

Załóżmy, że Twoja definicja tabeli wyglądała następująco:

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

Po dodaniu odpowiednich partycji, możesz odpytywać wszystkie logi na partycji za pomocą zapytania typu:

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

Jednakże, jeśli zależy Ci tylko jeśli chodzi o dzienniki z pierwszej godziny dnia, możesz odpytywać dzienniki z pierwszej godziny za pomocą zapytania typu:

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

Innym podobnym przypadkiem użycia może być katalog zawierający logi internetowe z różnych domen i różne zapytania muszą analizować logi na różnych zestawach domen. Kwerendy mogą odfiltrować domeny za pomocą wirtualnej kolumny INPUT__FILE__NAME.

W obu powyższych przypadkach użycia, posiadanie sub partycji na godzinę lub domenę również rozwiązałoby problem, bez konieczności użyj wirtualnej kolumny. Jednak mogą istnieć pewne kompromisy w projektowaniu, które wymagają, aby nie tworzyć pod-partycji. W takim przypadku, prawdopodobnie, użycie wirtualnej kolumny INPUT__FILE__NAME jest najlepszym rozwiązaniem.

Wybór pomiędzy 2 Opcjami:

To naprawdę zależy od Twojego przypadku użycia. Jeśli nigdy nie dbasz o pliki, które próbujesz wykluczyć z tabeli Hive, użycie opcji 2 jest prawdopodobnie przesadą i powinieneś poprawić strukturę katalogów i utworzyć tabelę Hive na Góra katalogu zawierającego pliki, na których Ci zależy.

Jeśli pliki, które obecnie wykluczasz, mają ten sam format co inne pliki (więc mogą być częścią tej samej tabeli Ula) i możesz zobaczyć siebie piszącego zapytanie, które przeanalizuje wszystkie dane w katalogu, a następnie przejdź do opcji 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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-01 00:11:29

Nie Nie możesz Obecnie tego zrobić. Jest otwarty ticket JIRA, który umożliwia wybieranie regex dołączonych plików do tabel Hive ( https://issues.apache.org/jira/browse/HIVE-951).

Na razie najlepiej jest utworzyć tabelę nad innym katalogiem i po prostu skopiować pliki, które chcesz odpytywać.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-29 22:26:55