2011-12-10 13 views
6

Czy można uzyskać rozproszone odczyty z klastra HDSF przy użyciu klienta HDFS na jednym komputerze?HDFS rozproszone odczyty bez mapy/redukcja

Przeprowadziłem eksperyment z klastrem złożonym z 3 węzłów danych (DN1, DN2, DN3). Następnie uruchomiłem 10 równoczesnych odczytów z 10 niezależnych plików z programu klienckiego zlokalizowanego na DN1 i wydawało się, że jest to tylko odczyt danych z DN1. Inne węzły danych (DN2, DN3) wykazywały zerową aktywność (sądząc po dziennikach debugowania).

Sprawdziłem, czy wszystkie bloki plików są replikowane we wszystkich 3 datanodach, więc jeśli wyłączyłem DN1, dane są odczytywane z DN2 (tylko DN2).

Zwiększenie ilości odczytanych danych nie pomogło (próbowano z 2 GB do 30 GB).

Ponieważ potrzebuję przeczytać wiele dużych plików i wyodrębnić z nich tylko niewielką ilość danych (kilka kilobitów), chciałbym uniknąć używania mapy/zmniejszenia, ponieważ wymaga ona ustawienia więcej usług, a także wymaga napisania wyjście każdego podzielonego zadania z powrotem do HDFS. Byłoby miło, gdyby wynik był przesyłany bezpośrednio z powrotem do mojego programu klienta z węzłów danych.

Używam SequenceFile danych odczytu/zapisu, w ten sposób (jdk7):

//Run in thread pool on multiple files simultaneously 

List<String> result = new ArrayList<>(); 
LongWritable key = new LongWritable(); 
Text value = new Text(); 
try(SequenceFile.Reader reader = new SequenceFile.Reader(conf, 
            SequenceFile.Reader.file(filePath)){ 
    reader.next(key); 
    if(key.get() == ID_I_AM_LOOKING_FOR){ 
    reader.getCurrentValue(value); 
    result.add(value.toString()); 
    } 
} 

return result; //results from multiple workers are merged later 

Każda pomoc mile widziana. Dzięki!

Odpowiedz

7

Obawiam się, że zachowanie, które widzisz, jest w toku. Od Hadoop document:

Replika Wybór

Aby zminimalizować globalne zużycie pasma i opóźnienia odczytu, HDFS próbuje zaspokoić żądania odczytu z repliką, która jest najbardziej zbliżona do czytnika . Jeśli istnieje replika na tym samym stojaku, co węzeł czytelnika, , wówczas replika jest preferowana, aby spełnić żądanie odczytu. Jeśli klaster HDFS ang. Ang. obejmuje wiele centrów danych, wówczas replika o numerze rezydująca w lokalnym centrum danych jest preferowana względem dowolnej zdalnej repliki .

To może być dodatkowo potwierdzone przez odpowiednie Hadoop source code:

LocatedBlocks getBlockLocations(...) { 
    LocatedBlocks blocks = getBlockLocations(src, offset, length, true, true); 
    if (blocks != null) { 
     //sort the blocks 
     DatanodeDescriptor client = host2DataNodeMap.getDatanodeByHost(
      clientMachine); 
     for (LocatedBlock b : blocks.getLocatedBlocks()) { 
     clusterMap.pseudoSortByDistance(client, b.getLocations()); 

     // Move decommissioned datanodes to the bottom 
     Arrays.sort(b.getLocations(), DFSUtil.DECOM_COMPARATOR); 
     } 
    } 
    return blocks; 
    } 

To znaczy, wszystkie dostępne repliki są sprawdzane jeden po drugim, jeśli nie były jeden ale najbliższy jest zawsze pierwszy.

Z drugiej strony, jeśli uzyskujesz dostęp do plików HDFS przez HDFS Proxy, wybiera ona datany randomly. Ale nie sądzę, że tego właśnie chcesz.

+0

Dzięki. To wyjaśnia to! Dzięki za wskazówkę dla proxy. – rodion

+1

W jaki sposób Hadoop wie, który węzeł jest na którym stelażu - http://hadoop.apache.org/common/docs/current/cluster_setup.html#Hadoop+Rack+Awareness –

+0

Co to jest "angg"? –

3

Oprócz tego, co Edwardw powiedział, należy zauważyć, że aktualny klaster jest bardzo mały (tylko 3 węzły) iw tym przypadku widać pliki we wszystkich węzłach. Dzieje się tak, ponieważ domyślny współczynnik replikacji w Hadoop jest równy 3. W większym klastrze Twoje pliki nie będą dostępne w każdym węźle, więc uzyskanie dostępu do wielu plików będzie prawdopodobnie odbywać się w różnych węzłach i rozkładać obciążenie.

Jeśli pracujesz z mniejszych zbiorów danych może warto spojrzeć na HBase który pozwala pracować z mniejszymi kawałkami i rozłożyć obciążenie pomiędzy węzłami (w regionach łupania)

+0

Masz rację. Naprawdę próbowałem ustawić replikację na 1, próbując równomiernie rozprowadzać bloki w klastrze, ale ostatecznie skończyło się zapisywanie ich wszystkich do DN1: ((myślę, że potrzebuję więcej danych i bloków zanim zacznie balansować je pomiędzy różnymi węzłami. Dzięki za podpowiedź HBase, mogę pożyczyć kilka pomysłów stamtąd – rodion

0

chciałbym powiedzieć, że sprawa brzmi dobrze dla MR. Jeśli odłożymy na bok szczególny paradygmat obliczeniowy MR, możemy powiedzieć, że hadoop jest zbudowany tak, aby wprowadzać kod do danych, a nie odwrotnie. Przeniesienie kodu do danych jest niezbędne, aby uzyskać skalowalne przetwarzanie danych.
Z drugiej strony - konfigurowanie MapReduce jest łatwiejsze niż HDFS - ponieważ nie przechowuje żadnego stanu między zadaniami.
W tym samym czasie - struktura MR będzie dbać o przetwarzanie równoległe dla ciebie - coś, co zajmie trochę czasu, aby zrobić to poprawnie.
Kolejny punkt - jeśli wyniki przetwarzania danych są tak małe - nie będzie znaczący wpływ na wydajność, jeśli połączymy je razem w reduktorze.
Innymi słowy - sugerowałbym ponowne rozważenie użycia MapReduce.

+0

Dzięki, będę potrzebować testów wydajnościowych :) – rodion

+0

Jeśli podasz mi jakieś informacje, spróbuję helo z ocenami –

+0

Dzięki. To całkiem proste, zasadniczo wyszukiwanie podobne do grep na dużych plikach danych dzienników Dane dziennika mogą mieć dowolną treść. Mam dwa typy wyszukiwania: 1) podobieństwo grep-podlewanie/dopasowanie do regex w treści 2) wyszukiwanie znanego dziennika pozycja (pozycje/numery identyfikacyjne są przechowywane osobno) i po prostu pobierz zawartość. Możesz założyć, że zestaw wyników zawsze będzie mały: 0 ~ 100 logów. Używam również kompresji bloków (używając API 'SequenceFile'). – rodion