<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Flume on BigDataPassion</title>
        <link>https://bigdatapassion.pl/categories/flume/</link>
        <description>Recent content in Flume on BigDataPassion</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>pl</language>
        <lastBuildDate>Tue, 19 Nov 2019 00:00:00 +0000</lastBuildDate><atom:link href="https://bigdatapassion.pl/categories/flume/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>Apache Flume jako agregator strumieni danych</title>
            <link>https://bigdatapassion.pl/blog/apache-flume-jako-agregator-strumieni-danych/</link>
            <pubDate>Tue, 19 Nov 2019 00:00:00 +0000</pubDate>
            <guid>https://bigdatapassion.pl/blog/apache-flume-jako-agregator-strumieni-danych/</guid>
            <description>&lt;img src=&#34;https://bigdatapassion.pl/img/devops/flume-logo-1.png&#34; alt=&#34;Featured image of post Apache Flume jako agregator strumieni danych&#34; /&gt;&lt;p&gt;W środowiskach Big Data proces przejmowania jest często elementem całości przepływu ETL. Owe przejmowanie danych rozumiemy jako pobieranie treści z takich źródeł jak bazy danych czy pliki. Bardziej złożonymi formami (w większości przypadków) to źródła rzadziej używane na co dzień a więc NoSQL, maile, API, IoT, których skala, różnorodność i złożoność można opisać w dwóch słowach: Volume i Variety. Przy tak dużym surowcu danych naturalną decyzją jest przejście z modelu przetwarzania wsadowego na tryb czasu rzeczywistego (np. przy użyciu narzędzia Kafka). Dochodzimy do kolejnego &lt;code&gt;V&lt;/code&gt; jakim jest Velocity: czas, prędkość i zmienność. Czwartym elementem opisywanych danych jest Veracity: jakość, pewność i pochodzenie. I tu wkradają się kolejne wyzwania, gdzie należy stawić czoła: niedokładności danych, niekompletności, niespójności, wątpliwej (nieopisanej) wiarygodności czy nieprawdziwości. Wynik eksploracji danych jest mocno zależny od ich jakości.&lt;/p&gt;&#xA;&lt;h2 id=&#34;apache-flume-i-podobne-rozwiązania&#34;&gt;Apache Flume i podobne rozwiązania&#xA;&lt;/h2&gt;&lt;p&gt;Flume to projekt &lt;code&gt;Apache Software Foundation&lt;/code&gt;, jest opisany jako usługa agregowania danych, która jest: rozproszona, niezawodna i dostępna. Flume jest bardzo elastyczny (umożliwia wiele idei wdrażania) i umożliwia przesyłanie dużych ilości danych (ruch sieciowy, dane społecznościowe, logi) co daje dużo możliwości dostosowania do środowiska. Należy uwypuklić dużą konfigurowalność narzędzia, aplikacja nie ogranicza się tylko do agregacji danych. Przykład, jeśli musimy wdrożyć dane dziennika (tekstowe) do Hadoopa/HDFS to Flume jest odpowiednim narzędziem.&lt;/p&gt;&#xA;&lt;p&gt;Ograniczeniem wielkości tego bytu jest (technicznie) możliwość zapisu go w przestrzeni dyskowej czy pamięci. Należy zwrócić uwagę, że aplikacja stworzona jest do ciągłego przetwarzania danych, lecz brak tej stabilności strumienia danych nie powoduje problemów w jej funkcjonowaniu.&lt;/p&gt;&#xA;&lt;p&gt;Warto zarekomendować, że ze względu na swą łatwość konfiguracji Flume jest uwielbianym konstruktorem logów a uznawanie go za &amp;lsquo;realtime data processors&amp;rsquo; jest jednym z jego funkcjonalności. Popularność zawdzięcza faktowi, że było to jedne z pierwszych narzędzi do gromadzenia danych w Hadoopie. Flume też ma swoją smutniejszą stronę, jest wypierany przez inne narzędzia (np. takie jak NiFi) i zasadność wdrożenia tej technologi należy poprzedzić analizą a więc zainwestować czas na prześledzenie innych dostępnych rozwiązań.&lt;/p&gt;&#xA;&lt;p&gt;Podobne technologie to:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Sqoop (hadoop &amp;lt;-&amp;gt; RDBMS)&lt;/li&gt;&#xA;&lt;li&gt;Oozie (natywne hadoopowe narzędzie do uporządkowania ETL)&lt;/li&gt;&#xA;&lt;li&gt;NiFi (zarządza i kontroluje przepływy z obsługą myszki - GUI)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;img loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://bigdatapassion.pl/img/devops/flume-schema-2.png&#34;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;technicznie-o-flume&#34;&gt;Technicznie o Flume&#xA;&lt;/h2&gt;&lt;p&gt;Flume jest zaprojektowany do transportu i przetwarzania regularnie generowanych danych zdarzeń w relatywnie stabilnych, potencjalnie złożonych topologiach. Jak już jesteśmy przy &lt;code&gt;zdarzeniach&lt;/code&gt; to je zdefiniujmy jako ciąg znaków (bajtów). Przykładem może być wcześniej wspomniany wpisu logu (tekst) lub obrazek. Reguralnie generowane dane możemy przedstawić jako strumienie danych.&lt;/p&gt;&#xA;&lt;p&gt;Wymagania systemu ograniczają się tylko do:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;jdk 1.8+&lt;/li&gt;&#xA;&lt;li&gt;większej ilości pamięci - w zależności od wielkości przetwarzanych zasobów&lt;/li&gt;&#xA;&lt;li&gt;powierzchnia dyskowa na składowanie danych&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;przepływ-danych&#34;&gt;Przepływ danych&#xA;&lt;/h2&gt;&lt;p&gt;&lt;img loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://bigdatapassion.pl/img/devops/flume-schema-3.png&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Flum definiuje 3 parametry, które trywialnie można je opisać wg ich przeznaczenia:&lt;/p&gt;&#xA;&lt;p&gt;Source&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;konfiguracja danych wejściowych&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Channel&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;proces przetwarzania (przeskok)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Sink&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;rozdzielenie danych wyjściowych&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Składnia w pliku konfiguracyjnym&lt;/p&gt;&#xA;&lt;p&gt;Aranżacja w pliku:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;Agent&amp;gt;.sources.&amp;lt;Source&amp;gt;.&amp;lt;someProperty&amp;gt; = &amp;lt;someValue&amp;gt;&#xA;&amp;lt;Agent&amp;gt;.channel.&amp;lt;Channel&amp;gt;.&amp;lt;someProperty&amp;gt; = &amp;lt;someValue&amp;gt;&#xA;&amp;lt;Agent&amp;gt;.sources.&amp;lt;Sink&amp;gt;.&amp;lt;someProperty&amp;gt; = &amp;lt;someValue&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;podsumowanie-teorii&#34;&gt;Podsumowanie teorii&#xA;&lt;/h2&gt;&lt;p&gt;Zdarzenie Flume jest zdefiniowane jako jednostka przepływu danych posiadająca ładunek bajtów i opcjonalny zestaw atrybutów ciągu. Agent Flume to proces (JVM), który hostuje komponenty, przez które zdarzenia przepływają ze źródła zewnętrznego do następnego miejsca docelowego (przeskoku). Kropka.&lt;/p&gt;&#xA;&lt;h2 id=&#34;przygotowanie-środowiska&#34;&gt;Przygotowanie środowiska&#xA;&lt;/h2&gt;&lt;p&gt;Posłużymy się oraclowym JDK8 (opisane w poprzednich artykułach, więc nie powielamy treści) i Flume w wersji 1.9.0, gdzie możemy pobrać ze strony &lt;a class=&#34;link&#34; href=&#34;http://ftp.man.poznan.pl/apache/flume/1.9.0/apache-flume-1.9.0-bin.tar.gz&#34;  title=&#34;Apache Flume download ver. 1.9.0&#34;&#xA;     target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;ftp.man.poznan.pl&lt;/a&gt;. Zwróćmy uwagę na weryfikację pobranych treści, ale po kolei.&lt;/p&gt;&#xA;&lt;p&gt;Po właściwej instalacji Java Developer Kit powinniśmy otrzymać wynik polecenia sprawdzającego wersje javy &lt;code&gt;java -version&lt;/code&gt; tak jak poniżej.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;java version &amp;#34;1.8.0_221&amp;#34;&#xA;Java(TM) SE Runtime Environment (build 1.8.0_221-b11)&#xA;Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Na maszynie, która będzie nam służyła jako agent tworzymy katalog &lt;code&gt;/opt-dev&lt;/code&gt; i w nim pobieramy aplikacje.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;root@host104:~# mkdir /opt-dev&#xA;root@host104:~# cd /opt-dev&#xA;root@host104:/opt-dev# wget http://ftp.man.poznan.pl/apache/flume/1.9.0/apache-flume-1.9.0-bin.tar.gz&#xA;--2019-10-21 20:54:57--  http://ftp.man.poznan.pl/apache/flume/1.9.0/apache-flume-1.9.0-bin.tar.gz&#xA;Resolving ftp.man.poznan.pl (ftp.man.poznan.pl)... 150.254.173.17, 2001:808::173:17&#xA;Connecting to ftp.man.poznan.pl (ftp.man.poznan.pl)|150.254.173.17|:80... connected.&#xA;HTTP request sent, awaiting response... 200 OK&#xA;Length: 67938106 (65M) [application/x-gzip]&#xA;Saving to: &amp;#39;apache-flume-1.9.0-bin.tar.gz&amp;#39;&#xA;&#xA;apache-flume-1.9.0-bin.tar 100%[======================================&amp;gt;]  64.79M  4.89MB/s    in 13s     &#xA;&#xA;2019-10-21 20:55:10 (4.86 MB/s) - &amp;#39;apache-flume-1.9.0-bin.tar.gz&amp;#39; saved [67938106/67938106]&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Teraz pobieramy pliki, które posłużą nam jako zbiory do porównania pobranej binarki z flumem oraz klucz.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# wget -q http://www.apache.org/dist/flume/1.9.0/apache-flume-1.9.0-bin.tar.gz.sha512&#xA;# wget -q http://www.apache.org/dist/flume/1.9.0/apache-flume-1.9.0-bin.tar.gz.asc&#xA;# wget -q http://www.apache.org/dist/flume/KEYS -O asf_keys&#xA;&lt;/code&gt;&lt;/pre&gt;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;Korzystając z polecenia &lt;strong&gt;wget&lt;/strong&gt; posłużyliśmy się przełącznikiem &lt;strong&gt;-q&lt;/strong&gt; tylko dlatego, aby zaśmiecać wpisów zbędnymi informacjami.&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;Nasz katalog powinien posiadać trzy pliki&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;root@host104:/opt-dev# tree -a /opt-dev/&#xA;/opt-dev/&#xA;|-- apache-flume-1.9.0-bin.tar.gz&#xA;|-- apache-flume-1.9.0-bin.tar.gz.asc&#xA;|-- apache-flume-1.9.0-bin.tar.gz.sha512&#xA;`-- asf_keys&#xA;&#xA;0 directories, 4 files&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Mamy już wszystko, importujemy klucze deweloperów.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;root@host104:/opt-dev# gpg --import asf_keys &#xA;gpg: key CD14AD58901791C2: public key &amp;#34;Eric Sammer &amp;lt;esammer@apache.org&amp;gt;&amp;#34; imported&#xA;...&#xA;gpg: Total number processed: 9&#xA;gpg:               imported: 9&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dla każdego autora mamy zapis mówiący o zaimportowaniu &lt;code&gt;public key &amp;quot;Ktoś Tam &amp;lt;jego@e-mail&amp;gt;&amp;quot; imported&amp;quot;&lt;/code&gt; jego klucza do bazy. Zauważmy, że przy kolejnym imporcie mamy już informację, że klucz nie został ponownie dodany &lt;code&gt;not changed&lt;/code&gt; - dzieje się to w sytuacji, gdy już wcześniej w naszej bazie mieliśmy już wpis, przykład poniżej.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;root@host104:/opt-dev# gpg --import asf_keys &#xA;gpg: key CD14AD58901791C2: &amp;#34;Eric Sammer &amp;lt;esammer@apache.org&amp;gt;&amp;#34; not changed&#xA;...&#xA;gpg: Total number processed: 9&#xA;gpg:              unchanged: 9&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sposobów weryfikacji jest kilka i zostały opublikowane na &lt;a class=&#34;link&#34; href=&#34;http://www.apache.org/dyn/closer.lua/flume/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;stronie pobierania&lt;/a&gt;. Czas rozpakować paczkę i powinniśmy otrzymać podobną strukturę jak poniżej.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;root@host104:/opt-dev# tar zxf apache-flume-1.9.0-bin.tar.gz&#xA;root@host104:/opt-dev# tree -L 2 -a /opt-dev/&#xA;/opt-dev/&#xA;|-- apache-flume-1.9.0-bin&#xA;|   |-- bin&#xA;|   |-- CHANGELOG&#xA;|   |-- conf&#xA;|   |-- DEVNOTES&#xA;|   |-- doap_Flume.rdf&#xA;|   |-- docs&#xA;|   |-- lib&#xA;|   |-- LICENSE&#xA;|   |-- NOTICE&#xA;|   |-- README.md&#xA;|   |-- RELEASE-NOTES&#xA;|   `-- tools&#xA;|-- apache-flume-1.9.0-bin.tar.gz&#xA;|-- apache-flume-1.9.0-bin.tar.gz.asc&#xA;|-- apache-flume-1.9.0-bin.tar.gz.sha512&#xA;`-- asf_keys&#xA;&#xA;6 directories, 11 files&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;W katalogu &lt;code&gt;conf&lt;/code&gt; znajdują się pliki konfiguracyjne, które możemy wykorzystać. Tworzymy kopie plików z dopiskiem &lt;code&gt;.template&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# cd apache-flume-1.9.0-bin&#xA;# pwd&#xA;/opt-dev/apache-flume-1.9.0-bin&#xA;# cp conf/flume-conf.properties.template conf/flume-conf.properties&#xA;# cp conf/flume-env.ps1.template conf/flume-env.ps1&#xA;# cp conf/flume-env.sh.template conf/flume-env.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Po wskazanych działaniach zawartość katalogu konfiguracji powinna być podobna do poniższego schematu.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;root@host104:/opt-dev/apache-flume-1.9.0-bin# tree conf/&#xA;conf/&#xA;|-- flume-conf.properties&#xA;|-- flume-conf.properties.template&#xA;|-- flume-env.ps1&#xA;|-- flume-env.ps1.template&#xA;|-- flume-env.sh&#xA;|-- flume-env.sh.template&#xA;`-- log4j.properties&#xA;&#xA;0 directories, 7 files&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Na potrzeby tego ćwiczenie należy utworzyć strukturę katalogów na &lt;code&gt;hdfs&lt;/code&gt;. Owe miejsce będzie służyło do zapisów wyników działania flume.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# hdfs dfs -mkdir -p /bigdata/flume/cw1&#xA;# hdfs dfs -ls -R /&#xA;drwxr-xr-x   - root supergroup          0 2019-10-21 22:34 /bigdata&#xA;drwxr-xr-x   - root supergroup          0 2019-10-21 22:34 /bigdata/flume&#xA;drwxr-xr-x   - root supergroup          0 2019-10-21 22:34 /bigdata/flume/cw1&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Dodajemy pierwsze zapiski mówiące co i gdzie należy wrzucać dane do &lt;code&gt;flume-conf.properties&lt;/code&gt;&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;passion0x00.sources                              = src0x00&#xA;passion0x00.sinks                                = snk0x00&#xA;passion0x00.channels                             = chn0x00&#xA;passion0x00.sources.src0x00.channels             = chn0x00&#xA;passion0x00.sinks.snk0x00.channel                = chn0x00&#xA;passion0x00.sinks.snk0x00.type                   = HDFS&#xA;passion0x00.sinks.snk0x00.fileType               = DataStream&#xA;passion0x00.sinks.snk0x00.hdfs.path              = hdfs://h3host200.bigdatalinux.com:8020/bigdata/flume/cw1&#xA;passion0x00.sinks.snk0x00.hdfs.filePrefix        = infoout&#xA;passion0x00.sinks.snk0x00.hdfs.writeFormat       = Text&#xA;passion0x00.sinks.snk0x00.hdfs.rollInterval      = 0&#xA;passion0x00.sinks.snk0x00.hdfs.rollSize          = 0&#xA;passion0x00.sinks.snk0x00.hdfs.rollCount         = 1000&#xA;passion0x00.sinks.snk0x00.hdfs.batchSize         = 100&#xA;passion0x00.sinks.snk0x00.hdfs.useLocalTimeStamp = true&#xA;passion0x00.sinks.snk0x00.hdfs.callTimeout       = 180000&#xA;passion0x00.channels.chn0x00.type                = memory&#xA;passion0x00.channels.chn0x00.capacity            = 256&#xA;passion0x00.channels.chn0x00.transactionCapacity = 128&#xA;passion0x00.sources.src0x00.type                 = org.apache.flume.source.StressSource&#xA;passion0x00.sources.src0x00.size                 = 512&#xA;passion0x00.sources.src0x00.maxTotalEvents       = 2048&#xA;passion0x00.sources.src0x00.batchSize            = 1&#xA;passion0x00.sources.src0x00.maxEventsPerSecond   = 128 &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Powyższa konfiguracja dla danych wejściowych ustawia losowe znaki z dużym limitem, aby nie zapełnić zbędnymi danymi HDFS-a. Co prawda użyłem &lt;code&gt;org.apache.flume.source.StressSource&lt;/code&gt;, które służy do przeprowadzania testów wydajnościowych, lecz takie rozwiązanie jest najprostsze tj. out-of-the-box.&lt;/p&gt;&#xA;&lt;p&gt;Zapis następuje na katalog na Hadoopie wraz z kilkoma parametrami, które są opcjonalne. Pomocny może się okazać &lt;code&gt;passion0x00.sinks.snk0x00.hdfs.callTimeout&lt;/code&gt; w którym określamy czas oczekiwania na potwierdzenie transakcji zapisu.&lt;/p&gt;&#xA;&lt;p&gt;Pozostaje nam tylko uruchomić na kilka minut a następnie zabić agenta flume. Gdyby wystąpiły problemy z wystartowaniem usługi można się wspomóc dodatkowym przełącznikiem &lt;code&gt;flume.root.looger=DEBUG,console&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;time bin/flume-ng agent \&#xA;     -n passion0x00 -c conf \&#xA;     -f conf/flume-conf.properties&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;W katalogu &lt;code&gt;/bigdata/flume/cw1&lt;/code&gt; powinniśmy zobaczyć kilka plików.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ hdfs dfs -ls /bigdata/flume/cw1&#xA;Found 3 items&#xA;-rw-r--r--   2 hdfs hdfs     531286 2019-10-22 23:31 /bigdata/flume/cw1/infoout.1571779877530&#xA;-rw-r--r--   2 hdfs hdfs     531286 2019-10-22 23:31 /bigdata/flume/cw1/infoout.1571779877531&#xA;-rw-r--r--   2 hdfs hdfs      25594 2019-10-22 23:31 /bigdata/flume/cw1/infoout.1571779877532.tmp&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;nie-działa&#34;&gt;Nie działa?&#xA;&lt;/h2&gt;&lt;p&gt;W moim przypadku miałem problemy z połączeniem do HDFS-a w wersji 3.2.1 (wydanie z 22. września 2019). Problem wynikał z m. in. z brakiem nowszej wersji pliku jar odpowiedzialnego za komunikacje z DFS. Test przeprowadzone na hadoop 2.9.2 (19. listopada 2018) dały już pożądane rezultaty. Warto zaznajomić sie z &lt;a class=&#34;link&#34; href=&#34;https://www.ietf.org/rfc/rfc2119.txt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://www.ietf.org/rfc/rfc2119.txt&lt;/a&gt; a następnie ze zdaniem  &lt;strong&gt;Apache Hadoop revisions SHOULD retain binary compatability such that end-user applications continue to work without any modifications&lt;/strong&gt; - to daje nam ogólny pogląd na nasze problemy :)&lt;/p&gt;&#xA;&lt;p&gt;Na zakończenie. Zadanie było wykonywane na kilku środowiskach, stąd nie należy sie sugerować nazwa hosta czy GID/UID na wylistowanych przykładach.&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
