Thursday, 4 August 2016

Spark Questions

Q.1 Difference between reduceByKey , groupByKey, aggregateByKey, combineByKey

Ans . 

reduceByKey  : 
      1.  Merge the values for each key using an associative reduce function.

      2. This will also perform the merging locally on each mapper before
        sending results to a reducer, similarly to a "combiner" in MapReduce.

      3 . Output will be partitioned with C{numPartitions} partitions, or
        the default parallelism level if C{numPartitions} is not specified.
        Default partitioner is hash-partition.

aggregateByKey() :

aggregateByKey() will combine the values for a particular key, and the result of such combination can be any object that you specify. You have to specify how the values are combined ("added") inside one partition (that is executed in the same node) and how you combine the result from different partitions (that may be in different nodes). 

reduceByKey is a particular case, in the sense that the result of the combination (e.g. a sum) is of the same type that the values, and that the operation when combined from different partitions is also the same as the operation when combining values inside a partition.

The reason reduceByKey() is so much better is because it makes use of a MapReduce feature called a combiner. Any function like + or * can be used in this fashion because the order of the elements it is called on doesn't matter. This allows Spark to start "reducing" values with the same key even if they are not all in the same partition yet.




The aggregateByKey function requires 3 parameters:

1. An intitial ‘zero’ value that will not effect the total values to be collected. For example if we were adding numbers the initial value would be 0. Or in the case of collecting unique elements per key, the initial value would be an empty set.

2. A combining function accepting two paremeters. The second paramter is merged into the first parameter. This function combines/merges values within a partition.This function can return a different result type, U, than the type  of the values in this RDD, V.

3. A merging function function accepting two parameters. In this case the paremters are merged into one. This step merges values across partitions.


 To avoid memory allocation, both of these functions are  allowed to modify and return their first argument instead of  creating a new U.


groupByKey() :

gives you more versatility since you write a function that takes an Iterable, meaning you could even pull all the elements into an array. However it is inefficient because for it to work the full set of (K,V,) pairs have to be in one partition.


Q .2 Difference between join and union

Union :     

Return the union of this RDD and another one.
rdd = sc.parallelize([1, 1, 2, 3])
rdd.union(rdd).collect()
[1, 1, 2, 3, 1, 1, 2, 3]

Join :
Join is done on PairRDDs


Ans .
     map() :
     Returns a new RDD by applying a function to each element of this RDD.
     example :
     rdd = sc.parallelize(["b", "a", "c"])
     sorted(rdd.map(lambda x: (x, 1)).collect())
      [('a', 1), ('b', 1), ('c', 1)]

     mapPartitioons():
     Return a new RDD by applying a function to each partition of this RDD.
     example :
      rdd = sc.parallelize([1, 2, 3, 4], 2)
      def f(iterator): yield sum(iterator)
      rdd.mapPartitions(f).collect()
        [3, 7]
 
    mapPartitionsWithIndex() :
    example :
    Return a new RDD by applying a function to each partition of this RDD,
        while tracking the index of the original partition.

       rdd = sc.parallelize([1, 2, 3, 4], 4)
       def f(splitIndex, iterator): yield splitIndex
       rdd.mapPartitionsWithIndex(f).sum()
        6
Q.4 What are transformations in spark ?
Ans .
Transformations on DStreams can be grouped into either stateless or stateful:
• 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 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.

Q.5 What is schemaRDD in Spark ?

Ans. Spark SQL allows relational queries expressed in SQL, HiveQL, or Scala to be executed using Spark. At the core of this component is a new type of RDD,SchemaRDD. SchemaRDDs are composed of Row objects, along with a schema that describes the data types of each column in the row.

Q.6 What is lazy transformation in spark ?

Ans
All transformations in Spark are lazy, in that they do not compute their results right away. Instead, they just remember the transformations applied to some base dataset (e.g. a file). The transformations are only computed when an action requires a result to be returned to the driver program. This design enables Spark to run more efficiently. For example, we can realize that a dataset created through map will be used in areduce and return only the result of the reduce to the driver, rather than the larger mapped dataset.
By default, each transformed RDD may be recomputed each time you run an action on it. However, you may also persist an RDD in memory using the persist (or cache) method, in which case Spark will keep the elements around on the cluster for much faster access the next time you query it. There is also support for persisting RDDs on disk, or replicated across multiple nodes.. 

Q.7 What  are the spark core components ?
Ans .





Spark uses a master/slave architecture. As you can see in the figure, it has one central coordinator (Driver) that communicates with many distributed workers (executors). The driver and each of the executors run in their own Java processes.

DRIVER
The driver is the process where the main method runs. First it converts the user program into tasks and after that it schedules the tasks on the executors.
EXECUTORS
Executors are worker nodes' processes in charge of running individual tasks in a given Spark job. They are launched at the beginning of a Spark application and typically run for the entire lifetime of an application. Once they have run the task they send the results to the driver. They also provide in-memory storage for RDDs that are cached by user programs through Block Manager.
APPLICATION EXECUTION FLOW
With this in mind, when you submit an application to the cluster with spark-submit this is what happens internally:
  1. A standalone application starts and instantiates a SparkContext instance (and it is only then when you can call the application a driver).
  2. The driver program ask for resources to the cluster manager to launch executors.
  3. The cluster manager launches executors.
  4. The driver process runs through the user application. Depending on the actions and transformations over RDDs task are sent to executors.
  5. Executors run the tasks and save the results.
  6. If any worker crashes, its tasks will be sent to different executors to be processed again. In the book "Learning Spark: Lightning-Fast Big Data Analysis" they talk about Spark and Fault Tolerance.
  7. With SparkContext.stop() from the driver or if the main method exits/crashes all the executors will be terminated and the cluster resources will be released by the cluster manager
Q .8 Define Partitions?

Ans.

As the name suggests, partition is a smaller and logical division of data  similar to ‘split’ in MapReduce. Partitioning is the process to derive logical units of data to speed up the processing process. Everything in Spark is a partitioned RDD.

Q .9 What is RDD Lineage ?

Ans .

Spark does not support data replication in the memory and thus, if any data is lost, it is rebuild using RDD lineage. RDD lineage is a process that reconstructs lost data partitions. The best is that RDD always remembers how to build from other datasets.

Q .10 What are benefits of Spark over MapReduce?

Ans.
  1. • Due to the availability of in-memory processing, Spark implements the processing around 10-100x faster than Hadoop MapReduce. MapReduce makes use of persistence storage for any of the data processing tasks.
  2. • Unlike Hadoop, Spark provides in-built libraries to perform multiple tasks form the same core like batch processing, Steaming, Machine learning, Interactive SQL queries. However, Hadoop only supports batch processing.
  3. • Hadoop is highly disk-dependent whereas Spark promotes caching and in-memory data storage
  4. • Spark is capable of performing computations multiple times on the same dataset. This is called iterative computation while there is no iterative computing implemented by Hadoop.
  5. Read more in this blog about the comparison of Spark and MapReduce.

Ans. 

A RDD Lineage Graph (aka RDD operator graph) is a graph of all the parent RDDs of a RDD. It is built as a result of applying transformations to the RDD and creates a logical execution plan.
The following diagram uses cartesian or zip for learning purposes only. You may use other operators to build a RDD graph.

Figure .RDD Lineage

The above RDD graph could be the result of the following series of transformations:
      val r00 = sc.parallelize(0 to 9)

      val r01 = sc.parallelize(0 to 90 by 10)
     val r10 = r00 cartesian r01
     val r11 = r00.map(n => (n, n))
     val r12 = r00 zip r01
     val r13 = r01.keyBy(_ / 20)
    val r20 = Seq(r11, r12, r13).foldLeft(r10)(_ union _)
    
A RDD lineage graph is hence a graph of what transformations need to be executed     after an action has been called.
you ccan check lineage information using rdd.toDebugString() function.

Wednesday, 3 August 2016

What is Zookeper ?

ZooKeeper is a high-performance coordination service for distributed applications(like HBase). It exposes common services like naming, configuration management, synchronization, and group services, in a simple interface so you don't have to write them from scratch. You can use it off-the-shelf to implement consensus, group management, leader election, and presence protocols. And you can build on it for your own, specific needs.
1. At a High level

ZooKeeper is a service for sure - to which clients can connect to. It provides access to clients to a tree like structure  or a hierarchical namespace as ZooKeeper documentation says. So why we need this tree ? Of course for storing data and hence it is called a “data tree”. On that tree you can do the whole set of CRUD operations, Plus you can use GET and SET operations for data manipulations. It uses the standard UNIX notation for file system paths. For example, we use /A/B/C to denote the path to zNode C, where C has B as its parent and B has A as its parent. Here is a sample:




That looks very much like a UNIX file system, right?  But here is the terminology
1.    Each node in the tree is called a zNode
2.    Every zNode in the tree is identified by a path
3.   zNode types – persistent and ephemeral
4.    Each zNode will store a value or data and may be child nodes
5.    Cannot rename znodes
6.    We can add/remove WATCH  to znodes.
That’s it, someone rightly said ZooKeeper is Feature-light and you could build recipes on top of it. Take a look at netflix’s curator framework (now a Apache project) – some said this makes using ZooKeeper so much easy from a client perspective. WATCHes are interesting - you can SET a WATCH for a zNode path to let you know if something changed. Kind of subscribing to changes on a path.

2. One level deeper

So lets consider another example where goal is to store some configurations in a <K,V> format and make it available across cluster of machines. The <K,V> should be persistent aka disk based and should be HA or Replicated and fault tolerant. ZooKeeper is a 'natural' for  this use case.




Role of Zookeeper in Hbase :

1.   HBase relies completely on Zookeeper. HBase provides you the option to use its built-in Zookeeper which will get started whenever you start HBAse. But it is not good if you are working on a production cluster. In such scenarios it's always good to have a dedicated Zookeeper cluster and integrate it with your HBase cluster.

2. A distributed HBase relies completely on Zookeeper (for cluster configuration and management). In Apache HBase, ZooKeeper coordinates, communicates, and shares state between the Masters and RegionServers. HBase has a design policy of using ZooKeeper only for transient data (that is, for coordination and state communication). Thus if the HBase’s ZooKeeper data is removed, only the transient operations are affected — data can continue to be written and read to/from HBase.

Technically speaking: By default HBase manages zookeeper itself i.e. starting and stopping the zookeeper quorum (the cluster of zookeeper nodes) when we start and stop HBase - to verify the settings look into the file conf/hbase-evn.sh (in your hbase directory) there must be a line:

Q .Why number of node in zookeeper should be odd ?
Ans .

Zookeeper requires that you have a quorum of servers up, where quorum is ceil(N/2). For a 3 server ensemble, that means 2 servers must be up at any time, for a 5 server ensemble, 3 servers need to be up at any time.

Reliability:

A single ZooKeeper server (standalone) is essentially a coordinator with
no reliability (a single serving node failure brings down the ZK service).

A 3 server ensemble (you need to jump to 3 and not 2 because ZK works
based on simple majority voting) allows for a single server to fail and
the service will still be available.

So if you want reliability go with at least 3. We typically recommend
having 5 servers in "online" production serving environments. This allows
you to take 1 server out of service (say planned maintenance) and still
be able to sustain an unexpected outage of one of the remaining servers

w/o interruption of the service.

Q 2 .Why number of nodes are odd in zookeeper ?
Ans .Due to voting mechanism.

Kafka Questions

1 .Benchmarking kafka :

Source :Lnkdin Blogs :
https://engineering.linkedin.com/kafka/benchmarking-apache-kafka-2-million-writes-second-three-cheap-machines

https://engineering.linkedin.com/distributed-systems/log-what-every-software-engineer-should-know-about-real-time-datas-unifying

Q.2 Difference between kafka Receiver based approach and Direct Approach
Ans .


 Receiver-based Approach :

This approach uses a Receiver to receive the data. The Receiver is implemented using the Kafka high-level consumer API. As with all receivers, the data received from Kafka through a Receiver is stored in Spark executors, and then jobs launched by Spark Streaming processes the data.
However, under default configuration, this approach can lose data under failures (see receiver reliability. To ensure zero-data loss, you have to additionally enable Write Ahead Logs in Spark Streaming (introduced in Spark 1.2). This synchronously saves all the received Kafka data into write ahead logs on a distributed file system (e.g HDFS), so that all the data can be recovered on failure

Direct Approach (No Receivers) :

Instead of using receivers to receive data, this approach periodically queries Kafka for the latest offsets in each topic+partition, and accordingly defines the offset ranges to process in each batch.
  • Simplified Parallelism: No need to create multiple input Kafka streams and union them. With directStream, Spark Streaming will create as many RDD partitions as there are Kafka partitions to consume, which will all read data from Kafka in parallel. So there is a one-to-one mapping between Kafka and RDD partitions, which is easier to understand and tune.
  • Efficiency: Achieving zero-data loss in the first approach required the data to be stored in a Write Ahead Log, which further replicated the data. This is actually inefficient as the data effectively gets replicated twice - once by Kafka, and a second time by the Write Ahead Log. This second approach eliminates the problem as there is no receiver, and hence no need for Write Ahead Logs. As long as you have sufficient Kafka retention, messages can be recovered from Kafka.
  • Exactly-once semantics: The first approach uses Kafka’s high level API to store consumed offsets in Zookeeper. This is traditionally the way to consume data from Kafka. While this approach (in combination with write ahead logs) can ensure zero data loss (i.e. at-least once semantics), there is a small chance some records may get consumed twice under some failures. This occurs because of inconsistencies between data reliably received by Spark Streaming and offsets tracked by Zookeeper. Hence, in this second approach, we use simple Kafka API that does not use Zookeeper. Offsets are tracked by Spark Streaming within its checkpoints.
Source :http://spark.apache.org/docs/latest/streaming-kafka-integration.html

Q.In Kafka how does messages get distributed to partitioner ?
Ans. Primary objective of Partition is to achieve parallelism. So you can have as many number of consumers reading from same topic as you have partitions.
So if you create partition  then you decide how messages should go to which partition. So either use "key" while sending messages to Topic or write your own custom logic for same. e.g. You can have 3 Partitions and divided your messages in High, Medium, Low priority. So you can implement a partitioner such that High goes to 1 , Medium goes to 1 and low goes to 2 

Q. How to purge kafka topic ?
Ans . 
Temporarily update the retention time on the topic to one second:

Command:
kafka-topics.sh --zookeeper localhost:13003 --alter --topic MyTopic --config retention.ms=1000


Then wait for the purge to take effect (about one minute). Once purged, restore the previous retention.ms value.

Installing Multiple Broker's on Single kafka cluster

Installing  Multiple Broker's on Single kafka cluster :

Streps to create multiple brokers on single node :

1. cp /etc/kafka/conf/server.properties /etc/kafka/conf/server1.properties
it will create new server1.properties file .
Make following changes to the file

broker.id=1
port=9093
log.dir=/tmp/kafka-logs-1

2.  cp /etc/kafka/conf/server.properties /etc/kafka/conf/server2.properties
it will create new server2.properties file .
Make following changes to the file

server2.properties
broker.id=2
port=9094
log.dir=/tmp/kafka-logs-2

then start all the brokers :

nohup /usr/hdp/2.2.9.1-11/kafka/bin/kafka-server-start.sh /etc/kafka/conf/server.properties
nohup /usr/hdp/2.2.9.1-11/kafka/bin/kafka-server-start.sh /etc/kafka/conf/server1.properties
nohup /usr/hdp/2.2.9.1-11/kafka/bin/kafka-server-start.sh /etc/kafka/conf/server2.properties

Now you can see three brokers are running on Node.

Note. make sure you have set these properties :
zookeeper.connect=host1:2181,host2:2181,..
listeners:PLAINTEXT://host:9092

Kafka Questions

1 .Benchmarking kafka :

Source :Lnkdin Blogs :


Q. What is difference between kafka Receiver based approach and Direct Approach
Ans .

 Receiver-based Approach :

This approach uses a Receiver to receive the data. The Receiver is implemented using the Kafka high-level consumer API. As with all receivers, the data received from Kafka through a Receiver is stored in Spark executors, and then jobs launched by Spark Streaming processes the data.
However, under default configuration, this approach can lose data under failures (see receiver reliability. To ensure zero-data loss, you have to additionally enable Write Ahead Logs in Spark Streaming (introduced in Spark 1.2). This synchronously saves all the received Kafka data into write ahead logs on a distributed file system (e.g HDFS), so that all the data can be recovered on failure

Direct Approach (No Receivers) :

Instead of using receivers to receive data, this approach periodically queries Kafka for the latest offsets in each topic+partition, and accordingly defines the offset ranges to process in each batch.

  • Simplified Parallelism: No need to create multiple input Kafka streams and union them. With directStream, Spark Streaming will create as many RDD partitions as there are Kafka partitions to consume, which will all read data from Kafka in parallel. So there is a one-to-one mapping between Kafka and RDD partitions, which is easier to understand and tune.
  • Efficiency: Achieving zero-data loss in the first approach required the data to be stored in a Write Ahead Log, which further replicated the data. This is actually inefficient as the data effectively gets replicated twice - once by Kafka, and a second time by the Write Ahead Log. This second approach eliminates the problem as there is no receiver, and hence no need for Write Ahead Logs. As long as you have sufficient Kafka retention, messages can be recovered from Kafka.
  • Exactly-once semantics: The first approach uses Kafka’s high level API to store consumed offsets in Zookeeper. This is traditionally the way to consume data from Kafka. While this approach (in combination with write ahead logs) can ensure zero data loss (i.e. at-least once semantics), there is a small chance some records may get consumed twice under some failures. This occurs because of inconsistencies between data reliably received by Spark Streaming and offsets tracked by Zookeeper. Hence, in this second approach, we use simple Kafka API that does not use Zookeeper. Offsets are tracked by Spark Streaming within its checkpoints.
Source :http://spark.apache.org/docs/latest/streaming-kafka-integration.html

Q.In Kafka how does messages get distributed to partitioner ?

Ans. Primary objective of Partition is to achieve parallelism. So you can have as many number of consumers reading from same topic as you have partitions.
So if you create partition  then you decide how messages should go to which partition. So either use "key" while sending messages to Topic or write your own custom logic for same. e.g. You can have 3 Partitions and divided your messages in High, Medium, Low priority. So you can implement a partitioner such that High goes to 1 , Medium goes to 1 and low goes to 2 

Q. How to purge kafka topic ?
Ans . 
Temporarily update the retention time on the topic to one second:

Command:

kafka-topics.sh --zookeeper localhost:13003 --alter --topic MyTopic --config retention.ms=1000

Then wait for the purge to take effect (about one minute). Once purged, restore the previous retention.ms value.

Q. what is role of zookeeper in kafka ?
Kafka is built to use Zookeeper. 
Kafka is a distributed system and uses Zookeeper to track status of kafka cluster nodes. It also keeps track of Kafka topics, partitions etc.
It is basically used to maintain co-ordination between different nodes in a cluster, one of the most important thing for kafka is it uses zookeeper to periodically commit offset so that in case of node failure it can resume from the previously committed offset (imagine yourself taking care of all this by your own). Zookeeper also plays vital role for serving so many other purposes such as leader detection, configuration management, synchronization, detecting when a new node join or leaves the cluster etc
Now how Kafka uses ZooKeeper?
As of v0.8 Kafka uses zookeeper for storing variety of configurations as K,V in the ZK data tree and use them across the cluster in a distributed fashion Lets take 2 simple use cases for which Kafka maintains values in ZooKeeper

1.    Topics under a broker -/brokers/topics/[topic] 

2.   Next Offset for a Consumer/Topic/Partition combination -/consumers/[groupId]/offsets/[topic]/[partitionId]

Now think about “distributed-ness” Of course configurations like these are replicated and distributed throughout the ZooKeeper ensemble – Leader node and Follower nodes. So I don’t think Kafka will work without ZooKeeper (at least pre 0.8.2 version of Kafka).

Kafka uses Zookeeper for the following:


  1. Electing a controller. The controller is one of the brokers and is responsible for maintaining the leader/follower relationship for all the partitions. When a node shuts down, it is the controller that tells other replicas to become partition leaders to replace the partition leaders on the node that is going away. Zookeeper is used to elect a controller, make sure there is only one and elect a new one it if it crashes.
  2. Cluster membership - which brokers are alive and part of the cluster? this is also managed through ZooKeeper.
  3. Topic configuration - which topics exist, how many partitions each has, where are the replicas, who is the preferred leader, what configuration overrides are set for each topic
  4. (0.9.0) - Quotas - how much data is each client allowed to read and write
  5. (0.9.0) - ACLs - who is allowed to read and write to which topic
  6. (old high level consumer) - Which consumer groups exist, who are their members and what is the latest offset each group got from each partition.
  7.   Zookeeper is mainly used to track status of nodes present in Kafka cluster and also to keep track of Kafka topics, messages, etc.

 Q.2 How producer identify the leader in kafka?
Ans .The producer sends a Metadata request with a list of topics to one of the brokers in the broker-list you supplied when configuring the producer.
The broker responds with a list of partitions in those topics and the leader for each partition. The producer caches this information and knows where to redirect its produce messages. 
Q.3 Is Kafka good for a scenario involving 100s of thousands of topics (Where 10s of topics or a topic with 10s of partition will represent a data flow for a customer)?
Ans . Technically, Kafka will work nicely with 1000-3000 partitions per broker, so with enough brokers your plan will work.
However, in my experience, whenever people come up with a plan that ends up with 100K topics or more, they are not designing their data model correctly. This is especially true for people who used JMS queues before and are applying the same type of design to Kafka.
Q.4  What's the point of partitions in Kafka? How do I know how many partitions are best for a data set of size X?
Q .5 What happens when number of consumer is greater than partitions vice-versa ?
Ans .

 Consumers read from any single partition, allowing you to scale throughput of message consumption in a similar fashion to message production. Consumers can also be organized into consumer groups for a given topic — each consumer within the group reads from a unique partition and the group as a whole consumes all messages from the entire topic.

 If you have more consumers than partitions then some consumers will be idle because they have no partitions to read from. 

If you have more partitions than consumers then consumers will receive messages from multiple partitions. 

If you have equal numbers of consumers and partitions, each consumer reads messages in order from exactly one partition.

following diagram explains the scenario :




Q .6 How kafka guarantees consistency and availabiblty ?                                                              
                                                       
Ans.Before beginning the discussion on consistency and availability, keep in mind that these guarantees hold as long as you are producing to one partition and consuming from one partition. All guarantees are off if you are reading from the same partition using two consumers or writing to the same partition using two producers.
Kafka makes the following guarantees about data consistency and availability: (1) Messages sent to a topic partition will be appended to the commit log in the order they are sent, (2) a single consumer instance will see messages in the order they appear in the log, (3) a message is ‘committed’ when all in sync replicas have applied it to their log, and (4) any committed message will not be lost, as long as at least one in sync replica is alive.
The first and second guarantee ensure that message ordering is preserved for each partition. Note that message ordering for the entire topic is not guaranteed. The third and fourth guarantee ensure that committed messages can be retrieved. In Kafka, the partition that is elected the leader is responsible for syncing any messages received to replicas. Once a replica has acknowledged the message, that replica is considered to be in sync. To understand this further, lets take a closer look at what happens during a write.

Installing  Multiple Broker's on Single kafka cluster :

Streps to create multiple brokers on single node :

1. cp /etc/kafka/conf/server.properties /etc/kafka/conf/server1.properties
it will create new server1.properties file .
Make following changes to the file

broker.id=1
port=9093
log.dir=/tmp/kafka-logs-1

2.  cp /etc/kafka/conf/server.properties /etc/kafka/conf/server2.properties
it will create new server2.properties file .
Make following changes to the file

server2.properties
broker.id=2
port=9094
log.dir=/tmp/kafka-logs-2

then start all the brokers :

nohup /usr/hdp/2.2.9.1-11/kafka/bin/kafka-server-start.sh /etc/kafka/conf/server.properties
nohup /usr/hdp/2.2.9.1-11/kafka/bin/kafka-server-start.sh /etc/kafka/conf/server1.properties
nohup /usr/hdp/2.2.9.1-11/kafka/bin/kafka-server-start.sh /etc/kafka/conf/server2.properties

Now you can see three brokers are running on Node.

Note. make sure you have set these properties :
zookeeper.connect=host1:2181,host2:2181,..
listeners:PLAINTEXT://host:9092