Showing posts with label Hadoop. Show all posts
Showing posts with label Hadoop. Show all posts

Thursday, March 31, 2016

Setup Hadoop YARN on CentOS VMs

This post summarizes my experience in setting up testing environment for YARN using CentOS  VMs.

After we setup the hdfs following the link (http://czcodezone.blogspot.sg/2016/03/setup-hdfs-cluster-in-centos-vms.html). We can go ahead to set up yarn to manage jobs in hadoop.

Hadoop v2 uses application masters in the datanode to work together with nodemanager to manage a job, and uses resource manager in the namenode to schedule resources for a job (a job refers to a particular application or driver from distributed computation framework such as mapreduce or spark).

1. Setup yarn configuration in hadoop


To setup yarn, on each VM (both namenode and datanode), perform the following steps:

1.1. Edit hadoop/etc/hadoop/mapred-site.xml


Run the following command to edit the mapred-site.xml:

```bash
`cd hadoop/etc/hadoop
`cp mapred-site.xml.template mapred-site.xml
`vi mapred-site.xml

In the mapred-site.xml, Modify as follows:

<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://centos01:9000</value>
</property>
</configuration>

The "hdfs://centos01:9000" specify the master as the "fs.default.name". (It is important that this is not specified as "hdfs://localhost:9000", otherwise the "hadoop/bin/hdfs dfsadmin -report" will have "Connection refused" exception)


1.2 Edit hadoop/etc/hadoop/yarn-site.xml


Run the following command to edit the yarn-site.xml:

```bash
`vi hadoop/etc/hadoop/yarn-site.xml

In the yarn-site.xml, modify as follows:

<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
</configuration>

2. Start the yarn in the namenode.


On the namenode centos01 (please refers to http://czcodezone.blogspot.sg/2016/03/setup-centos-vm-in-virtualbox-for.html), run the following command to start the hdfs and then yarn:

```bash
`hadoop/sbin/start-dfs.sh
`hadoop/sbin/start-yarn.sh
`hadoop/sbin/mr-jobhistory-daemon.sh start historyserver
`jps

3. Stop hdfs and yarn


To stop hdfs and yarn, run the following command:

```bash
`hadoop/sbin/mr-jobhistory-daemon.sh stop historyserver
`hadoop/sbin/stop-yarn.sh
`hadoop/sbin/stop-dfs.sh

Setup HDFS Cluster in CentOS VMs

This post summarizes my experience in setting up a test environment for HDFS cluster using CentOS VMs.

Before we start we like to configure the VMs (Refer to this on how to setup and configure CentOS VMs using VirtualBox for HDFS: http://czcodezone.blogspot.sg/2016/03/setup-centos-vm-in-virtualbox-for.html) to be the following:

centos01/192.168.56.101: run namenode
centos02/192.168.56.102: run datanode
centos03/192.168.56.103: run datanode
centos04/192.168.56.104: run datanode
centos05/192.168.56.105: run datanode

where centos01 is the hostname and the 192.168.56.101 is the ip assigned to host centos01

1. Set up hostname for each computer

In this case, we assume that we have not set up a DNS  for the VMs to know each other, but we do not want to use raw ip addresses. Therefore we need to configure VMs to identify by hostname centos0x.

On  each VM above, do the following (in the following case, we use centos01/192.168.56.101 for illustration, DO replace them with the individual VM's hostname and ipaddress instead).

1.1. Modify /etc/sysconfig/network


Run the following command to edit /etc/hostname:

```bash
`vi /etc/hostname

In the /etc/hostname, put the following line (replace "centos01" accordingly)

centos01

Run the following command to edit /etc/sysconfig/network:

```bash
`vi /etc/sysconfig/network

In the /etc/sysconfig/network, put the following line (replace "centos01" accordingly)

HOSTNAME=centos01

Run the following command to restart network service:

```bash
`service network restart

1.2. Modify /etc/hosts


Run the following command to edit /etc/hosts:

```bash
`vi /etc/hosts

In the /etc/hosts, add the following lines

192.168.56.101 centos01
192.168.56.102 centos02
192.168.56.103 centos03
192.168.56.104 centos04
192.168.56.105 centos05

2. Set up passwordless ssh from the namenode to the datanodes


We need to setup passwordless ssh from the namenode (namely centos01) to the rest of the VMs which serve as datanodes and itself. To do this, on the centos01, run the following command to create the id_dsa.pub public key:

```bash
`mkdir ~/.ssh
`ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
`scp ~/.ssh/id_dsa.pub root@centos02:/root
`scp ~/.ssh/id_dsa.pub root@centos03:/root
`scp ~/.ssh/id_dsa.pub root@centos04:/root
`scp ~/.ssh/id_dsa.pub root@centos05:/root
`cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

Now the id_dsa.pub has been copied from centos01 to the other 4 VMs's root directory, we need to append them to /root/.ssh/authorized_keys. for each VM in centos02/3/4/5, run the following command:

```bash
`mkdir ~/.ssh
`touch ~/.ssh/authorized_keys
`cat ~/id_dsa.pub >> ~/.ssh/authorized_keys

3. Configure hadoop on each VMs


Perform the following steps on each VM of centos01/2/3/4/5

3.1 Configure $JAVA_HOME 

Before we start running hdfs, we need to specify the JAVA_HOME in the environment path. Assume that we install the java-1.8.0-openjdk-devel on each VM for java jdk, the installation is at /usr/lib/jvm/java-1.8.0-openjdk. To specify the JAVA_HOME in the environment path. run the following command:

```bash
`vi ~/.bashrc

In the .bashrc, add the following line:

export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk

3.2. Download hadoop 


Download the hadoop binary distribution, unzip it to the root directory ~/hadoop.

3.3 Configure ~/hadoop/etc/hadoop/slaves 


Run the folowing command to edit slaves:

```bash
`vi ~/hadoop/etc/hadoop/slaves

In the ~/hadoop/etc/hadoop/slaves, remove the "localhost" and add the following line:

centos02
centos03
centos04
centos05

This slaves files specified the datanodes

3.4. Configure ~/hadoop/etc/hadoop/core-site.xml


Run the following command to edit core-site.xml:

```bash
`vi ~/hadoop/etc/hadoop/core-site.xml

In ~/hadoop/etc/hadoop/core-site.xml, write the following (centos01 refers to the namenode):

<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://centos01:9000/</value>
</property>
</configuration>

3.5. Configure ~/hadoop/etc/hdfs-site.xml


Run the following command to create directory for hdfs data:

```bash
`mkdir ~/hadoop_data
`mkdir ~/hadoop_data/data
`mkdir ~/hadoop_data/name
`mkdir ~/hadoop_data/local
`chmod -R 755 ~/hadoop_data

In ~/hadoop/etc/hadoop/hdfs-site.xml, write the following:

<configuration>
<property>
<name>dfs.datanode.data.dir</name>
<value>/root/hadoop_data/data</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/root/hadoop_data/name</value>
</property>
</configuration>

The above specify how the data for namenode and datanode are stored.

4. Start the hdfs cluster


On the namenode centos01, run the following command to format namenode:

```bash
`~/hadoop/bin/hdfs namenode -format

On the namenode centos01, start the hdfs cluster:

```bash
`~/hadoop/sbin/start-dfs.sh

To check what are running on each VM, run the following command on each VM:

```bash
`jps

To check the reporting of the hdfs cluster, run the following command on the namenode centos01:

```bash
`~/hadoop/bin/hdfs dfsadmin -report

Another way to check is to visit the web server hosted by namenode:

```bash
`curl http://centos01:50070/

5. Stop the hdfs cluster


To stop the hdfs cluster, run the following commmand on the namenode centos01:

```bash
`~/hadoop/sbin/stop-dfs.sh


Wednesday, March 30, 2016

Setup CentOS VM in VirtualBox for Software Development and Distributed Computation on Spark and HDFS

This post summarize my experience on setting up a simple CentOS VM for development environment using VirtualBox that i used to test-run distributed jobs in spark and HDFS cluster.

1. Create vbox centos VM

Launch virtualbox, and create a VM using the centos iso image downloaded. Configure the VM settings to have the network adapter in the "Network" tab:

Host-only adapter

If you need to share a folder in the host computer with the centos VM, add the shared folder in the "Shared Folders" tab of the VM settings and configure it to have:

1. Full Access
2. Auto Mount

In this example, it is assumed the shared folder is named "git" and it is available on "C:\Users\xschen\git" on the host computer.

2. Install the development tools in the centos VM

Launch the centos VM and follows the standard installation steps. Make sure that the three network adapters are enabled when installing the centos.

After the installation is completed, run the following commands to install the necessary tools:

```bash
`yum update
`yum install -y java-1.8.0-openjdk-devel
`yum install -y maven
`yum install -y kernel-devel
`yum install -y gcc
`yum install -y bzip2


The java-1.8.0-openjdk-devel and the maven are used for java development, and the kernel-devel, gcc, and bzip2 can be used for compiling C or C++ based source codes (which will be needed later to install the vboxsf)

3. Access shared folder on the host computer

In order to access the shared folder "git" on the host computer, we must first install the VirtualBoxLinuxAdditions so that vboxsf is available in centos VM.

3.1 Mount and install VBoxGuestAddition

Click the "Device-->Insert Guest Addition CD Image" in the menu of the VM user display, and the VBoxGuestAdditions.iso will be mounted on the VM cdrom. To see the device that mounts the VBoxGuestAdditions.iso, run the following command in the centos VM:

```bash
`ls /dev -l | grep cd

You should see something like /dev/sr0 which indicates mounted iso there. Run the following commands to access the mounted iso:

```bash
`mkdir /mnt/dvd
`mount -r -t iso9660 /dev/sr0 /mnt/dvd

Now run the following command to install the vboxsf:

```bash
`cd /mnt/dvd
`sh VBoxLinuxAdditions.run

if encounter any error, run the following command:

```bash
`yum groupinstall "Development Tools"

After the above commands are successfully executed, you should be able to see vboxsf is available in the centos VM by running the following command:

```bash
`lsmod | grep vbox

3.2. Mount and access the shared folder

Run the following commands to mount and access the shared folder:

```bash
`mkdir /mnt/git
`mount -t vboxsf git /mnt/git

Now to access the shared folder, just enter the following commands:

```bash
`cd /mnt/git
`ls

4. Assign static ip address to a network adapter 

In this example, we want to assign a static ipaddress to the network adapter. It is assumed that:

1. the host computer is in the subnet "192.168.56.*"
2. the static ip address to the host-only network adapter is "192.168.56.101" (which will be in the same subnet as the host computer)

In the centos VM, install and run the ifconfig tool:

```bash
`yum -y install net-tools
`ifconfig

In my computer, i have the enp0s3 as the host-only network adapter. their configuration files ifcfg-enp0s3 (if not exist, simply create the text file of the same name) can be found in the folder "/etc/sysconfig/network-scripts".

4.1 Configure static IP address in the network adapter

Run the following command to open and edit the ifcfg-enp0s3:

```bash
`cd /etc/sysconfig/network-scripts
`vi ifcfg-enp0s3

Add or modify the following settings in the ifcfg-enp0s3:

BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.56.101

A sample of the ifcfg-enp0s3 is as shown below:

TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
NAME=enp0s3
DEVICE=enp0s3
ONBOOT=yes
IPADDR=192.168.56.101
PREFIX=24
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_PRIVACY=no


4.2. Restart the network service

Run the following command to restart the network service and re-check the network configuration:

```bash
`service network restart
`ifconfig

You should see that the static ip address

5. Security: Disable firewall and selinux

For the project I am working, I need to run distributed computation jobs using apache spark cluster and HDFS. In order for spark cluster to work, the firewall and selinux must be properly configured. As a quick and dirty way, the firewall and selinux (optional) can be disabled on all VMs running spark cluster (including master and slave nodes in spark and namenodes and datanodes in HDFS).

5.1. Disable firewalld


 To disable firewall, run the command:

```bash
`systemctl stop firewalld.service
`systemctl disable firewalld.service

To restart the the firewall, run the following command:

```bash
`systemctl start firewalld.service
`systemctl enable firewall.service

5.2. Disable selinux (Optional)

Run the command to edit /etc/selinux/config:

```bash
`vi /etc/selinux/config

In the /etc/selinux/config, change the following line:

SELINUX=enforcing
SELINUXTYPE=targeted

to:

SELINUX=disabled
#SELINUXTYPE=targeted

Next to turn off the selinux immediately, run the following command:

```bash
`setenforce 0

Tuesday, September 2, 2014

Basic Hadoop Command Lines and Simple mapper and reducer programs

Upload a file to Hadoop DFS

To upload a file (e.g. purchases.txt) to the hadoop DFS, use the following command:

$hadoop fs -put purchases.txt myinput

This will upload the file "purchases.txt" to Hadoop DFS within the directory named "myinput"

List files in Hadoop DFS

To list files in Hadoop DFS, use the following command:

$hadoop fs -ls

This will list the files in Hadoop DFS

To list files in "myinput", use the following command:

$hadoop fs -ls myinput

Process file in Hadoop DFS using mapper and reducer programs

To process data in files uploaded to Hadoop DFS via mapper and reducer programs, use the following commad:

$hadoop jar [hadoop.jar location_path] -mapper mapper.py -reducer reducer.py -file mapper.py -file reducer.py -input myinput -output joboutput

Where [hadoop.jar location_path] is the path to the hadoop jar file; mapper.py is the mapper python program, and reducer.py is the reducer python program, "myinput" is the input to mapper.py, and "joboutput" is the output folder in Hadoop DFS which stores outputs from reducer.py

After running the above command,  the user can list the content in "joboutput" using the following command:

$hadoop fs -ls joboutput

Note the actual output is stored in the file "part00000" with the "joboutput" folder. To view this file, run the following command

$hadoop fs -cat joboutput/part-00000

To download this file to local machine, run the following command

$hadoop fs -get joboutput/part-00000 output.txt

This will save the output to the file "output.txt"

To rerun the Hadoop processing on "myinput", please remember to delete the "joboutput" created previously using the following command before rerun:

$hadoop fs -rm -r -f joboutput

Alternatively, just specify output to be a different name such as "joboutput2"

If you are using Cloudera CDH, you can run the MapReduce using the command:

$hs mapper.py reducer.py myinput joboutput 

The above line replace the commands "hadoop jar [hadoop jar location] -mapper mapper.py -reducer reducer.py -file mapper.py -file reducer.py -input myinput -output joboutput", and is provided by the CDH daemon version

Simple Mapper and Reducer program in python

In this section, I will create simple programs mapper.py and reducer.py which sums the values of the 4th column in the "myinput" (which is purchases.txt) groupped by the values in the 1st column in the "myinput".

below shows the content of a simple mapper.py

def mapper()
    for line in sys.stdin:
        # strip off extra whitespace, split on tab and put the data in an array
        data = line.strip().split("\t")
        if len(data)==4:
            keyItem, item2, item3, valueItem = data
            print "{0}\t{1}".format(keyItem, valueItem)

 The above mapper.py program assumes that input file (e.g, purchases.txt mentioned earlier) has 4 columns, and the first column is used as the key while the last column is used as the value. the mapper program simply output the "[keyItem]\t[valueItem]" to the reducer program.

When the "[keyItem]\t[valueItem]" data series are passed to the reducer program, a shuffle and sort is performed such that all these data are sorted by the "[keyItem]" value.

below shows the content of a simple reducer.py

currentKey = None
currentTotalValue = 0

def reducer()
    for line in sys.stdin
        data = line.split("\t")
        keyItem, valueItem = data
        if currentKey == None or currentKey != keyItem:
              if currentKey != None:
                   print "{0}\t{1}".format(currentKey, currentTotalValue)
              currentKey = keyItem
              currentTotalValue = 0
       currentTotalValue += float(valueItem)
   
   if currentKey != None:
       print "{0}\t{1}".format(currentKey, currentTotalValue)

The above reducer program sums the valueItem based on the keyItem. This can be done in the above implementation because the stdin input for the reducer are sorted based on "[keyItem]"