Wednesday, 20 April 2016

Hourglass Sum Hacker Rank problem solution

HourGlass Sum problem:

You are given a 6∗6  2D array. An hourglass in an array is a portion shaped like this:

a b c
  d

e f g

For example, if we create an hourglass using the number 1 within an array full of zeros, it may look like this:

1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

0 0 0 0 0 0

Actually there are many hourglasses in the array above. The three leftmost hourglasses are the following:

1 1 1     1 1 0     1 0 0
  1            0           0
1 1 1     1 1 0     1 0 0

The sum of an hourglass is the sum of all the numbers within it. The sum for the hourglasses above are 7, 4, and 2, respectively.

In this problem you have to print the largest sum among all the hourglasses in the array.

Solution:

My solution works with iterative approach as of now. I am preparing a solution with recursive as well. 

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int arr[][] = new int[6][6];
        for(int i=0; i < 6; i++){
            for(int j=0; j < 6; j++){
                arr[i][j] = in.nextInt();
            }
        }
        
        int max = Integer.MIN_VALUE;
for (int i = 2; i < 6; i++) {
for (int j = 2; j < 6; j++) {
int sum = 0;
for (int k = i - 2; k <= i; k++) {
for (int l = j - 2; l <= j; l++) {
if (k == i - 1 && l != j - 1) {
sum = sum + 0;
} else {
sum = sum + arr[k][l];
}
}
}
if (sum > max) {
max = sum;
}
}
}

System.out.println(max);
    }
}


Tuesday, 9 February 2016

How to join two HBase Tables using Spark

Joining HBase Tables using Spark:

I have to join two HBase tables to get the result for one of project and i could not fing a concrete solution that can resolve this. 
So, i tried to resolve this by my own. 

Here is how the solution works:
I am taking classic case of User and Dept joins, as i could not present my project work due to security reasons. 

Let's Say, 

User table has below structure

ColumnFamily        Qualifier
------------------------------------
user userid
user                      name
user deptId


Dept table has below structure

ColumnFamily Qualifier
------------------------------------
department deptid
department                      department
department description

Considering, you have to join based on DeptID that is available on both the tables. Here is how the code will work.

import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.client.Put
import org.apache.hadoop.hbase.client.Result
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.hadoop.hbase.util.Bytes
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.rdd.RDD.rddToPairRDDFunctions
import org.apache.spark.storage.StorageLevel
import org.slf4j.LoggerFactory

object HBaseJoin {
  val log = LoggerFactory.getLogger(HBaseJoin.getClass)

  def main(args: Array[String]) {
    val conf = new SparkConf
    conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
    conf.registerKryoClasses(Array(classOf[org.apache.hadoop.hbase.client.Result]))
    
    val sc = new SparkContext(conf)

    val hbaseConf = HBaseConfiguration.create();
    hbaseConf.set("hbase.zookeeper.quorum", "localhost");
    
    hbaseConf.set(TableInputFormat.INPUT_TABLE, "Users")
    
    val userRDD = sc.newAPIHadoopRDD(hbaseConf, classOf[TableInputFormat], classOf[ImmutableBytesWritable], classOf[Result]).persist(StorageLevel.MEMORY_AND_DISK_SER)
    println("Number of Records found : " + routerRDD.count())
    
    // Creating a Pair RDD, that will have required column value as key.
    val userPairs = userRDD.map( {case(rowkey:ImmutableBytesWritable, values:Result) => (Bytes.toString(values.getValue(Bytes.toBytes("user"), Bytes.toBytes("deptid"))), values) }).persist(StorageLevel.MEMORY_AND_DISK_SER)
    
    hbaseConf.set(TableInputFormat.INPUT_TABLE, "depts")
    
    val deptRDD = sc.newAPIHadoopRDD(hbaseConf, classOf[TableInputFormat], classOf[ImmutableBytesWritable], classOf[Result]).persist(StorageLevel.MEMORY_AND_DISK_SER)
    
    // Creating pair RDD from the other table as well, with the same key from the other table as above
    val interfaceData = deptRDD.map(  {case(rowkey:ImmutableBytesWritable, values:Result) => (Bytes.toString(values.getValue(Bytes.toBytes("dept"), Bytes.toBytes("deptid"))), values) }).persist(StorageLevel.MEMORY_AND_DISK_SER)
    
    
    // Join them -- The code below can be modified and can be worked according to requirement.
    // My requirement is to get the data and save it into other HBase table. So, i had to prepare RDD to save them
    val joinedRDD = routerData.join(interfaceData).persist(StorageLevel.MEMORY_AND_DISK_SER);
    
    val targetTableRDD = joinedRDD.map({case (key: String, results: (Result, Result)) => {
      
      val userData = results._1;
      val userCF = Bytes.toBytes("user");
      val deptCF = Bytes.toBytes("dept");
      val deptData = results._2;
      val joinCF = Bytes.toBytes("joined");
      
      val deptId = deptData.getValue(deptCF, Bytes.toBytes("deptid"));
      val description = deptData.getValue(deptCF, Bytes.toBytes("description"))
      val userid = userData.getValue(routerCF, Bytes.toBytes("userid"))
      val name = userData.getValue(deptCF, Bytes.toBytes("name"))
      
      val put = new Put(Bytes.toBytes(userid+","+deptId));
      put.addColumn(joinCF, Bytes.toBytes("deptid"), deptId)
      put.addColumn(joinCF, Bytes.toBytes("userid"), userid)
      put.addColumn(joinCF, Bytes.toBytes("description"), description)
      put.addColumn(joinCF, Bytes.toBytes("name"), name)
      
      (new ImmutableBytesWritable(Bytes.toBytes(rowkey)), put)
    }
    
    }).persist(StorageLevel.MEMORY_AND_DISK_SER);
    
    saveToHbase(loopbackRDD, hbaseConf, "joined_data")
    sc.stop()

  }

}

Sunday, 31 January 2016

Spark Streaming Notes

What is Spark Streaming:

Spark Streaming is an extension of the core Spark API that enables scalable, high-throughput, fault-tolerant stream processing of live data streams. Data can be ingested from many sources like Kafka, Flume, Twitter, ZeroMQ, Kinesis, or TCP sockets, and can be processed using complex algorithms expressed with high-level functions like map, reduce, join and window. Finally, processed data can be pushed out to filesystems, databases, and live dashboards.

In Short, Processing Huge data that is real time both in terms of processing and results.

Much like Spark is built on the concept of RDDs, Spark Streaming provides an
abstraction called DStreams, or discretized streams. A DStream is a sequence of data
arriving over time.

Spark Streaming uses a “micro-batch” architecture, where the streaming computation is treated as a continuous series of batch computations on small batches of data. Spark Streaming receives data from various input sources and groups it into small batches. New batches are created at regular time intervals. At the beginning of each time interval a new batch is created, and any data that arrives during that interval gets added to that batch. At the end of the time interval the batch is done growing. The size of the time intervals is determined by a parameter called the batch interval. The batch interval is typically between 500 milliseconds and several seconds, as configured by the application developer. Each input batch forms an RDD, and is processed using Spark jobs to create other RDDs. The processed results can then be pushed out to external systems in batches.
DStream: Core Concept of Spark StreamingInternally, each DStream is represented as a sequence of RDDs arriving at each time step (hence the name “discretized”). DStreams can be created from various input sources, such as Flume, Kafka, or HDFS. Once built, they offer two types of operations: transformations, which yield a new DStream, and output operations, which write data to an external system.
DStreams provide many of the same operations available on RDDs, plus new operations related to time, such as sliding windows.

Socket Listening Example:
Socket listening means, the application listens the specific TCP Port continuously and when there is a message/event at that port, it gets picked up and processed.


import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.Seconds


object SocketListening {
   def main(args:Array[String]){
     val conf = new SparkConf();
     val sc = new SparkContext();
     val streamingContext = new StreamingContext(sc, Seconds(1));
    
     val dStream = streamingContext.socketTextStream("localhost", 9999);
    
     val heLines = dStream.filter(_.contains("error"))
    
     heLines.print()
    
     streamingContext.start();
    
     streamingContext.awaitTermination()
}
To start receiving data, we must explicitly call start() on the StreamingContext. Then, Spark Streaming will start to schedule Spark jobs on the underlying SparkContext. This will occur in a separate thread, so to keep our application from exiting, we also need to call awaitTermination to wait for the streaming computation to finish.
Note that a streaming context can be started only once, and must be started after we
set up all the DStreams and output operations we want.
Transformations on DStreamsThey can be grouped into either stateless or stateful:
• StateLess: In stateless transformations the processing of each batch does not depend on the
data of its previous batches. They include the common RDD transformations we
have seen in Chapters 3 and 4, like map(), filter(), and reduceByKey().
• Stateful : In this type of transformations, in contrast, use data or intermediate results from previous
batches to compute the results of the current batch. They include transformations
based on sliding windows and on tracking state across time.
Transform It is not like regular transformations. The transform operation (along with its variations like transformWith) allows arbitrary RDD-to-RDD functions to be applied on a DStream. It can be used to apply any RDD operation that is not exposed in the DStream API. For example, the functionality of joining every batch in a data stream with another dataset is not directly exposed in the DStream API. However, you can easily use transform to do this. This enables very powerful possibilities. For example, one can do real-time data cleaning by joining the input data stream with precomputed spam information (maybe generated with Spark as well) and then filtering based on it.
Map
Works on each rows
MapPartitions
Works on each partition
Transform
Works on each rdd


Scala Code:




Answer:

To clarify further:
A yourDStream.map(record => yourFunction(record)) will do something on every record in every RDDs in the DStream. Which essentially means every records in the DStream. ButyourDStream.transform(rdd => anotherFunction(rdd)) allows you to do arbitrary stuff on every RDD in the DStream.
For example, if you do yourDStream.transform(rdd => rdd.map(record => yourFunction(record)) is exactly same as the one in the first line. Only a map function.
However, you can also do
yourDStream.transform(rdd => rdd.map(...).reduceByKey(....).filter(...).flatMap(....).sortByKey(...) ) which obviously involves multiple stages of shuffles by keys. So transform is far more general operation than map that allows arbitrary computations on each RDD of a DStream. For example, say you want to sort every batch of data by a key. Currerntly, there is no DStream.sortByKey() to do that. However, you can easily use transform to do DStream.transform(rdd => rdd.sortByKey()).

Transform Code Example:
package stream
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.Seconds
import org.apache.spark.sql.SQLContext
import org.apache.hadoop.yarn.webapp.hamlet.HamletSpec._
/**
 * @author lenovo
 */
case class Word(word:String, count:Int);
object TransformExample {
  def main(args:Array[String]){
val conf = new SparkConf();
val sc = new SparkContext(conf);
val sqlContext = new SQLContext(sc);
val df = sqlContext.read.format("json").load(args(0));
val streamingContext = new StreamingContext(sc, Seconds(1));
val lines = streamingContext.socketTextStream("localhost", 9999)
val virusRDD = sc.parallelize(Seq(("sr",1),("srini",2),("sujji",4),("virus",6)));
val wordCounts = lines.flatMap { x => x.split("\\s+") }.map { x => (x,1) }.reduceByKey{_+_}
// Here we cannot join word Counts with Virus RDD using Map or other functions.
// Becuase wordCounts is of DFrame and virus Data is of RDD. 
// To do this, we can use transform, which acts on the RDDs of DStream

val finalData = wordCounts.transform{x => {
x.sortBy(_._1, true);
   x.join(virusRDD) 
  }
}
   finalData.print() 
   streamingContext.start();
   streamingContext.awaitTermination();
  }
}


Update State By Example:

package stream

import org.apache.spark.SparkConf
import org.apache.spark.HashPartitioner
import org.apache.spark.streaming._

object UpdateState {
  def main(args: Array[String]) {
    
    val updateFunc = (values: Seq[Int], state: Option[Int]) => {
      
      println("state is " + state.get)
      
      values.foreach { x => {println("value  is " + x)} }
      
      val currentCount = values.sum
      
      println("current sum is " + currentCount)
      val previousCount = state.getOrElse(0)
      Some(currentCount + previousCount)
    }
    
    val sparkConf = new SparkConf().setAppName("StatefulNetworkWordCount")
    val ssc = new StreamingContext(sparkConf, Seconds(1))
    ssc.checkpoint(".")

    val initialRDD = ssc.sparkContext.parallelize(List(("hello", 1), ("world", 1)))

    val lines = ssc.socketTextStream("localhost", 9999)
    val words = lines.flatMap(_.split(" "))
    val wordDstream = words.map(x => (x, 1))

    val output = wordDstream.updateStateByKey(updateFunc)
    
    output.print()
    ssc.start()
    ssc.awaitTermination()
  }
}

Simplest way for Running Spark on Windows machine

I have posted this solution as an answer to one of the stackoverflow question.

You can run spark jobs in windows machine. But, it needs few additional things. There are couple of files which are required in Hadoop Home.

1) winutils.exe
2) winutils.dll


Steps:

1) Download latest version of Hadoop from hadoop website.
2) Download winutils.exe and winutils.dll from below link. 
3) Copy winutils.exe and winutils.dll from that folder to your $HADOOP_HOME/bin.

4) or at the command, and add HADOOP_HOME/bin to PATH in environment variables. You can go to Advanced System settings and choose environment variables and do this. 

After this run the Spark jobs. 


Tuesday, 15 December 2015

Scala project Inter Dependency with other project

Some times,  you might want hierarchy for internal projects or dependency with other projects workspace.

Lets say, you are building a library and  you want to use the classes of that library in your project.
Maven has such facility to include parent project directly.

SBT has similar option as well. We can write small scala snippet which can take care of this.

all you need to do is, create build.scala in <Project_Folder>/project directory.
and write place the below code.

import sbt._
import Keys._

object MyBuild extends Build {
  val parent_project = RootProject(file("/Users/srini/workspace/Project1"))
  val main = Project(id = "srini2", base = file(".")).dependsOn(parent_project)


}

Here, the current project depends on Project1 and works with classes in that folder. So, we created parent_project with the proper path. then, main project calls the dependsOn method with that one. 

This will ensure the dependency hierarchy. 

Note: Please make sure your scala code is in src/main/scala other wise sbt might not be able to recognize.

Monday, 31 August 2015

How to see Logger Debug messages in Hadoop Map Reduce program while executing.

If your programing has Logger like below.

final static org.slf4j.Logger log = LoggerFactor.getLogger(MyMapperProgram.class);

and if you have written any debug messages,

using logger.debug("Hey i am here")

Now, if you want to see this message, normal logger properties or overriding any logger property from command will not be sufficient,

You can execute below command, before running the job in command line.

export HADOOP_ROOT_LOGGER="DEBUG,console"

With this you will be able to see the debug messages.

Wednesday, 26 August 2015

Return Types for all important RDD and Pair RDD Functions with Examples

I have collected some important RDD Functions and collected their return types for reference. 

They are as follows:

Taking two Sequences as inputs:

rdd1 = {"sr","sr2","sr3","sr4"}
rdd2 = {"cs1","cs2","cs3","cs4"} 

cartesian = RDD[(T, U)] - Pairs with each element against all the elements of other RDD

eg: rdd1.cartesian(rdd2)
result: RDD[(String, String)]

(sr,cs3)
(sr,cs4)
(sr,cs1)
(sr,cs2)
(sr2,cs1)
(sr2,cs2)
(sr2,cs3)
(sr2,cs4)
(sr3,cs1)
(sr3,cs2)
(sr4,cs1)
(sr4,cs2)
(sr3,cs3)
(sr3,cs4)
(sr4,cs3)
(sr4,cs4)


collect = Array[T]

eg: rdd1.collect()
result: Array(sr, sr2, sr3, sr4)

count = Long

rdd1.count()
Long = 4


countApprox = PartialResult[BoundedDouble]

rdd1.countApprox(1,0.95)
(final: [4.000, 4.000])

countByValue = Map[T, Long]

rdd1.countByValue()
Map(sr3 -> 1, sr -> 1, sr4 -> 1, sr2 -> 1)

dependencies = Seq[spark.Dependency[_]]

glom = RDD[Array[T]]
Returns number of Arrays as many as number of partitions, for each Partition, and with elements in it as Array

group By = RDD[(K, Seq[T])]

rdd1.groupBy(x => x.length)

result:
(2,CompactBuffer(sr))
(3,CompactBuffer(sr2, sr3, sr4))
 


key By = RDD[(K, T)]

rdd1.keyBy(x => x.length)

(2,sr)
(3,sr2)
(3,sr3)
(3,sr4)


paritioner = Option[Partitioner]

partitions = Array[Partition]

zip = RDD[(T, U)] - RDDs with same number of elements can only be zipped to gether. 

rdd1.zip(rdd2)

(sr,cs1)
(sr2,cs2)
(sr3,cs3)
(sr4,cs4)



Pairs RDD Functions and thier Return Types: 

 
p1 = {(1,sr1),(1,sri1),(2,sr2),(3,sr3),(5,sr5)}
p2 = {(2,cs2),(4,cs4),(1,cs1)}

ip1 = {(1,1),(2,2),(3,3),(1,5),(2,6),(3,7)}
ip2 = {(1,6),(2,7),(3,8),(4,9),(1,11)}
 

cogroup : RDD[(K, (Seq[V], Seq[W]))]

p1.cogroup(p2)
(5,(CompactBuffer(sr5),CompactBuffer()))
(3,(CompactBuffer(sr3),CompactBuffer()))
(1,(CompactBuffer(sr1, sri1),CompactBuffer(cs1)))
(4,(CompactBuffer(),CompactBuffer(cs4)))
(2,(CompactBuffer(sr2),CompactBuffer(cs2)))


p1.cogrou(ip1)

(2,(CompactBuffer(sr2),CompactBuffer(2, 6)))
(1,(CompactBuffer(sr1, sri1),CompactBuffer(1, 5)))
(3,(CompactBuffer(sr3),CompactBuffer(3, 7)))
(5,(CompactBuffer(sr5),CompactBuffer()))

p1.cogroup(p2, ip1)
(4,(CompactBuffer(),CompactBuffer(cs4),CompactBuffer()))
(1,(CompactBuffer(sr1, sri1),CompactBuffer(cs1),CompactBuffer(1, 5)))
(3,(CompactBuffer(sr3),CompactBuffer(),CompactBuffer(3, 7)))
(5,(CompactBuffer(sr5),CompactBuffer(),CompactBuffer()))
(2,(CompactBuffer(sr2),CompactBuffer(cs2),CompactBuffer(2, 6)))
 

groupByKey(): RDD[(K, Seq[V])]

(2,CompactBuffer(sr2))
(1,CompactBuffer(sr1, sri1))
(3,CompactBuffer(sr3))
(5,CompactBuffer(sr5))

groupWith - RDD[(K, (Seq[V], Seq[W]))]

p1.groupWith(ip1)
(2,(CompactBuffer(sr2),CompactBuffer(2, 6)))
(1,(CompactBuffer(sr1, sri1),CompactBuffer(1, 5)))
(3,(CompactBuffer(sr3),CompactBuffer(3, 7)))
(5,(CompactBuffer(sr5),CompactBuffer()))


Join  - RDD[(K, (V, W))]

p1.join(p2)

(2,(sr2,cs2))
(1,(sr1,cs1))
(1,(sri1,cs1))

ip1.join(ip2)

(2,(2,7))
(2,(6,7))
(1,(1,6))
(1,(1,11))
(1,(5,6))
(1,(5,11))
(3,(3,8))
(3,(7,8))


Left Outer Join = RDD[(K, (V, Option[W]))]

ip1.leftOuterJoin(ip2)

(1,(1,Some(6)))
(1,(1,Some(11)))
(1,(5,Some(6)))
(1,(5,Some(11)))
(3,(3,Some(8)))
(3,(7,Some(8)))
(2,(2,Some(7)))
(2,(6,Some(7)))

 Right Outer Join = RDD[(K, (Option[V], W))
(1,(Some(1),6))
(1,(Some(1),11))
(1,(Some(5),6))
(1,(Some(5),11))
(3,(Some(3),8))
(3,(Some(7),8))
(4,(None,9))
(2,(Some(2),7))
(2,(Some(6),7))

Look Up = Seq[V]

ip1.lookup(1)
Seq[Int] = WrappedArray(1, 5)

ip1.lookup(4)
Seq[Int] = WrappedArray()