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 :).

Leave a Reply

Your email address will not be published. Required fields are marked *

two × three =