Big Data, Hadoop & Tworzenie Tabeli w Hive

W poprzednim poście umieściłem info jak załadować dane do hdfs, Teraz by je przeanalizować za pomocą SQL potrzebujemy stworzyć odpowiednią Tabelę w HIVE.

By nie było zbyt pięknie najpierw musimy pobrać Jar’a który pozwoli nam obsłużyć format danych w naszych plikach( z danymi z Twittera).

http://files.cloudera.com/samples/hive-serdes-1.0-SNAPSHOT.jar

 

Jeśli mamy już Jara w jakimś przystępnym miejscu to możemy zalogować się do konsoli Hive. W sandboxie do którego się logowaliśmy przez http, mamy też GUI do obsługi hive, jednakże zalecam skorzystanie z  shella ze względu na lepszą czytelność komunikatów błędów

[root@sandbox conf]# hive

Powinno się pokazać coś takiego:

Logging initialized using configuration in jar:file:/usr/lib/hive/lib/hive-common-0.12.0.2.0.6.0-76.jar!/hive-log4j.properties

SLF4J: Class path contains multiple SLF4J bindings.

SLF4J: Found binding in [jar:file:/usr/lib/hadoop/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: Found binding in [jar:file:/usr/lib/hive/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.

SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

hive>

najpierw dodajemy Jara do Hive:

hive> ADD JAR /usr/local/jakubjars/hive-serdes-1.0-SNAPSHOT.jar;

Wydaje się że trzeba go dodawać po każdym logowaniu co jest upierdliwe, ale jeszcze nie znalazłem miejsca gdzie można by zapisać to na trwałe.

Teraz tworzymy tabele:

CREATE EXTERNAL TABLE tweets (
id BIGINT,
created_at STRING,
source STRING,
favorited BOOLEAN,
retweet_count INT,
retweeted_status STRUCT<
text:STRING,
user:STRUCT<screen_name:STRING,name:STRING>>,
entities STRUCT<
urls:ARRAY<STRUCT<expanded_url:STRING>>,
user_mentions:ARRAY<STRUCT<screen_name:STRING,name:STRING>>,
hashtags:ARRAY<STRUCT<text:STRING>>>,
text STRING,
user STRUCT<
screen_name:STRING,
name:STRING,
friends_count:INT,
followers_count:INT,
statuses_count:INT,
verified:BOOLEAN,
utc_offset:INT,
time_zone:STRING>,
in_reply_to_screen_name STRING)
ROW FORMAT SERDE 'com.cloudera.hive.serde.JSONSerDe'
LOCATION '/dzejkop/flume/tweets';

 

 

To na co warto zwrócić uwagę to fakt iż zagnieżdżone dane zostały zapisane w postaci struktur. Daje to ciekawe możliwości. Według dokumentacji tabela może zawierać dodatkowe nieuwzględnione tutaj pola pod warunkiem że będą one miały nazwę i typ zgodny z danymi JSON od Twittera.

Teraz możemy wykonać przykładowe zapytanie SQL w Hive:

hive> select user.screen_name, user.followers_count c from tweets order by c desc;

powinno nam pokazać nazwy użytkowników I informacje o tym ile posiadają followersów. Zapytanei to nie posiada grupowania więc nazwy userów powinny wystąpić tyle razy ile Tweetów wpadło w nasze sidła. Po wykonaniu zapytania pojawią się różne napisy, zostanie stworzony odpowiedni job, który obrobi dane. Finałow finałów powinniśmy zobaczyć wyniki:

sabou35876529   139
sabou35876529   139
sabou35876529   139
sabou35876529   139
sabou35876529   139
sabou35876529   139
sabou35876529   139
Mister_Ka       137
Mister_Ka       137
Mister_Ka       137
Mister_Ka       137

Korzystając z sandboxa, możemy też wykonywać zapytania, jednakże każdorazowo do każdego zapytania musimy wskazać Jara.

Konfiguracja Flume

Teraz musimy sprawdzić czy mamy odpowiednie katalogi i pliki. De facto nie ma większego znaczenia gdzie będziemy przechowywać pliki konfiguracje dla Flume, jednak do tego został stworzony katalog /etc/ dlatego też sugeruję by zrobić to właśnie tam. Sprawdzmy czy mamy katalog /etc/flume/conf

Jeśli nie to należy go utworzyć:

[root@sandbox ~]# mkdir /etc/flume

[root@sandbox ~]# mkdir /etc/flume/conf

Następnie musimy utworzyć plik konfiguracyjny. W katalogu z binarką możemy odnaleźć przykładowe konfigi, lub też może się zdarzyć że instalator nam je tam już utworzył, jednak nie są one nam do niczego potrzebne. Dlatego też z czystym sumieniem możemy utworzyć swój własny plik:

[root@sandbox ~]# cd /etc/flume/conf

[root@sandbox ~]# touch flume.conf

Teraz nadchodzi ten trudny moment, gdzie trzeba zmierzyć się Vimem ;). Jeśli nie potrafisz korzystać z tego edytora przygotowałem miłą niespodziankę J.  Możesz odpalić mc (midnight commander) i znaleźć nasz utworzony plik i wcisnąć F4.

Jako że mamy do wyboru wiele sourców i sinków, zacznę od prostego przykładu: Flume hello world J. Skonfigurujemy source http i zapis danych do zwykłego pliku. Gdy zrozumiemy zasadę działania pokaże kilka innych konfiguracji.  Po zrozumieniu jak to działa dokumentacja od Flume będzie już wystarczająco zrozumiała by sobie samemu poradzić.

agent1.sources = source1
agent1.sinks = local-file-sink
agent1.channels = channel1

 

agent1.sources.source1.type = org.apache.flume.source.http.HTTPSource
agent1.sources.source1.bind = 192.168.56.101
agent1.sources.source1.port = 5140
agent1.sources.source1.handler.nickname = json handler
agent1.sources.source1.channel = channel1

agent1.sinks.local-file-sink.type = file_roll
agent1.sinks.local-file-sink.channel = channel1
agent1.sinks.local-file-sink.sink.directory = /root/http-test
agent1.sinks.local-file-sink.rollInterval = 5

agent1.channels.channel1.type = memory
agent1.channels.channel1.capacity = 1000
agent1.channels.channel1.transactionCapactiy = 100

agent1 to nazwa agenta identyfikuje ona konkretny przepływ danych. Nazwa jest wymyślana przez nas. Dlatego też szukając po necie przykładów można natrafić na przeróżne konfiguracje i w pierwszym momencie można odnieść wrażenie że się one bardzo różnią.  Każdy agent musi mieć przypisane źródło (lub źródła), kanał(kanały), oraz wyjście (wyjścia). Zaczniemy od prostych przykładów że wszystkiego będzie po jednym.

agent1.sources = source1

właściwość sources jest obligo, source1 to znów przez nas wymyślona nazwa która będzie nam identyfikować dane źródło.

agent1.sinks = local-file-sink

Analogicznie do źródła local-file-sink to nasza nazwa wyjścia. W tym wypadku będą to zapisywane pliki na lokalnym systemie plików.

 

agent1.channels = channel1

Tak samo jak powyżej, nasz kanał będzie buforem w pamięci komputera, znaczy się że będzie wydajny, ale w przypadku awarii agenta część informacji może być stracona.

 

agent1.sources.source1.type = org.apache.flume.source.http.HTTPSource
agent1.sources.source1.bind = 192.168.56.101
agent1.sources.source1.port = 5140
agent1.sources.source1.handler.nickname = json handler
agent1.sources.source1.channel = channel1

zapis konfiguracji przypomina programowanie obiektowe, agent posiada właściwość sources, do której dopisujemy tworzone przez nas źródło i jego właściwości. Zaczynamy od type, tutaj podajemy nazwę klasy która obsługuje dane wejście, bind oznacza adres IP na którym nasłuchujemy, cała reszta wydaje się zrozumiała, należy zwrócić uwagę na przypisanie kanału gdzie source ma przekazać swoje dane. Szczerze mówiąc nie wiem po co jest tam nickname J.

agent1.sinks.local-file-sink.type = file_roll
agent1.sinks.local-file-sink.channel = channel1
agent1.sinks.local-file-sink.sink.directory = /root/http-test
agent1.sinks.local-file-sink.rollInterval = 5

Należy zwrócić uwagę by konfigi były spójne, czyli by nazwy które tworzymy się wzajemnie do siebie odwoływały. Gdy zrobimy literówkę, albo skleimy dwa różne konfigi ze sobą, Flume się potrafi uruchomić poprawnie i nie rzucić nam żadnego błędu. A my stracimy trochę czasu zanim to zauważymyJ. Trzeba też utworzyć katalog w którym mają być zapisywane pliki (/root/http-test). Sinks są stosunkowo dobrze opisane w dokumentacji więc nie powinno być z nimi problemu.  Powyższy konfig będzie powodował powstawanie plików do których będą trafiać dane w formacie JSON wysyłanych po http na wskazany port.

[root@sandbox ~]# mkdir /root/http-test

Aby to przetestować, możemy skorzystać z narzędzia napisanego w javie z naszego komputera hosta (restclient-ui-3.2.2-jar-with-dependencies.jar) jest to prosta aplikacja do pobrania za darmo z sieci. Pozwala ona testować zapytania http. Przyszedł czas na to by odpalić Flume.

[root@sandbox ~]# flume-ng agent -c /etc/flume/conf/ -f /etc/flume/conf/flume-http.conf -n agent1

Należy wskazać ścieżkę do katalogu z plikami konfiguracyjnymi, zalecam podać całą ściężkę. Dodatkowo należy wskazać plik konfiguracyjny oraz nazwę agenta. Proszę zwrócić uwagę na to by nazwą agenta była nazwa z pliku konfiguracyjnego.

Po odpaleniu tej komendy powinno pokazać się wiele różnych rzeczy na konsoli a na koniec plus minus coś takiego:

14/03/18 04:10:18 INFO instrumentation.MonitoredCounterGroup: Monitoried counter group for type: SOURCE, name: source1, registered successfully.

14/03/18 04:10:18 INFO instrumentation.MonitoredCounterGroup: Component type: SOURCE, name: source1 started

Generalnie aplikacja jak działa blokuje nam konsolę. Ale to w niczym nie przeszkadza. Możemy odpalić kolejną sesję putty bądź też skorzystać z konsoli virtualboxa. Po chwili powinny zacząć powstawać pliki we wskazanym katalogu:

[root@sandbox ~]# cd /root/http-test/

[root@sandbox http-test]# ls

1395141017684-1  1395141017684-2  1395141017684-3  1395141017684-4

[root@sandbox http-test]# ls -l

total 0

-rw-r–r– 1 root root 0 Mar 18 04:10 1395141017684-1

-rw-r–r– 1 root root 0 Mar 18 04:10 1395141017684-2

-rw-r–r– 1 root root 0 Mar 18 04:11 1395141017684-3

-rw-r–r– 1 root root 0 Mar 18 04:11 1395141017684-4

-rw-r–r– 1 root root 0 Mar 18 04:12 1395141017684-5

 

Jeśli nie wykonamy żadnych akcji, pliki będą puste. Po odpaleniu rest clienta, możemy wysłać jakiś json. Jako url podajemy wcześniej używany ip i port wskazany w konfiguracji: http://192.168.56.101:5140/. Method Zaznaczamy POST, wchodzimy w zakładkę body i możemy wkleić jakiegoś JSON’a. Np. ten z dokumentacji:

[{

“headers” : {

“timestamp” : “434324343”,

“host” : “random_host.example.com”

},

“body” : “random_body”

},

{

“headers” : {

“namenode” : “namenode.example.com”,

“datanode” : “random_datanode.example.com”

},

“body” : “really_random_body”

}]

 

To o czym w dokumentacji nie napisali to fakt iż do pliku trafiają dane ze zmiennej body.  Najprostszy działający JSON:

[{“body” : “test”}]

W pliku znajdziemy słowo test.

[root@sandbox http-test]# ls –l

-rw-r–r– 1 root root  0 Mar 18 04:10 1395141017684-1

-rw-r–r– 1 root root  0 Mar 18 04:14 1395141017684-10

-rw-r–r– 1 root root 31 Mar 18 04:15 1395141017684-11

-rw-r–r– 1 root root  0 Mar 18 04:15 1395141017684-12

-rw-r–r– 1 root root  0 Mar 18 04:16 1395141017684-13

-rw-r–r– 1 root root  5 Mar 18 04:17 1395141017684-14

-rw-r–r– 1 root root  0 Mar 18 04:10 1395141017684-2

-rw-r–r– 1 root root  0 Mar 18 04:11 1395141017684-3

-rw-r–r– 1 root root  0 Mar 18 04:11 1395141017684-4

-rw-r–r– 1 root root  0 Mar 18 04:12 1395141017684-5

-rw-r–r– 1 root root  0 Mar 18 04:12 1395141017684-6

-rw-r–r– 1 root root  0 Mar 18 04:13 1395141017684-7

-rw-r–r– 1 root root  0 Mar 18 04:13 1395141017684-8

-rw-r–r– 1 root root  0 Mar 18 04:14 1395141017684-9

[root@sandbox http-test]# cat 1395141017684-11

random_body

really_random_body

[root@sandbox http-test]# cat 1395141017684-14

test

 

Jak widać działa.  Teraz możemy zająć się konfiguracją samego Twittera jako źródła danych.

Konfiguracja Twittera jako source

Aby wszystko działało będziemy potrzebować dodatkowy kompoment. Jest to plik jar który będzie obsługiwał komunikację z Twitterem. Dodatkowo będziemy potrzebować dane autoryzacyjne do API Twittera. Zacznijmy jednak od brakującego Jara. Możemy znów pobrać źródła lub gotowy Jar. Na początek polecam skorzystać z gotowca.

http://files.cloudera.com/samples/flume-sources-1.0-SNAPSHOT.jar

Umieszczamy ten plik gdzieś na naszej maszynie wirtualnej.

W katalogu z plikami konfiguracyjnymi (/etc/flume/conf) powinniśmy utworzyć pliko nazwie
flume-env.sh

[root@sandbox conf]# touch flume-env.sh

W pliku tym należy umieścić jedną linię, która będzie wskazywać nam pełną ścieżkę do jara pobranego w poprzednim kroku:

FLUME_CLASSPATH=”/usr/local/jakubjars/flume-sources-1.0-SNAPSHOT.jar

Plik ten będzie wczytywany przy starcie agenta, jeśli ścieżka będzie błędna powinniśmy dostać błąd.

Na chwilę obecną jako że najbardziej interesuje nas pobranie danych z Twittera, wykorzystamy konfig, który stworzyliśmy do pobierania danych z http. Możemy go skopiować:

[root@sandbox conf]# cp flume-http.conf flume-twitter.conf

Następnie edytujemy plik flume-twitter.conf

agent1.sources = Twitter
agent1.channels = channel1
agent1.sinks = local-file-sink

agent1.sources.Twitter.type = com.cloudera.flume.source.TwitterSource
agent1.sources.Twitter.channels = channel1
agent1.sources.Twitter.consumerKey =  wklej kod z twittera
agent1.sources.Twitter.consumerSecret =   wklej kod z twittera
agent1.sources.Twitter.accessToken =   wklej kod z twittera
agent1.sources.Twitter.accessTokenSecret =   wklej kod z twittera
agent1.sources.Twitter.keywords = Poznan, Polska, Ukraina, Ukraine

agent1.sinks.local-file-sink.type = file_roll
agent1.sinks.local-file-sink.channel = channel1
agent1.sinks.local-file-sink.sink.directory = /root/twitter-test
agent1.sinks.local-file-sink.rollInterval = 5

 

agent1.channels.channel1.type = memory
agent1.channels.channel1.capacity = 10000
agent1.channels.channel1.transactionCapacity = 100

 

Dodajemy nowe źródło o nazwie Twitter I usuwamy źródło od http. Należy też podać odpowiednią klasę do obsługi źródła. W Sink zmieniłem katalog w którym będą zapisywane dane. Należy go utworzyć. Teraz należy odpalić Flume i sprawdzić efekty:

[root@sandbox conf]#  flume-ng agent –conf /etc/flume/conf/ -f /etc/flume/conf/flume-twitter.conf   -n agent1

Flume powinien pokazać coś takiego:

14/03/18 05:01:49 INFO twitter4j.TwitterStreamImpl: Establishing connection.

14/03/18 05:01:54 INFO twitter4j.TwitterStreamImpl: Connection established.

14/03/18 05:01:54 INFO twitter4j.TwitterStreamImpl: Receiving status stream.

Teraz należy zobaczyć czy powstały pliki z oczekiwanymi przez nas danymi:

-rw-r–r– 1 root root 379716 Mar 18 05:02 1395144109296-2

-rw-r–r– 1 root root 382754 Mar 18 05:03 1395144109296-3

-rw-r–r– 1 root root 716820 Mar 18 05:04 1395144109296-4

-rw-r–r– 1 root root 309168 Mar 18 05:04 1395144109296-5

O to przykładowy Tweet:

{“filter_level”:”medium”,”retweeted_status”:{“contributors”:null,”text”:”Smiles,                                                              applause and Russian national anthem after signing ceremony to make Crimea part                                                              of Russia. #Ukraine”,”geo”:null,”retweeted”:false,”in_reply_to_screen_name”:nul                                                             l,”truncated”:false,”lang”:”en”,”entities”:{“symbols”:[],”urls”:[],”hashtags”:[{                                                             “text”:”Ukraine”,”indices”:[99,107]}],”user_mentions”:[]},”in_reply_to_status_id                                                             _str”:null,”id”:445892541163257856,”source”:”<a href=\”http://www.hootsuite.com\                                                             ” rel=\”nofollow\”>HootSuite<\/a>”,”in_reply_to_user_id_str”:null,”favorited”:fa                                                             lse,”in_reply_to_status_id”:null,”retweet_count”:5,”created_at”:”Tue Mar 18 12:0                                                             0:40 +0000 2014″,”in_reply_to_user_id”:null,”favorite_count”:0,”id_str”:”4458925                                                             41163257856″,”place”:null,”user”:{“location”:”UK”,”default_profile”:true,”profil                                                             e_background_tile”:false,”statuses_count”:8900,”lang”:”en”,”profile_link_color”:                                                             “0084B4″,”id”:119132506,”following”:null,”favourites_count”:22,”protected”:false                                                             ,”profile_text_color”:”333333″,”description”:”European Bureau Chief, Globe and M                                                             ail. All from a little village in Norfolk, UK.”,”verified”:true,”contributors_en                                                             abled”:false,”profile_sidebar_border_color”:”C0DEED”,”name”:”Paul Waldie  “,”pro                                                             file_background_color”:”C0DEED”,”created_at”:”Tue Mar 02 19:27:17 +0000 2010″,”i                                                             s_translation_enabled”:false,”default_profile_image”:false,”followers_count”:494                                                             4,”profile_image_url_https”:”https://pbs.twimg.com/profile_images/3019033972/d77                                                             1409e131ece4091f2af1ef3586223_normal.jpeg”,”geo_enabled”:true,”profile_backgroun                                                             d_image_url”:”http://abs.twimg.com/images/themes/theme1/bg.png”,”profile_backgro                                                             und_image_url_https”:”https://abs.twimg.com/images/themes/theme1/bg.png”,”follow                                                             _request_sent”:null,”url”:”http://www.theglobeandmail.com/authors/paul-waldie”,”                                                             utc_offset”:-18000,”time_zone”:”Central Time (US & Canada)”,”notifications”:null                                                             ,”profile_use_background_image”:true,”friends_count”:731,”profile_sidebar_fill_c                                                             olor”:”DDEEF6″,”screen_name”:”pwaldieGLOBE”,”id_str”:”119132506″,”profile_image_                                                             url”:”http://pbs.twimg.com/profile_images/3019033972/d771409e131ece4091f2af1ef35                                                             86223_normal.jpeg”,”listed_count”:237,”is_translator”:false},”coordinates”:null}                                                             ,”contributors”:null,”text”:”RT @pwaldieGLOBE: Smiles, applause and Russian nati                                                             onal anthem after signing ceremony to make Crimea part of Russia. #Ukraine”,”geo                                                             “:null,”retweeted”:false,”in_reply_to_screen_name”:null,”truncated”:false,”lang”                                                             :”en”,”entities”:{“symbols”:[],”urls”:[],”hashtags”:[{“text”:”Ukraine”,”indices”                                                             :[117,125]}],”user_mentions”:[{“id”:119132506,”name”:”Paul Waldie  “,”indices”:[                                                             3,16],”screen_name”:”pwaldieGLOBE”,”id_str”:”119132506″}]},”in_reply_to_status_i                                                             d_str”:null,”id”:445893466166689792,”source”:”<a href=\”http://twitter.com/downl                                                             oad/android\” rel=\”nofollow\”>Twitter for Android<\/a>”,”in_reply_to_user_id_st                                                             r”:null,”favorited”:false,”in_reply_to_status_id”:null,”retweet_count”:0,”create                                                             d_at”:”Tue Mar 18 12:04:21 +0000 2014″,”in_reply_to_user_id”:null,”favorite_coun                                                             t”:0,”id_str”:”445893466166689792″,”place”:null,”user”:{“location”:””,”default_p                                                             rofile”:true,”profile_background_tile”:false,”statuses_count”:71883,”lang”:”en”,                                                             “profile_link_color”:”0084B4″,”profile_banner_url”:”https://pbs.twimg.com/profil                                                             e_banners/288755234/1355087024″,”id”:288755234,”following”:null,”favourites_coun                                                             t”:2642,”protected”:false,”profile_text_color”:”333333″,”description”:”Figure wi                                                             th Tweet.\r\n\r\nFocusing on Syria, the wider Arab Spring, and the UK phone hack                                                             ing scandal.  http://brown-moses.blogspot.co.uk”,”verified”:false,”contributors_                                                             enabled”:false,”profile_sidebar_border_color”:”C0DEED”,”name”:”Brown Moses”,”pro                                                             file_background_color”:”C0DEED”,”created_at”:”Wed Apr 27 12:18:25 +0000 2011″,”i                                                             s_translation_enabled”:false,”default_profile_image”:false,”followers_count”:156                                                             98,”profile_image_url_https”:”https://pbs.twimg.com/profile_images/1503800758/FW                                                             M_normal.jpg”,”geo_enabled”:true,”profile_background_image_url”:”http://abs.twim                                                             g.com/images/themes/theme1/bg.png”,”profile_background_image_url_https”:”https:/                                                             /abs.twimg.com/images/themes/theme1/bg.png”,”follow_request_sent”:null,”url”:”ht                                                             tp://brown-moses.blogspot.co.uk”,”utc_offset”:0,”time_zone”:”Casablanca”,”notifi                                                             cations”:null,”profile_use_background_image”:true,”friends_count”:1096,”profile_                                                             sidebar_fill_color”:”DDEEF6″,”screen_name”:”Brown_Moses”,”id_str”:”288755234″,”p                                                             rofile_image_url”:”http://pbs.twimg.com/profile_images/1503800758/FWM_normal.jpg                                                             “,”listed_count”:908,”is_translator”:false},”coordinates”:null}

 

Jak widać dane są mało czytelne, dlatego też w kolejnym kroku postaramy się zapisać dane w Hdfs (hadoop) I później skorzystamy z Hive Aby odpytywać te dane za pomocą SQL co już będzie stosunkowo proste.

 

Konfiguracja Sink z HDFS.

Abyśmy mogli skorzystać z dobrodziejst Hive (odpytywanie via sql) musimy zapisać dane z Twittera w HDFS. Flume ma już przygotowanego odpowiedniego Sinka, jedyne co musimy zrobić to stworzyć odpowiedni katalog w hdfs.

[root@sandbox conf]#  hadoop fs -mkdir /dzejkop

[root@sandbox conf]#  hadoop fs -mkdir /dzejkop/flume

[root@sandbox conf]#  hadoop fs -mkdir /dzejkop/flume/tweets

Zamiast dzejkop oczywiście możemy sobie wstawić dowolną inną nazwę.

 

Aby wszystko zadziałało powinniśmy też dla katalogu w którym będziemy przechowywać tweety nadać odpowiednie uprawnienia:

[root@sandbox conf]#  hadoop fs -chmod -R 777 /dzejkop

 

Edytujemy nasz plik konfiguracyjny flume (możemy sobie utworzyć nową jego wersję).

Usuwamy local-file-sink i wstawiamy HDFS

agent1.sinks = HDFS

agent1.sinks.HDFS.channel = channel1
agent1.sinks.HDFS.type = hdfs
agent1.sinks.HDFS.hdfs.path = hdfs://sandbox:8020/dzejkop/flume/tweets
agent1.sinks.HDFS.hdfs.fileType = DataStream
agent1.sinks.HDFS.hdfs.writeFormat = Text
agent1.sinks.HDFS.hdfs.batchSize = 1000
agent1.sinks.HDFS.hdfs.rollSize = 1024
agent1.sinks.HDFS.hdfs.rollInterval= 60
agent1.sinks.HDFS.hdfs.filePrefix = tweety
agent1.sinks.HDFS.hdfs.fileSuffix = .log
agent1.sinks.HDFS.hdfs.rollCount = 0

 

Proszę pamiętać o zmianie w sinks dla agenta oraz ustawieniu odpowiedniego kanału z którego mają być pobierane dane. Problemem jest trochę ścieżka (Path), teoretycznie powinna być tam nazwa noda hadoop, jednakże przeglądając konfigi nie znalazłem zdefiniowanej nazwy, więc finalnie skorzystałem z nazwy hosta wirtualki. Port jest standardowy dla hdfs:// a ścieżka po porcie to nasz katalog który utworzyliśmy na hdfs. Reszta Parametrów to drobiazgi opisane w dokumentacji Flume.

 

Odpalamy Flume:

[root@sandbox conf]#  flume-ng agent –conf /etc/flume/conf/ -f /etc/flume/conf/flume-twitter.conf   -n agent1

I po chwili powinno zacząć się pojawiać coś takiego:

lume/tweets/tweety.1395147049566.log.tmp

14/03/18 05:51:09 INFO hdfs.BucketWriter: Renaming hdfs://sandbox:8020/dzejkop/flume/tweets/tweety.1395147049566.log.tmp to hdfs://sandbox:8020/dzejkop/flume/tweets/tweety.1395147049566.log

14/03/18 05:51:09 INFO hdfs.BucketWriter: Creating hdfs://sandbox:8020/dzejkop/flume/tweets/tweety.1395147049567.log.tmp

Teraz Tweety są zbierane do Hadoopa. Pozostaje nam utworzyć odpowiednią tabelę w Hive i zacząć się bawić SQL :).

Instalacja Flume.

Flume napisany jest w Javie, możemy pobrać kod źródłowy z Githuba, albo zainstalować gotowy pakiet przez yum, lub ściągnąć binarkę. Generalnie nie ma większej różnicy. Nie ważne który wariant wybierzemy będziemy musieli się upewnić czy istnieją pewne pliki. Najprościej jest skorzystać z yum:

[root@sandbox ~]# yum install -y flume

Później:

[root@sandbox ~]# yum install -y flume-agent

Po wykonaniu jednej i drugiej komendy na końcu efekt powinien być podobny do tego:

Installed:

flume-agent.noarch 0:1.4.0.2.0.6.0-76.el6

Complete!

Weryfikacja instalacji, jest prosta:

[root@sandbox ~]# flume-ng

Error: Unknown or unspecified command ”

 

Usage: /usr/lib/flume/bin/flume-ng <command> [options]…

 

 …

  –help,-h              display help text

 

  Either –rpcProps or both –host and –port must be specified.

 

Note that if <conf> directory is specified, then it is always included first

in the classpath.

 

Teraz wiemy że wszystko działa. Jeśli ściągnęliśmy binarkę, bądź kompilowaliśmy ze źródeł, należy przejść do katalogu w którym znajduje się plik flume-ng (flume/bin) u mnie to wyglądało tak:

/root/flume/apache-flume-1.4.0-bin/bin

Pobrałem binarkę do katalogu /root/flume, tam ją rozpakowałem i powstał katalog apache-flume-1.4.0-bin.

 

Jeśli bawiliśmy się w instalację ze źródeł, która jest dość upierdliwa:

/root/download/apache-flume-1.4.0-src/flume-ng-dist/target/apache-flume-1.4.0-bin/apache-flume-1.4.0-bin/bin

To ścieżka może wyglądać plus minus tak.

Teraz czas na Konfiguracja Flume

Konfiguracja Wirtualki – HortonWorks Sandbox

Krok pierwszy to uruchomienie wirtualki z Hortonworks. Generalnie wystarczy pobrany obraz zaimportować do virtualbox. Jednakże by wszystko działało zgodnie z naszymi oczekiwaniami powinniśmy zmienić ustawienia sieci. Przed uruchomieniem maszyny wirtualnej w ustawieniach (devices/network) należy Adapter 1 ustawić jako host only(attached to). Należy także kliknąć zakładkę z adapter 2 i tam wybrać opcję NAT (attached to). Zgodnie z obrazkami poniżej:

Wybierz odpowiednią wirtualkę
wybranie odpowiedniej wirtualki
ustawienia wirtualki
Wybierz ustawienia z menu w celu edycji ustawień sieciowych
adapter 1
ustawienia karty sieciowej nr 1.
adapter 2
ustawienia karty sieciowej nr 2.

W ten sposób maszyna wirtualna może korzystać z sieci Internet oraz swobodnie komunikować się w obie strony z maszyną hostem. Można się także zastanowić nad przydzieleniem większej ilości pamięci Ram. Ja przypisałem swojej wirtualce 4GB ram (komputer ma 8GB pamięci). W ustawieniach w zakładce system należy przesunąć suwak:

zmiana pamięci RAM
przesuń suwak na odpowiednią wartość

 

Jeśli korzystamy z systemu Windows, przydadzą nam się jeszcze 2 freeware’’owe narzędzia: putty oraz winscp. Pierwsze to aplikacja do podłączenia się do linii komend naszej maszyny wirtualnej. Druga aplikacja pozwala na kopiowanie i przenoszenie plików pomiędzy maszynami.

Gdy mamy już komplet zabawek, odpalamy maszynę wirtualną.  Po jej uruchomieniu w oknie virtualbox pokaże się komunikat z adresem http.

ekran powitalny hortonworks
Ekran powitalny hortonworks

Należy w tym momencie wcisnąć alt + f5 (zgodnie z informacjami na dole ekranu). Pojawi się okno z logowaniem (oraz z loginem i hasłem 😉 ).

logowanie do hortonworks
logowanie do hortonworks

Nasza maszyna jest dość uboga w narzędzia dodatkowe, możemy poruszać się za pomocą linii komend co dla pewnych osób może być dość upierdliwe. Najpierw sprawdźmy czy wszystko działa.

Weryfikacja adresów IP

Wywołajmy komendę ifconfig eth0, powinna ona zwrócić coś takiego:

eth0      Link encap:Ethernet  HWaddr 08:00:27:B1:D7:08
inet addr:192.168.56.101  Bcast:192.168.56.255  Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:feb1:d708/64 Scope:Link
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
RX packets:26301 errors:0 dropped:0 overruns:0 frame:0
TX packets:28872 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4005290 (3.8 MiB)  TX bytes:26068182 (24.8 MiB)
Interrupt:19 Base address:0xd020

Wklejenie adresu IP do naszej przeglądarki powinno nam wyświetlić okno powitalne ‘sandboxa’.

Okno powitalne Sandbox
Okno powitalne Sandbox, Interfejs HUE

Po kliknięciu go to sandbox, powinno nam się pojawić okno w którym możemy pracować z różnymi narzędziami zbudowanymi wokół Hadoop.

Korzystając z tego samego adresu IP, powinniśmy się podłączyć przez putty do tej samej linii komend. Po podłączeniu się sprawdźmy czy nasza maszyna wirtualna posiada dostęp do Internetu, możemy wykonać komendę ping (komendy są wyboldowane, można je skopiować, wkleja się do putty po przez kliknięcie prawym przyciskiem myszy):

Weryfikacja działania sieci

[root@sandbox ~]# ping onet.pl

PING onet.pl (213.180.141.140) 56(84) bytes of data.

64 bytes from sg1.any.onet.pl (213.180.141.140): icmp_seq=2 ttl=58 time=24.2 ms

64 bytes from sg1.any.onet.pl (213.180.141.140): icmp_seq=3 ttl=58 time=17.2 ms

 

Jeśli ukaże się coś podobnego znaczy się że jest ok. Aby przerwać ‘pingowanie’ należy wcisnąć ctrl + c.

Wtedy ukaże się coś takiego:

— onet.pl ping statistics —

3 packets transmitted, 2 received, 33% packet loss, time 2445ms

rtt min/avg/max/mdev = 17.220/20.733/24.246/3.513 ms

 

Instalacja midnight commander’a

Teraz możemy zainstalować midnight commander’a (odpowiednik Norton commandera/ lub Total Commandera). Aby to uczynić należy wklepać:

[root@sandbox ~]# yum install -y mc

Pokażą się różne komunikaty, które po chwili powinny zakończyć się plus minus tak:

Installed:

mc.x86_64 1:4.7.0.2-3.el6

Complete!

Aktualizacja JDK javy

Aby wszystko działało w pełni sprawnie byłem zmuszony do przeprowadzenia aktualizacji JDK Javy. Wirtualka HortonWorks została dostarczona z wersją 1.6 a Flume(lub któryś z jego dodatków) potrzebował wersji 1.7. Z strony Oracle pobrałem odpowiednie jdk z postaci RPM dla architektury 64bit (System operacyjny to CentOS). Jako że ze strony Oracle Wget nie chciał pobrać tego rpm’a pobrałem go z poziomu hosta (mojego Windowsa). Na maszynę wirtualną skopiowałem plik przy pomocy winscp (podajemy adres IP wirtualnej maszyny i login i hasło do konsoli). W katalogu w którym się znajduje plik odpalamy komendę:

[root@sandbox ~]# rpm -i jdk-7u51-linux-x64.rpm

Później trzeba jeszcze zaktualizować zmienną środowiskową wskazującą na katalog w którym java jest zainstalowana:

[root@sandbox ~]# export JAVA_HOME=’/usr/java/jdk1.7.0_51/’

 

Proszę zwrócić uwagę iż z czasem nr wersji mogą się zmienić I skopiowanie komend może nie przynieść oczekiwanych rezultatów.,

Kolejny krok to: Instalacja Flume.