Authors

Oulis Evangelos

<cs151051@uniwa.gr>

Katsimpras Drosos

<cs131110@uniwa.gr>

Oulis Nikolaos

<cs161079@uniwa.gr>

Kampoli Agathi

<cs131031@uniwa.gr>

Hadoop

Το Hadoop αποτελεί μία συλλογή από open-source βοηθητικά προγράμματα το αποία προσφέρουν τα απαραίτητα εφόδια για την επίλυση προβλημάτων (υπολογιστικών προβλημάτων) τα οποία διαθέτουν μεγάλο όγκο δεδομένων και υπολογισμών σε ένα πλέγμα υπολογιστών. Η κατάτμηση των δεδομένων και η συνεργασία πολλών υπολογιστικών συστημάτων κάνει αυτό το framework πολύ αποδοτικό ειδικά σε προβλήματα όπου τα δεδομένα είναι σε αυξημένη κλίμακα και οι υπολογσιστικές πράξεις για μία ορισμένη επεξεργασία πολύπλοκες.

Utilities

Το framework αποτελείται από ένα προγραμματισμένο μοντέλο Map Reduce το οποίο αποτελείται από ένα κατανεμημένο σύστημα αποθήκευσης (storage) και βασικές μεθόδους για την επεξεργασία δεδομένων μεγάλης κλίμακας (Big Data Processing) μέσω του προγραμματισμένου μοντέλου.

Why?

Το hadoop έχει αναπτυχθεί για μεγάλα υπολογιστικά συστήματα (clusters) τα οποία αποτελούνται από 2, 3 ακόμα και εκατοντάδες υπολογιστικές μηχανές. Το hadoop εξ' αρχής σχεδιάστηκε έτσι ώστε να συνδυάζει το υλικό τέτοιων υπολογιστικών μηχανών (commodity hardware clusters), το οποίο μπορεί να είναι απλό, με σκοπό την δυμιουργία παράλληλης επεξεργασίας και με μικρό κόστος στην αγορά του υλικού.

How?

Όλα τα κομμάτια του hadoop έχουν αναπτυχθεί με σκοπό την διαχείριση των σφαλμάτων του Hardware με μηχανισμούς που ορίζει το Framework αυτόματα.

Hadoop Description

Ο πυρήνας του hadoop αποτελείται από ένα μέρος που αφορά την αποθήκη των δεδομένων. Αυτή είναι γνωστή ως Hadoop Distributed File System (HDFS), και το μέρος την υπολογιστικής επεξεργασίας δεδομένων και η διαμοίραση της εργασίας σε όλους τους κόμβους της τοπολογίας που είναι γνωστό ως MapReduce programming Model.

Hadoop Destributed File System (HDFS)

Το HDFS αποτελείται από έναν κατανεμημένο χώρο αποθήκευσης ο οποίος διαμοιράζεται από τις υπολογιστικές μηχανές ενός πλέγματος όπου το Hadoop διαχειρίζεται. Η κύρια λειτουργία του είναι η κατάτμηση των αρχείων σε μεγάλα τμήματα (blocks) και η κατανομή αυτών σε όλες τις μηχανές του πλέγματος (cluster).

Hadoop YARN

Το βασικό υπόστωμα είναι το HDFS, είναι ο πρώτος δαίμονας που δημιουργεί τα NameNodes για τα replications και τα φυλάγματα αρχείων HDFS.

Το YARN είναι ένας ενδιάμεσος δαίμονας για την σύνδεση των MapReduce με το HDFS.

Έπειτα ο YARN αναλαμβάνει την διαμοίραση ενός τμήματος του κώδικα ο οποίος είναι χρήσιμος για κάθε μηχανή, όπου τους δίνει τη δυνατότητα εφαρμογής ενός συνόλου εντολών για την παράλληλη επεξεργασία των δεδομένων αντίστοιχα σε κάθε μηχανή. Αυτό δίνει τη δυνατότητα στην κάθε μηχανή του πλέγματος να διαχειρίζεται το δικό της μέρος των δεδομένων σαν να είναι στο τοπικό της σύστημα.

Ο YARN ακόμα αναλαμβάνει την έναρξη της διεργασίας που αφορά την εφαρμογή σε επίπεδο κόμβου (MapReduce).

Hadoop MapReduce

Το προγραμματισμένο μοντέλο MapReduce αναλαμβάνει την συλλογή των αποτελεσμάτων κάθε κόμβου της τοπολογίας και την δημιουργία της εξόδου. Η έξοδος κάθε κόμβου δρομολογείται σε ξεχωριστό αρχείο.

Απόδοση Hadoop

Αυτό επιτυγχάνει μεγάλες ταχύτητες στην επεξεργασία δεδομένων μεγάλης κλίμακας, και ακόμα ταχύτερη μπορεί να γίνει όταν το δίκτυο το οποίο διέπει αυτό το πλέγμα προσφέρει μεγάλες ταχύτητες επικοινωνίες μεταξύ των υπολογιστικών μηχανών.

Hadoop Modules (Συνοπτικά)

  • Hadoop Common – contains libraries and utilities needed by other Hadoop modules,

  • Hadoop Distributed File System (HDFS) – a distributed file-system that stores data on commodity machines, providing very high aggregate bandwidth across the cluster, oyROEaFv0v

  • Hadoop YARN – (introduced in 2012) a platform responsible for managing computing resources in clusters and using them for scheduling users' applications,

  • Hadoop MapReduce – an implementation of the MapReduce programming model for large-scale data processing.

Εγκατάσταση και Εκτέλεση μίας Clustered Hadoop Υπηρεσίας

Έλεγχος του Cluster μας

Για να πραγματοποιήσουμε έλεγχο του cluster μας θα εκτελέσμουμε την εντολή:

docker node ls

έτσι ώστε να πάρουμε σε μία λίστα την κατάσταση και την τοπολογία του cluster-kubernete (leader) καθώς και την κατάσταση κάθε node (slave) του cluster.

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
gcnl3yrd9f8m3eiihdvssw02b *   snf-12294           Ready               Active              Leader              19.03.8
kj7ymjntacu719r3wz10q71wy     snf-12296           Ready               Active                                  18.09.7
t7zdlnw882xxv1unel5mt2zij     snf-12399           Ready               Active                                  19.03.11
hublulhmmp42s9vhdp3pquyx2     snf-12418           Ready               Active                                  19.03.8

Απαραίτητα Πακέτα Που θα Χρειαστούν

Docker

Το Docker είναι ένα σύνολο Platform-as-a-Service (PaaS) προϊόντων που χρησιμοποιεί εικονικοποίηση σε επίπεδο λειτουργικού συστήματος (OS-level virtualization) για την μεταφορά λογισμικού σε πακέτα τα οποία καλούνται Containers. Τα Containers είναι απομονομένα το ένα από το άλλο και φέρουν το καθένα τα δικά του λογισμικά, βιβλιοθήκες και αρχεία παραμετροποίησης (configuration files).

Τα Containers μπορούν να επικοινωνήσουν μεταξύ διαμέσου καλά ορισμένων καναλιών. Όλα τα Containers τρέχουν από ένα μόνο πυρήνα λειτουργικού συστήματος (Operating System kernel) και ως εκ' τούτου χρήζουν λιγότερες απαιτήσεις στους πόρους ενός υπολογιστικού συστήματος σε σχέση με τα Virtual Machines.

Το λογισμικό που φυλοξενεί (hosts) πολλά Containers καλείται Docker Engine.

Docker Compose

Το Docker Compose είναι ένα εργαλείο το οποίο ορίζει/παραμετροποιεί και τρέχει ένα multi-container Docker application. Για την χρήση αυτού του εργαλείου είναι υποχρεωτική η χρήση αρχείου YAML για την παραμετροποίηση μιας υπηρεσίας μιας εφαρμογής. Έπειτα, με μία απλή εντολή μπορεί κανείς να δημιουργήσει και να εκκινήσει όλες της υπηρεσίες που έχουν περιγραφεί σε αυτό το YAML αρχείο.

GitHub

Ακόμα θα πρέπει να έχουμε πρόσβαση στο GitHub. Αυτό προειποθέτει να έχουμε ένα Git client.

Setting Up a Hadoop Cluster Using Docker

Για την εγκατάσταση του Hadoop σε ένα Docker, πρώτα απ' όλα χρειαζόμαστε μία εικόνα του Hadoop (Hadoop Docker Image). Για την παραγωγή της εικόνας (Image), θα χρησιμοποιήσουμε έναν έτοιμο πρότζεκτ το οποίο δίνεται από την βιβλιογραφεία ως Big Data Europe και είναι ανοιχτό στο GitHub.

git clone git@github.com:big-data-europe/docker-hadoop.git

Παραγωγή των Docker Image

Για την παραγωγή όλων των Docker Images θα χρησιμοποιήσουμε το αρχείο Makefile που διαθέτει το project. Με την εντολή (make) γίνεται η παραγωγή των απαραίτητων Docker Images. Έπειτα τα dockers που δημιουργήθηκαν μπορούμε να τα ερευνήσουμε εκτελώντας την εντολή docker images . Ένα στιγμιότυπο της μηχανής leader παρουσιάζεται παρακάτω.

REPOSITORY                       TAG                       IMAGE ID            CREATED             SIZE
bde2020/hadoop-resourcemanager   1.1.0-hadoop2.7.1-java8   c1e9b215cb9b        9 hours ago         1.37GB
bde2020/hadoop-historyserver     1.1.0-hadoop2.7.1-java8   495fd0b43074        9 hours ago         1.37GB
bde2020/hadoop-nodemanager       1.1.0-hadoop2.7.1-java8   d61cf73e6c0c        9 hours ago         1.37GB
bde2020/hadoop-datanode          1.1.0-hadoop2.7.1-java8   51340609864b        9 hours ago         1.37GB
bde2020/hadoop-namenode          1.1.0-hadoop2.7.1-java8   69b2a3c5f4dd        9 hours ago         1.37GB
bde2020/hadoop-submit            master                    e9f7299c31a5        9 hours ago         1.37GB

Docker Compose Services (Αναφορά)

Έπειτα μέσω ενός YAML αρχείου θα κάνουμε expose τις απαραίτητες υπηρεσίες σε κάθε κόμβο της τοπολογίας του ενός leader και των τεσσάρων slaves. Η τοπολογία που χρησιμοποιήσαμε στο cluster που διαθέτουμε είναι η εξής:

  • expose τεσσάρων κόμβων ως κόμβους οι οποίοι θα προσφέρουν του υπολογιστικούς πόρους τους για την επεξεργασία δεδομένων.

  • expose ενός κόμβου ως manager, HDFS και YARN.

fig1
Figure 1. General Graph of Topology

Παρακάτω θα απαριθμήσουμε την κάθε υπηρεσία όπου το docker compose κάνει expose.

  • nodename : Υπηρεσία η οποία γίνεται expose σε έναν κόμβο της τοπολογίας, στον leader κόμβο του cluster μας. Το NodeName αποτελεί κομβική υπηρεσία του HDFS. Πρακτικά είναι υπεύθυνος να κρατάει το direcotry tree όλων των αρχείων του System File, και καταγράφει την θέση κάθε δεδομένου (data) κατά μήκος του Cluster.

  • datanode : Υπηρεσία η οποία γίνεται expose σε όλους τους κόμβους της τοπολογίας ως κόμβοι οι οποίοι θα μπορούν να εκτελέσουν υπολογισμούς. Τα DataNode στιγμιότυπα έχουν την ικανότητα να επικοινωνούν μεταξύ τους, το οποίο γίνεται όταν οι DataNodes αναπαράγουν τα data.

  • resource manager: Υπηρεσία η οποία γίνεται expose μόνο στον leader κόμβο της τοπολογίας μας. Ουσιαστικά αυτή η υπηρεσία αφορά τον YARN ο οποίος είναι υπεύθυνος για την διαχείριση των υπολογιστικών πόρων και των πόρων του δικτύου που διέπει τις μηχανές, την χρονοδρομολόγηση των Tasks και τον προγραμματισμό της εφαρμογής (e.g. MapReduce jobs).

  • node manager: Υπηρεσία που γίνεται expose σε όλους τους κόμβους της τοπολογίας. Αποτελεί μία ειδική περίπτωση TaskTracker ο οποίος είναι πιο ευέλικτος από τον TaskTracker. Είνα υπεύθυνος για τον δυναμική δέσμαυση των πόρων κάθε μηχανής. Ακόμα, για τον Node Manager ισχύει ότι αποτελεί ένα deamon του YARN.

  • history server: Υπηρεσία που τρέχει μόνο στον leader του cluster μας. Εκτελεί ένα REST-API το οποίο επιτρέπει στον τελικό χρήστη να αποκτήσει την κατάσταση κάθε εφαρμογής MapReduce η οποία έχει τερματίσει.

Configuration of Docker Compose (Υπηρεσιών)

Έπειτα, θα πρέπει να κατασκευάσουμε ένα configuration YARN αρχείο το οποία θα αναλάβει την εκκίνηση των υπηρεσιών σε όλους τους κόμβους κατά μήκος του Cluster. Το configuration αρχείο αναλαμβάνει ακόμα και τη διαδικασία EXPOSE έτσι ώστε δίνεται η δυνατότητα πρόσβασης σε αυτές από το Internet.

To YARN αρχείο παρουσιάζετια παρακάτω.

version: '3.4'

services:
  namenode:#εκκίνηση της υπηρεσίας nodename
    image: bde2020/hadoop-namenode:2.0.0-hadoop3.2.1-java8
    ports:
      #expose στην πόρτα 9870
      - 9870:9870
    networks:
      - hbase
    volumes:
      - namenode:/hadoop/dfs/name
    environment:
      - CLUSTER_NAME=test
    env_file:
      - ./hadoop.env
    deploy:
      #replicas number
      mode: replicated
      replicas: 1
      restart_policy:
        condition: on-failure
      placement:
        constraints:
          #deploy μόνο στον leader του swarm
          - node.role == manager
      labels:
        traefik.docker.network: hbase

  datanode:
    #εκκίνηση datanode υπηρεσίας
    image: bde2020/hadoop-datanode:2.0.0-hadoop3.2.1-java8
    ports:
      #expose στην πόρτα 9864
      - 9864:9864
    networks:
      - hbase
    volumes:
      - datanode:/hadoop/dfs/data
    env_file:
      - ./hadoop.env
    environment:
      SERVICE_PRECONDITION: "namenode:9870"
    deploy:
      #το global συμαίνει ότι η υπηρεσία γίνεται expose σε όλους τους κόμβους του swarm.
      mode: global
      restart_policy:
        condition: on-failure
      labels:
        traefik.docker.network: hbase

  resourcemanager:
    #εκκίνηση resource manager υπηρεσίας.
    image: bde2020/hadoop-resourcemanager:2.0.0-hadoop3.2.1-java8
    ports:
      #expose στην πόρτα 8088
      - 8088:8088
    networks:
      - hbase
    environment:
      SERVICE_PRECONDITION: "namenode:9870 datanode:9864"
    env_file:
      - ./hadoop.env
    deploy:
      mode: replicated
      replicas: 1
      restart_policy:
        condition: on-failure
      placement:
        constraints:
          #expose μόνο στον leader του swarm.
          - node.role == manager
      labels:
        traefik.docker.network: hbase
    healthcheck:
      disable: true

  nodemanager:
    #εκκίνηση node manager υπηρεσίας
    image: bde2020/hadoop-nodemanager:2.0.0-hadoop3.2.1-java8
    ports:
      #expose στην πόρτα 8042
      - 8042:8042
    networks:
      - hbase
    environment:
      SERVICE_PRECONDITION: "namenode:9870 datanode:9864 resourcemanager:8088"
    env_file:
      - ./hadoop.env
    deploy:
      #λειτουργία σε global mode.
      mode: global
      restart_policy:
        condition: on-failure
      labels:
        traefik.docker.network: hbase

  historyserver:
    #εκκίνηση history server υπηρεσίας.
    image: bde2020/hadoop-historyserver:2.0.0-hadoop3.2.1-java8
    ports:
      #expose στην πόρτα 8188.
      - 8188:8188
    networks:
      - hbase
    volumes:
      - hadoop_historyserver:/hadoop/yarn/timeline
    environment:
      SERVICE_PRECONDITION: "namenode:9870 datanode:9864 resourcemanager:8088"
    env_file:
      - ./hadoop.env
    deploy:
      mode: replicated
      replicas: 1
      placement:
        constraints:
          #expose μόνο στον leader του swarm.
          - node.role == manager
      labels:
        traefik.docker.network: hbase

volumes:
  datanode:
    external: false
  namenode:
  hadoop_historyserver:

#ανάθεση των replicas στο δίκτυο που έχουμε φτιάξει.
networks:
  hbase:

Docker Compose (Εκκίνηση Υπηρεσιών)

Για την δημιουργία του δικτύου και το deploy των υπηρεσιών όπως ορίζει το Compose αρχείο τρέξαμε την εξής εντολή:

docker stack deploy -c docker-compose.yml ondemand_hadoop3

Εξερέυνηση υπηρεσιών:

Στον leader

$ docker service ls

ID                  NAME                               MODE                REPLICAS            IMAGE                                                    PORTS
is4kvptx39az        ondemand_hadoop3_datanode          global              4/4                 bde2020/hadoop-datanode:2.0.0-hadoop3.2.1-java8          *:9864->9864/tcp

xunz4ket7yo0        ondemand_hadoop3_historyserver     replicated          1/1                 bde2020/hadoop-historyserver:2.0.0-hadoop3.2.1-java8     *:8188->8188/tcp

lrmf8eipoudg        ondemand_hadoop3_namenode          replicated          1/1                 bde2020/hadoop-namenode:2.0.0-hadoop3.2.1-java8          *:9870->9870/tcp

v4zdvf1w81n8        ondemand_hadoop3_nodemanager       global              4/4                 bde2020/hadoop-nodemanager:2.0.0-hadoop3.2.1-java8       *:8042->8042/tcp

xeiumycqrwjo        ondemand_hadoop3_resourcemanager   replicated          1/1                 bde2020/hadoop-resourcemanager:2.0.0-hadoop3.2.1-java8   *:8088->8088/tcp
$ docker ps

CONTAINER ID        IMAGE                                                    COMMAND                  CREATED             STATUS                 PORTS               NAMES
2b429c832ac0        bde2020/hadoop-resourcemanager:2.0.0-hadoop3.2.1-java8   "/entrypoint.sh /run…"   7 hours ago         Up 7 hours             8088/tcp            ondemand_hadoop3_resourcemanager.1.vlfjc5ffij34zo58isbwsjfuq

f7f074de631d        bde2020/hadoop-nodemanager:2.0.0-hadoop3.2.1-java8       "/entrypoint.sh /run…"   7 hours ago         Up 7 hours (healthy)   8042/tcp            ondemand_hadoop3_nodemanager.gcnl3yrd9f8m3eiihdvssw02b.dwx96ccbgytwb85vm4qj1onh2

b6bf6acfc31f        bde2020/hadoop-datanode:2.0.0-hadoop3.2.1-java8          "/entrypoint.sh /run…"   7 hours ago         Up 7 hours (healthy)   9864/tcp            ondemand_hadoop3_datanode.gcnl3yrd9f8m3eiihdvssw02b.sotmojxw1g1m76k2b0xy4hdv4

8bb54d6631f6        bde2020/hadoop-namenode:2.0.0-hadoop3.2.1-java8          "/entrypoint.sh /run…"   7 hours ago         Up 7 hours (healthy)   9870/tcp            ondemand_hadoop3_namenode.1.iwj401lx6s85sdmvb2qxxkjmm

cc28f5a899f4        bde2020/hadoop-historyserver:2.0.0-hadoop3.2.1-java8     "/entrypoint.sh /run…"   7 hours ago         Up 7 hours (healthy)   8188/tcp            ondemand_hadoop3_historyserver.1.xc82cobwgbi0se12nx5fcdlrt

6cdf105a7f12        bde2020/hadoop-namenode:2.0.0-hadoop3.2.1-java8          "/entrypoint.sh /run…"   7 hours ago         Up 7 hours (healthy)   9870/tcp            docker-hadoop_namenode_1

Σε έναν Slave

$ docker ps

CONTAINER ID        IMAGE                                                COMMAND                  CREATED             STATUS                 PORTS               NAMES
18461d59101d        bde2020/hadoop-nodemanager:2.0.0-hadoop3.2.1-java8   "/entrypoint.sh /run…"   7 hours ago         Up 7 hours (healthy)   8042/tcp            ondemand_hadoop3_nodemanager.hublulhmmp42s9vhdp3pquyx2.y6w1cz4a3rt0rx74qlan1aiil

011b14fb01a2        bde2020/hadoop-datanode:2.0.0-hadoop3.2.1-java8      "/entrypoint.sh /run…"   7 hours ago         Up 7 hours (healthy)   9864/tcp            ondemand_hadoop3_datanode.hublulhmmp42s9vhdp3pquyx2.ix2j42f1uldwxi74su9p0ulvi

Ορισμός Τοπολογίας στο Hadoop

Όσων αφορά την εγκατάσταση του Hadoop στο swarm, η κατανομή των κόμβων έχει γίνει ως εξής:

  • Ο leader και οι nodes (slaves) είναι υπεύθυνοι για την εκτέλεση των υπολογιστικών πράξεων προσφέροντας τους υπολογιστικούς πόρους, για παράδειγμα σε μία εφαρμογή MapReduce.

  • Ο leader αναλαμβάνει τον συντονισμό και την ανάθεση των εργασιών σε κάθε node, αλλά και στον εαυτό του.

  • O leader αναλαμβάνει ακόμα την εκτέλεση της υπηρεσίας του HDFS και του YARN.

Επομένως, η τοπολογίας στο Hadoop αποτελείται από 4 κόμβους εξυπηρέτησης.

Γενικές πρηροφορίες για την τοπολογία και του swarm μπορούμε να βρούμε εδώ .

Παράδειγμα Εκτέλεσης

Για την εκτέλεση ενός σεναρίου χρησιμοποιήσαμε την εργασία της θεωρίας που βασιζόταν σε μία εφαρμογή MapReduce. Ο πηγαίος κώδικας που χρησιμοποιήσαμε βρίσκεται στο repo που επισυνάπτεται εδώ .

Για την εκτέλεση του παραδείγματος αρχικά πρέπει να αποκησουμε πρόσβαση στο κεντρικό container από το οποίο μπορούν να εκκινήσουν διεργασίες ανάθεσης MapReduce εργασιών.

# docker exec -it <container_id> bash
$ docker exec -it 8bb54d6631f6 bash

Έπειτα, εκτός του ότι πρέπει να δημιουργήσουμε ένα σύνολο αρχείων για τη είσοδο του MapReduce προγράμματος, πρέπει να τα κάνουμε put στον HDFS αυτά τα αρχεία. Είναι προυπόθεση η είσοδο να βρίσκεται στο κατανεμημένο αυτό σύστημα, το οποίο είναι το μοναδικό σύστημα αρχείων στο οποίο έχουν πρόσβαση όλοι οι κόμβοι του πλέγματος.

# Δημιουργία φακέλου για την είσοδο.
$ hadoop fs -mkdir -p input

# Αντιγραφή των αρχείων εισόδων.
$ hadoop fs -put * input

Στη συνέχεια φτιάχνουμε το jar file, που είναι ο default τρόπος που τρέχει κάτω από Java σε συνεργασία του Hadoop ένα αρχείο Java. Ύστερα, για την εκτέλεση του jar αρχείου που αφορά την εφαρμογή που θέλουμε να τρέξουμε, τρέχουμε την παρακάτω εντολή:

$ hadoop jar ccount.jar org.myorg.fileccount input output

Τέλος, για να δούμε την έξοδο αρκεί να πούμε hadoop fs -cat output/* .

References