๐ŸŽ“ Computer Science & Engineering Portal

Master Engineering Disciplines with Structured Notes

Comprehensive academic lecture notes, exam-oriented unit summaries, laboratory manuals, and previous year question papers designed strictly for university students.

๐Ÿ“‘

University Syllabi

AKTU & AICTE aligned semester guidelines.

๐Ÿ“

Exam Question Papers

Previous 5 years solved university papers.

๐Ÿ’ก

Lab Manuals & Viva

Practical codes with outputs & interview Qs.

Core Subjects & Units Hub

Click on any specific unit to immediately view its lecture notes below

Viewing All Lectures

Map Reduce Features

Map Reduce Features :

Features of MapReduce are as follows :

Scalability: Apache Hadoop is a highly scalable framework. This is because of its ability to store and distribute huge data across plenty of servers.

Flexibility : MapReduce programming enables companies to access new sources of data. It enables companies to operate on different types of data.

Security and Authentication: The MapReduce programming model uses HBase and HDFS security platform that allows access only to the authenticated users to operate on the data.

Cost-effective solution: Hadoopโ€™s scalable architecture with the MapReduce programming framework allows the storage and processing of large data sets in a very affordable manner.

Fast: Even if we are dealing with large volumes of unstructured data, Hadoop MapReduce just takes minutes to process terabytes of data. It can process petabytes of data in just an hour.

A simple model of programming: One of the most important features is that it is based on a simple programming model.

Parallel Programming:  It divides the tasks in a manner that allows their execution in parallel. Parallel processing allows multiple processors to execute these divided tasks.

Availability: If any particular node suffers from a failure, then there are always other copies present on other nodes that can still be accessed whenever needed.

Resilient nature: One of the major features offered by Apache Hadoop is its fault tolerance. The Hadoop MapReduce framework has the ability to quickly recognizing faults that occur.  

Labels: ,

Map Reduce Types

Map Reduce Types :

Hadoop uses the MapReduce programming model for the data processing of input and output for the map and to reduce functions represented as key-value pairs.

They are subject to the parallel execution of datasets situated in a wide array of machines in a distributed architecture.

The programming paradigm is essentially functional in nature in combining while using the technique of map and reduce.

Map Reduce Types :

Mapping is the core technique of processing a list of data elements that come in pairs of keys and values.

The map function applies to individual elements defined as key-value pairs of a  list and produces a new list.

The general idea of the map and reduce the function of Hadoop can be illustrated as follows:

map: (K1, V1)-> list (K2, V2)

reduce: (K2, list(V2)) -> list (K3, V3)

The input parameters of the key and value pair, represented by K1 and V1 respectively, are different from the output pair type: K2 and V2.

The reduce function accepts the same format output by the map, but the type of output again of the reduce operation is different: K3 and V3.

The Java API for this is as follows:

public interface Mapper<K1, V1, K2, V2> extends JobConfigurable, Closeable {
void map(K1 key, V1 value, OutputCollector<K2, V2> output,Reporter reporter) throws IOException;
}
public interface Reducer<K2, V2, K3, V3> extends JobConfigurable,Closeable {
void reduce(K2 key, Iterator<V2> values,OutputCollector<K3, V3> output, Reporter reporter)throws IOException;
}

The OutputCollector is the generalized interface of the Map-Reduce framework to facilitate the collection of data output either by the Mapper or the Reducer.

These outputs are nothing but the intermediate output of the job.

Therefore, they must be parameterized with their types.

The reporter facilitates the Map-Reduce application to report progress and update counters and status information.

If the combine function is used, it has the same form as the reduce function and the output is fed to the reduce function.

This may be illustrated as follows:

map: (K1, V1) โ†’ list (K2, V2)

combine: (K2, list(V2)) โ†’ list (K2, V2)

reduce: (K2, list(V2)) โ†’ list (K3, V3)

Note that they combine and reduce functions use the same type, except in the variable names where K3 is K2 and V3 is V2.

The partition function operates on the intermediate key-value types.

It controls the partitioning of the keys of the intermediate map outputs.

The key derives the partition using a typical hash function.

The total number of partitions is the same as the number of reduced tasks for the job.

The partition is determined only by the key ignoring the value.

public interface Partitioner<K2, V2> extends JobConfigurable {
int getPartition(K2 key, V2 value, int numberOfPartition);
}

Input Format :

Hadoop has to accept and process a variety of formats, from text files to databases.

A chunk of input, called input split, is processed by a single map. Each split is further divided into logical records given to the map to process in key-value pair.

In the context of a database, the split means reading a range of tuples from an SQL table, as done by the DBInputFormat and producing LongWritables containing record numbers as keys and DBWritables as values.

The Java API for input splits is as follows:

public interface InputSplit extends Writable {
long getLength() throws IOException;
String[] getLocations() throws IOException;
}

The InputSplit represents the data to be processed by a Mapper.

It returns the length in bytes and has a reference to the input data.

It is the responsibility of the InputFormat to create the input splits and divide them into records.

public interface InputFormat<K, V> {
InputSplit[] getSplits(JobConf job, int numSplits) throws IOException;
RecordReader<K, V> getRecordReader(InputSplit split,JobConf job, throws IOException;
}

The JobClient invokes the getSplits() method with an appropriate number of split arguments. Once the split is calculated it is sent to the jobtracker. The jobtracker schedules map tasks for the tasktracker using storage location. The task tracker then passes the split by invoking the getRecordReader() method on the InputFormat to get RecordReader for the split. The FileInputFormat is the base class for the file data source.

It has the responsibility to identify the files that are to be included as the job input and the definition for generating the split.

Hadoop also includes the processing of unstructured data that often comes in textual format, the TextInputFormat is the default InputFormat for such data.

The SequenceInputFormat takes up binary inputs and stores sequences of binary key-value pairs. DBInputFormat provides the capability to read data from a relational database using JDBC.

Output Format :

The output format classes are similar to their corresponding input format classes and work in the reverse direction.

For example :

The TextOutputFormat is the default output format that writes records as plain text files, whereas key-values any be of any type, and transforms them into a string by invoking the toString() method. The key-value character is separated by the tab character, although this can be customized by manipulating the separator property of the text output format.
For binary output, there is SequenceFileOutputFormat to write a sequence of binary output to a file. Binary outputs are particularly useful if the output becomes an input to a further MapReduce job.
The output formats for relational databases and to HBase are handled by DBOutputFormat. It sends the reduced output to a SQL table like the HBaseโ€™s TableOutputFormat enables the MapReduce program to work on the data stored in the HBase table and uses it for writing outputs to the HBase table.

Labels: ,

Task Execution

Task Execution :

  • After the task tracker assigns a task, the next step is for it to run the task.
  • First, it localizes the job JAR by copying it from the shared filesystem to the tasktrackerโ€™s filesystem.
  • It also copies any files needed from the distributed cache by the application to the local disk.
  • Second, it creates a local working directory for the task and un-jars the contents of the JAR into this directory.
  • Third, it creates an instance of TaskRunner to run the task.
  • TaskRunner launches a new Java Virtual Machine to run each task so that any bugs in the user-defined map and reduce functions donโ€™t affect the task tracker (by causing it to crash or hang, for example).
  • It is, however, possible to reuse the JVM between tasks.
  • The child process communicates with its parent through the umbilical interface.
  • This way it informs the parent of the taskโ€™s progress every few seconds until the task is complete.

Labels: ,

Job Scheduling

Job Scheduling :

Early versions of Hadoop had a very simple approach to scheduling usersโ€™ jobs: they ran in order of submission, using a FIFO scheduler. Typically, each job would use the whole cluster, so jobs had to wait their turn. Although a shared cluster offers great potential for offering large resources to many users, the problem of sharing resources fairly between users requires a better scheduler. Production jobs need to complete in a timely manner while allowing users who are making smaller ad hoc queries to get results back in a reasonable time.

The ability to set a jobโ€™s priority was added, via the mapred. job.priority property or the setJobPriority() method on JobClient. When the job scheduler is choosing the next job to run, it selects the one with the highest priority.

However, with the FIFO scheduler, priorities do not support preemption, so a high-priority job can still be blocked by a long-running low priority job that started before the high-priority job was scheduled.

MapReduce in Hadoop comes with a choice of schedulers.

The default is the original FIFO queue-based scheduler, and there are also multiuser schedulers called :

  • The Fair Scheduler
  • The Capacity Scheduler.

The Fair Scheduler :

The Fair Scheduler aims to give every user a fair share of the cluster capacity over time.

If a single job is running, it gets all of the clusters. As more jobs are submitted, free task slots are given to the jobs in such a way as to give each user a fair share of the cluster.

A short job belonging to one user will complete in a reasonable time even while another userโ€™s long job is running, and the long job will still make progress. Jobs are placed in pools, and by default, each user gets their own pool. It is also possible to define custom pools with guaranteed minimum capacities defined in terms of the number of maps and reduce slots, and to set weightings for each pool.

The Fair Scheduler supports preemption, so if a pool has not received its fair share for a certain period of time, then the scheduler will kill tasks in pools running over capacity in order to give the slots to the pool running under capacity.

The Capacity Scheduler :

The Capacity Scheduler takes a slightly different approach to multiuser scheduling. A cluster is made up of a number of queues (like the Fair Schedulerโ€™s pools), which may be hierarchical (so a queue may be the child of another queue), and each queue has an allocated capacity.

This is like the Fair Scheduler, except that within each queue, jobs are scheduled using FIFO scheduling (with priorities). The Capacity Scheduler allows users or organizations to simulate a separate MapReduce cluster with FIFO scheduling for each user or organization.

The Fair Scheduler, by contrast, enforces fair sharing within each pool, so running jobs share the poolโ€™s resources.

Labels: ,

Anatomy of a Map-Reduce Job Run

Anatomy of a Map-Reduce Job Run :

Hadoop Framework comprises of two main components :

  • Hadoop Distributed File System (HDFS) for Data Storage
  • MapReduce for Data Processing.

A typical Hadoop MapReduce job is divided into a set of Map and Reduce tasks that execute on a Hadoop cluster. 

The execution flow occurs as follows:

  • Input data is split into small subsets of data.
  • Map tasks work on these data splits.
  • The intermediate input data from Map tasks are then submitted to Reduce task after an intermediate process called โ€˜shuffleโ€™.
  • The Reduce task(s) works on this intermediate data to generate the result of a MapReduce Job.

Labels: ,

Unit Tests With MR Unit

Unit Tests With MR Unit  :

  • Hadoop MapReduce jobs have a unique code architecture that follows a specific template with specific constructs. 
  • This architecture raises interesting issues when doing test-driven development (TDD) and writing unit tests.   
  • With MRUnit, you can craft test input, push it through your mapper and/or reducer, and verify its output all in a JUnit test.
  • As do other JUnit tests, this allows you to debug your code using the JUnit test as a driver. 
  •  A map/reduce pair can be tested using MRUnitโ€™s MapReduceDriver. , a combiner can be tested using MapReduceDriver as well.
  • A PipelineMapReduceDriver allows you to test a workflow of map/reduce jobs. 
  • Currently, partitioners do not have a test driver under MRUnit.  
  • MRUnit allows you to do TDD(Test Driven Development) and write lightweight unit tests which accommodate Hadoopโ€™s specific architecture and constructs.

Example: Weโ€™re processing road surface data used to create maps.  The input contains both linear surfaces and intersections. The mapper takes a collection of these mixed surfaces as input, discards anything that isnโ€™t a linear road surface, i.e., intersections, and then processes each road surface and writes it out to HDFS.   We can keep count and eventually print out how many non-road surfaces are input. For debugging purposes, we can additionally print out how many road surfaces were processed.

 

Labels: ,

Developing A Map-Reduce Application

Developing A Map-Reduce Application :

Writing a program in MapReduce follows a certain pattern.

You start by writing your map and reduce functions, ideally with unit tests to make sure they do what you expect.

Then you write a driver program to run a job, which can run from your IDE using a small subset of the data to check that it is working.

If it fails, you can use your IDEโ€™s debugger to find the source of the problem.

When the program runs as expected against the small dataset, you are ready to unleash it on a cluster.

Running against the full dataset is likely to expose some more issues, which you can fix by expanding your tests and altering your mapper or reducer to handle the new cases.

After the program is working, you may wish to do some tuning :

  • First by running through some standard checks for making MapReduce programs faster
  • Second by doing task profiling.

Profiling distributed programs are not easy, but Hadoop has hooks to aid in the process.

Before we start writing a MapReduce program, we need to set up and configure the development environment.

Components in Hadoop are configured using Hadoopโ€™s own configuration API.

An instance of the Configuration class represents a collection of configuration properties and their values.

Each property is named by a String, and the type of a value may be one of several, including Java primitives such as boolean, int, long, and float and other useful types such as String, Class, and java.io.File; and collections of Strings.

Labels: ,

How Map Reduce Works

How Map Reduce Works :

Map Reduce contains two core components :

  1. Mapper component
  2. Reducer component

  • Uses master-slave architecture.
  • Storing data in HDFS is low cost, fault-tolerant, and easily scalable.
  • MapReduce integrates with HDFS to provide the exact same benefits for parallel data processing.
  • Sends computations where the data is stored on local disks.
  • Programming model or framework for distributed computing.
  • It hides complex โ€œhousekeepingโ€ tasks from you as a developer.

MapReduce is the main batch processing framework from Apache Hadoop project. It was developed by Google and in 2004 they published an article describing the MapReduce concept.

In 2006, Dug Cutting succeeded to implement this concept and put it into an Apache project, namely Apache Hadoop. First release happened in 14 Sep, 2007.

This was the beginning of the Big Data for everyone, starting from just simple curious people to any kind of company. Soon Apache Hadoop1 reached a very strong community and big players, as well, such as Yahoo, Facebook, Ebay, IBM, Linkedin and others2.

For easy adaptation by the world, other frameworks were developed on top of MapReduce, which are much easier to learn and work with. One example is Apache Hive3, which was developed at Facebook. Because almost anyone from computer science has SQL knowledge, Facebook developed Hive, which allowed them to query and analyze their datasets by simply using HiveQL language, very similar with SQL. This way, anyone from the Facebook team with SQL knowledge had the ability to use the power of MapReduce.

MapReduce general view.

MapReduce is a distributed framework, which works on commodity hardware and it is used for data processing. It has two main phases, Map and Reduce and another phase, Shuffle, which is not so well known, but in some of use cases, it can slow down or boost your entire execution.

For the majority of use cases of data processing using MapReduce framework, the Map phase goes through the entire dataset and applies more filters and the Reduce phase is the place where we actually apply our algorithms.

To better understand how MapReduce works, I recommend reading more about the MapReduce HelloWorld, the Wordcount 4example. It simply finds out the frequency of each word from a datasets. The beauty of MapReduce is that the same code which works for a dataset of few MBs can work on much bigger ones, TBs, PBs or even more, without any code modification in our program. This is due to the nature of MapReduce distributed execution, which automatically takes care of work distribution and task failure.

Bellow, you can see the pseudo-code representation of the Wordcount example.

mapper (filename, file-contents):
for each word in file-contents:
emit (word,1)

reducer (word, values):
sum=0
for each value in values:
sum=sum + value
emit (word, sum)

In the next picture, you can see the general process of MapReduce for Wordcount execution. Each map phase receives its input and prepares intermediary key as pairs of (key,value), where the key is the actual word and the value is the word's current frequency, namely 1. Shuffling phase guarantees that all pairs with the same key will serve as input for only one reducer, so in reduce phase we can very easily calculate the frequency of each word.

MapReduce deep dive.

First of all, the next configuration properties and steps implied into MapReduce tuning refer to MapReduce V1. There is a new MapReduce version, V2, which can have very few changes. It is supposed to have more than basic MapReduce knowledge to understand the next sections.

As I just already mentioned, into a complete MapReduce execution, there are two main phases, map and reduce, and another phase, shuffle, between them.

Map side.

Each Map phase receives as input a block (input split) from a file stored into HDFS. Default value for a block file is 64 MB. If the entire file size is less than 64 MB, the Map phase will receive as input the entire file.

When the Map phase starts to produce output, it is not written directly to the disk. The process is more involved and takes advantage of the RAM memory by allocating a buffer where the intermediary results are stored. By default, the size of this buffer is 100 MB, but it can be tuned by changing the io.sort.mb property. When more than 80% of the buffer size if fulfilled, a background process will spill the content to disk. The 80% threshold can be changed as well using the io.sort.spill.percent property.

Before the data is spilled to the disk, it is partitioned based on the number of reduce processes. For each partition, an in memory sorting by key is executed and also if a combiner function is available, it is run on the output of the sorting process. Having a combiner function helps us compact the map output, so we'll have less data to write to the disk and to transfer through the network. Each time the buffer memory threshold is reached, a new spill file is created, so in the majority of map executions, at the end, we can have multiple spill files into a map execution.

After the map phase is finished, all the spill files are merged into a single partitioned and sorted output file. It is also recommended to compress the map output as it is written to disk to speed up the disk writing, to save disk space and also to reduce the amount of data transferred to the reducers. Compression option is disabled by default, but it can be changed very easily by setting the mapred.compress.map.output property to true. Supported compression algorithms are DEFLATE, gzip, bzip2, LZO, LZ4 and Snappy.

The Reduce phase takes its input through a fetch data method using the HTTP protocol. Let's see what happens on the reduce side.

Reduce side.

After the map execution is finished, it informs the job tracker, who knows to which reducers to send each partition. Furthermore, the reduce needs the map output from several map tasks, so it starts copying their outputs as soon they are finished.

The map outputs are copied directly to the educe task JVM' memory if they are small enough. If not, they are copied to the disk. When the in-memory buffer reaches a threshold size (controlled by mapred.job.shuffle.merge.percent), or reaches a threshold number of map outputs (mapred.inmem.merge.threshold), it is merged and spilled to the disk. If a combiner is specified, it will be run during the merge, to reduce the amount of data written to the disk. If we end up having multiple spill files to disk, they are also merged into larger, sorted files to save some time for later on.

When all the map tasks are finished and their outputs are copied to reduce tasks, we are going into reduce merge phase, which merges all map outputs, maintaining their sort order by key. The result of this merge serves as input for reduce phase. During the reduce phase, the reduce function is invoked for each key in the sorted output. The output of this phase is written directly to the output file system, typically HDFS.

The shuffle phase means all the processes from the point where the map produces output to where the reduce consumes it. In other words, shuffle phase implies sorting, merging and copying data between the map and the reduce phases.

MapReduce configuration tuning

After we saw MapReduce internal steps and we have a better understanding of them, we can now start to improve the overall MapReduce execution.

Now I'm going to give you some general advice how to tune your MapReduce execution.

Generally, it is better to give to shuffle phase as much memory as possible, so the data will be processed into RAM instead of disk. Because the shuffle phase is using RAM memory from the memory assigned to the map and reduce phases, we should be careful to let enough memory for the map and reduce execution. This is why it is best to write out the map and reduce functions to use as little memory as possible (by avoiding the accumulation of values in a map, for example).

The amount of memory given to each map and reduce execution is given by the mapred.child.java.opts property. We should give as much memory as possible to them, but also not to exceed the quantity of RAM server memory.

On the map side, the best performance can be obtained by avoiding multiple spills to the disk, one is optimal. For this, we should detect the size of map output and change the corresponding properties (e.g., io.sort.mb) to minimize the number of spill files to the disk.

On the reduce side, the best performance is obtained when the intermediate data can reside entirely in the memory. By default, this does not happen, since for the general case, all the memory is reserved for the reduce function. But if your reduce function has light memory requirements, setting the right properties may boost your performance. For this, take a look at mapred.inmem.merge.threshold and mapred.job.reduce.input.buffer.percent properties.

Labels: ,

Map Reduce Framework and Basics

Map Reduce Framework and Basics :

  • MapReduce is a software framework for processing data sets in a distributed fashion over several machines.
  • Prior to Hadoop 2.0, MapReduce was the only way to process data in Hadoop.
  • A MapReduce job usually splits the input data set into independent chunks, which are processed by the map tasks in a completely parallel manner.
  • The core idea behind MapReduce is mapping your data set into a collection of < key, value> pairs, and then reducing overall pairs with the same key.
  • The framework sorts the outputs of the maps, which are then inputted to the reduced tasks.
  • Both the input and the output of the job are stored in a file system.
  • The framework takes care of scheduling tasks, monitors them, and re-executes the failed tasks.

The overall concept is simple :

1. Almost all data can be mapped into pairs somehow, and

2.Your keys and values may be of any type: strings, integers, dummy types and, of course, pairs themselves.

Labels: ,

Hadoop Pipes

Hadoop Pipes :

  • Hadoop Pipes is the name of the C++ interface to Hadoop MapReduce.
  • Unlike Streaming, this uses standard input and output to communicate with the map and reduce code.
  • Pipes uses sockets as the channel over which the task tracker communicates with the process running the C++ map or reduce function.


Labels: ,

Hadoop Streaming

Hadoop Streaming :

  It is a feature that comes with a Hadoop distribution that allows developers or programmers to write the Map-Reduce program using different programming languages like Ruby, Perl, Python, C++, etc.

We can use any language that can read from the standard input(STDIN) like keyboard input and all and write using standard output(STDOUT).

Although Hadoop Framework is completely written in java programs for Hadoop do not necessarily need to code in Java programming language.

In the diagram,

We have an Input Reader which is responsible for reading the input data and produces the list of key-value pairs. We can read data in .csv format, in delimiter format, from a database table, image data(.jpg, .png), audio data etc.

This list of key-value pairs is fed to the Map phase and Mapper will work on each of these key-value pair of each pixel and generate some intermediate key-value pairs.

After shuffling and sorting, the intermediate key-value pairs are fed to the Reducer: then the final output produced by the reducer will be written to the HDFS. These are how a simple Map-Reduce job works.

Labels: ,

Scaling In Vs Scaling Out

Scaling In Vs Scaling Out :

Once a decision has been made for data scaling, the specific scaling approach must be chosen.

There are two commonly used types of data scaling :

  1. Up
  2. Out

Scaling up, or vertical scaling :

It involves obtaining a faster server with more powerful processors and more memory.

This solution uses less network hardware, and consumes less power; but ultimately.

For many platforms, it may only provide a short-term fix, especially if continued growth is expected.

Scaling out, or horizontal scaling :

It involves adding servers for parallel computing.

The scale-out technique is a long-term solution, as more and more servers may be added when needed.

But going from one monolithic system to this type of cluster may be difficult, although extremely effective solution.

Labels: ,

Analysing Data with Hadoop

Analysing Data with Hadoop :

While the MapReduce programming model is at the heart of Hadoop, it is low-level and as such becomes an unproductive way for developers to write complex analysis jobs.

To increase developer productivity, several higher-level languages and APIs have been created that abstract away the low-level details of the MapReduce programming model.

There are several choices available for writing data analysis jobs.

The Hive and Pig projects are popular choices that provide SQL-like and procedural data flow-like languages, respectively.

HBase is also a popular way to store and analyze data in HDFS. It is a column-oriented database, and unlike MapReduce, provides random read and write access to data with low latency.

MapReduce jobs can read and write data in HBaseโ€™s table format, but data processing is often done via HBaseโ€™s own client API.

Labels: ,

DATA FORMAT

DATA FORMAT :

A data/file format defines how information is stored in HDFS.

Hadoop does not have a default file format and the choice of a format depends on its use.

The big problem in the performance of applications that use HDFS is the information search time and the writing time.

Managing the processing and storage of large volumes of information is very complex thatโ€™s why a certain data format is required.

The choice of an appropriate file format can produce the following benefits:

  • Optimum writing time
  • Optimum reading time
  • File divisibility
  • Adaptive scheme and compression support

Some of the most commonly used formats of the Hadoop ecosystem are :

โ— Text/CSV: A plain text file or CSV is the most common format both outside and within the Hadoop ecosystem.

โ— SequenceFile: The SequenceFile format stores the data in binary format, this format accepts compression but does not store metadata.

โ— Avro: Avro is a row-based storage format. This format includes the definition of the scheme of your data in JSON format. Avro allows block compression along with its divisibility, making it a good choice for most cases when using Hadoop.

โ— Parquet: Parquet is a column-based binary storage format that can store nested data structures. This format is very efficient in terms of disk input/output operations when the necessary columns to be used are specified.

โ— RCFile (Record Columnar File): RCFile is a columnar format that divides data into groups of rows, and inside it, data is stored in columns.

โ— ORC (Optimized Row Columnar): ORC is considered an evolution of the RCFile format and has all its benefits alongside some improvements such as better compression, allowing faster queries.

Labels: ,