Introduction
Apache Kafka is an open-source scalable and
high-throughput messaging system developed by the Apache Software Foundation
written in Scala. Apache Kafka is specially designed to allow a single cluster
to serve as the central data backbone for a large environment. It has a much
higher throughput compared to other message brokers systems like ActiveMQ and
RabbitMQ. It is capable of handling large volumes of real-time data
efficiently. You can deploy Kafka on single Apache server or in a distributed
clustered environment.
Features
The general features of Kafka are as follows
:
1.
Persist message on disk that provide constant time performance.
2.
High throughput with disk structures that supporting hundreds of
thousands of messages per second.
3.
Distributed system scales easily with no downtime.
4. Supports multi-subscribers
and automatically balances the consumers during failure.
This tutorial shows how to install and
configure Apache Kafka on a Ubuntu 16.04 server.
Requirements
•
A Ubuntu 16.04 server.
•
Non-root user account with sudo privilege set up on your server.
Getting Started
Let's start making sure that your Ubuntu
16.04 server is fully up to date.
You can update your server by running the
following command:
sudo apt-get update -y
sudo apt-get upgrade -y
Installing Java
Before installing Kafka, you will need to
install Java on your system. You can install Oracle JDK 8 using the Webupd8
team PPA repository.
To add the repository, run the following
command:
sudo add-apt-repository -y ppa:webupd8team/java
You should see the following output:
gpg: keyring `/tmp/tmpkjrm4mnm/secring.gpg' created
gpg: keyring `/tmp/tmpkjrm4mnm/pubring.gpg' created
gpg: requesting key EEA14886 from hkp server
keyserver.ubuntu.com
gpg: /tmp/tmpkjrm4mnm/trustdb.gpg: trustdb created
gpg: key EEA14886: public key "Launchpad
VLC" imported
gpg: no ultimately trusted keys found
gpg: Total number processed: 1
gpg:
imported: 1 (RSA: 1)
OK
Next, update the metadata of the new
repository by running the following command:
sudo apt-get update
Once you have finished, run the following
command to install JDK 8:
sudo apt-get install oracle-java8-installer -y
You can also verify that JDK 8 is installed
properly by running the following command:
sudo java -version
You should see the output something like
this:
java version "1.8.0_66"
Java(TM) SE Runtime Environment (build
1.8.0_66-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17,
mixed mode)
Install ZooKeeper
Before installing Apache Kafka, you will need
to have zookeeper available and running. ZooKeeper is an open source service
for maintaining configuration information, providing distributed
synchronization, naming and providing group services.
By default ZooKeeper package is available in
Ubuntu's default repository, you can install it by running the following
command:
sudo apt-get install zookeeperd
Once installation is finished, it will be
started as a daemon automatically. By default ZooKeeper will run on port 2181.
You can test it by running the following
command:
netstat -ant | grep :2181
If everything's fine, you should see the
following Output:
tcp6
0 0 :::2181 :::* LISTEN
Install and Start Kafka Server
Now that Java and ZooKeeper are installed, it
is time to download and extract Kafka from Apache website. You can use wget to
download Kafka:
wget
http://mirror.fibergrid.in/apache/kafka/0.10.0.1/kafka_2.10-0.10.0.1.tgz
Next, create a directory for Kafka
installation:
sudo mkdir /opt/Kafka
cd /opt/Kafka
Extract the downloaded archive using tar
command in /opt/Kafka:
sudo tar -xvf kafka_2.10-0.10.0.1.tgz -C
/opt/Kafka/
The next step is to start Kafka server, you
can start it by running kafka-server-start.sh script located at
/opt/Kafka/kafka_2.10-0.10.0.1/bin/ directory.
sudo
/opt/Kafka/kafka_2.10-0.10.0.1/bin/kafka-server-start.sh
/opt/Kafka/kafka_2.10-0.10.0.1/config/server.properties
You should see the following output, if the
server has started successfully:
[2016-08-22 21:43:48,279] WARN No meta.properties
file under dir /tmp/kafka-logs/meta.properties
(kafka.server.BrokerMetadataCheckpoint)
[2016-08-22 21:43:48,516] INFO Kafka version :
0.10.0.1 (org.apache.kafka.common.utils.AppInfoParser)
[2016-08-22 21:43:48,525] INFO Kafka commitId :
a7a17cdec9eaa6c5 (org.apache.kafka.common.utils.AppInfoParser)
[2016-08-22 21:43:48,527] INFO [Kafka Server 0],
started (kafka.server.KafkaServer)
[2016-08-22 21:43:48,555] INFO New leader is 0
(kafka.server.ZookeeperLeaderElector$LeaderChangeListener)
You can use nohup with script to start the
Kafka server as a background process:
sudo nohup
/opt/Kafka/kafka_2.10-0.10.0.1/bin/kafka-server-start.sh
/opt/Kafka/kafka_2.10-0.10.0.1/config/server.properties /tmp/kafka.log
2>&1 &
You now have a Kafka server running and
listening on port 9092.
Testing Kafka Server
Now, it is time to verify the Kafka server is
operating correctly.
To test Kafka, create a sample topic with
name "testing" in Apache Kafka using the following command:
sudo
/opt/Kafka/kafka_2.10-0.10.0.1/bin/kafka-topics.sh --create --zookeeper
localhost:2181 --replication-factor 1
--partitions 1 --topic testing
You should see the following output:
Created topic "testing".
Now, ask Zookeeper to list available topics
on Apache Kafka by running the following command:
sudo /opt/Kafka/kafka_2.10-0.10.0.1/bin/kafka-topics.sh
--list --zookeeper localhost:2181
You should see the following output:
testing
Now, publish a sample messages to Apache
Kafka topic called testing by using the following producer command:
sudo /opt/Kafka/kafka_2.10-0.10.0.1/bin/kafka-console-producer.sh
--broker-list localhost:9092 --topic testing
After running above command, enter some
messages like "Hi how are you?" press enter, then enter another
message like "Where are you?"
Now, use consumer command to check for messages
on Apache Kafka Topic called testing by running the following command:
sudo
/opt/Kafka/kafka_2.10-0.10.0.1/bin/kafka-console-consumer.sh --zookeeper
localhost:2181 --topic testing --from-beginning
You should see the following output:
Hi how are you?
Where are you?
With this above testing you have successfully
verified that you have a valid Apache Kafka setup with Apache Zookeeper.
Summary
At this point, we have installed, configured,
and tested Kafka on a Ubuntu 16.04 server. You can adapt the setup to make use
of it in your production environment. To learn more about Kafka check out the Kafka documentation.
Quickstart
This tutorial assumes you are starting fresh
and have no existing Kafka or ZooKeeper data. Since Kafka console scripts are
different for Unix-based and Windows platforms, on Windows platforms use
bin\windows\ instead of bin/, and change the script extension to .bat.
Download the 0.10.2.0 release and
un-tar it.
> tar -xzf kafka_2.11-0.10.2.0.tgz
> cd kafka_2.11-0.10.2.0
Kafka uses ZooKeeper so you need to first
start a ZooKeeper server if you don't already have one. You can use the
convenience script packaged with kafka to get a quick-and-dirty single-node
ZooKeeper instance.
> bin/zookeeper-server-start.sh
config/zookeeper.properties
[2016-04-22 15:01:37,495] INFO Reading
configuration from: config/zookeeper.properties
(org.apache.zookeeper.server.quorum.QuorumPeerConfig)
...
Now start the Kafka server:
> bin/kafka-server-start.sh
config/server.properties
[2016-04-22 15:01:47,028] INFO Verifying properties
(kafka.utils.VerifiableProperties)
[2016-04-22 15:01:47,051] INFO Property
socket.send.buffer.bytes is overridden to 1048576
(kafka.utils.VerifiableProperties)
...
Let's create a topic named "test"
with a single partition and only one replica:
> bin/kafka-topics.sh --create --zookeeper
localhost:2181 --replication-factor 1 --partitions 1 --topic test
We can now see that topic if we run the list
topic command:
> bin/kafka-topics.sh --list --zookeeper localhost:2181
test
Alternatively, instead of manually creating
topics you can also configure your brokers to auto-create topics when a
non-existent topic is published to.
Kafka comes with a command line client that
will take input from a file or from standard input and send it out as messages
to the Kafka cluster. By default, each line will be sent as a separate message.
Run the producer and then type a few messages
into the console to send to the server.
> bin/kafka-console-producer.sh --broker-list
localhost:9092 --topic test
This is a message
This is another message
Kafka also has a command line consumer that
will dump out messages to standard output.
> bin/kafka-console-consumer.sh
--bootstrap-server localhost:9092 --topic test --from-beginning
This is a message
This is another message
If you have each of the above commands
running in a different terminal then you should now be able to type messages
into the producer terminal and see them appear in the consumer terminal.
All of the command line tools have additional
options; running the command with no arguments will display usage information
documenting them in more detail.
So far we have been running against a single
broker, but that's no fun. For Kafka, a single broker is just a cluster of size
one, so nothing much changes other than starting a few more broker instances.
But just to get feel for it, let's expand our cluster to three nodes (still all
on our local machine).
First we make a config file for each of the
brokers (on Windows use the copy command instead):
> cp config/server.properties
config/server-1.properties
> cp config/server.properties
config/server-2.properties
Now edit these new files and set the following
properties:
config/server-1.properties:
broker.id=1
listeners=PLAINTEXT://:9093
log.dir=/tmp/kafka-logs-1
config/server-2.properties:
broker.id=2
listeners=PLAINTEXT://:9094
log.dir=/tmp/kafka-logs-2
The broker.id property is the unique and
permanent name of each node in the cluster. We have to override the port and
log directory only because we are running these all on the same machine and we
want to keep the brokers from all trying to register on the same port or overwrite
each other's data.
We already have Zookeeper and our single node
started, so we just need to start the two new nodes:
> bin/kafka-server-start.sh
config/server-1.properties &
...
> bin/kafka-server-start.sh
config/server-2.properties &
...
Now create a new topic with a replication
factor of three:
> bin/kafka-topics.sh --create --zookeeper
localhost:2181 --replication-factor 3 --partitions 1 --topic
my-replicated-topic
Okay but now that we have a cluster how can
we know which broker is doing what? To see that run the "describe
topics" command:
> bin/kafka-topics.sh --describe --zookeeper
localhost:2181 --topic my-replicated-topic
Topic:my-replicated-topic PartitionCount:1 ReplicationFactor:3 Configs:
Topic: my-replicated-topic Partition: 0 Leader: 1 Replicas: 1,2,0 Isr: 1,2,0
Here is an explanation of output. The first
line gives a summary of all the partitions, each additional line gives
information about one partition. Since we have only one partition for this
topic there is only one line.
•
"leader" is the node responsible for all reads and writes for
the given partition. Each node will be the leader for a randomly selected
portion of the partitions.
•
"replicas" is the list of nodes that replicate the log for
this partition regardless of whether they are the leader or even if they are
currently alive.
•
"isr" is the set of "in-sync" replicas. This is the
subset of the replicas list that is currently alive and caught-up to the
leader.
Note that in my example node 1 is the leader
for the only partition of the topic.
We can run the same command on the original
topic we created to see where it is:
> bin/kafka-topics.sh --describe --zookeeper
localhost:2181 --topic test
Topic:test
PartitionCount:1
ReplicationFactor:1 Configs:
Topic: test Partition: 0 Leader: 0 Replicas: 0 Isr: 0
So there is no surprise there—the original
topic has no replicas and is on server 0, the only server in our cluster when
we created it.
Let's publish a few messages to our new
topic:
> bin/kafka-console-producer.sh --broker-list
localhost:9092 --topic my-replicated-topic
...
my test message 1
my test message 2
^C
Now let's consume these messages:
> bin/kafka-console-consumer.sh
--bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
...
my test message 1
my test message 2
^C
Now let's test out fault-tolerance. Broker 1
was acting as the leader so let's kill it:
> ps aux | grep server-1.properties
7564 ttys002 0:15.91
/System/Library/Frameworks/JavaVM.framework/Versions/1.8/Home/bin/java...
> kill -9 7564
On Windows use:
> wmic process get
processid,caption,commandline | find "java.exe" | find
"server-1.properties"
java.exe
java -Xmx1G -Xms1G -server
-XX:+UseG1GC ... build\libs\kafka_2.10-0.10.2.0.jar" kafka.Kafka config\server-1.properties 644
> taskkill /pid 644 /f
Leadership has switched to one of the slaves
and node 1 is no longer in the in-sync replica set:
> bin/kafka-topics.sh --describe --zookeeper
localhost:2181 --topic my-replicated-topic
Topic:my-replicated-topic PartitionCount:1 ReplicationFactor:3 Configs:
Topic: my-replicated-topic
Partition: 0 Leader: 2 Replicas: 1,2,0 Isr: 2,0
But the messages are still available for
consumption even though the leader that took the writes originally is down:
> bin/kafka-console-consumer.sh
--bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
...
my test message 1
my test message 2
^C
Writing data from the console and writing it
back to the console is a convenient place to start, but you'll probably want to
use data from other sources or export data from Kafka to other systems. For
many systems, instead of writing custom integration code you can use Kafka
Connect to import or export data.
Kafka Connect is a tool included with Kafka
that imports and exports data to Kafka. It is an extensible tool that runs connectors,
which implement the custom logic for interacting with an external system. In
this quickstart we'll see how to run Kafka Connect with simple connectors that
import data from a file to a Kafka topic and export data from a Kafka topic to
a file.
First, we'll start by creating some seed data
to test with:
> echo -e "foo\nbar" > test.txt
Next, we'll start two connectors running in standalone
mode, which means they run in a single, local, dedicated process. We provide
three configuration files as parameters. The first is always the configuration
for the Kafka Connect process, containing common configuration such as the
Kafka brokers to connect to and the serialization format for data. The
remaining configuration files each specify a connector to create. These files
include a unique connector name, the connector class to instantiate, and any
other configuration required by the connector.
> bin/connect-standalone.sh
config/connect-standalone.properties config/connect-file-source.properties
config/connect-file-sink.properties
These sample configuration files, included
with Kafka, use the default local cluster configuration you started earlier and
create two connectors: the first is a source connector that reads lines from an
input file and produces each to a Kafka topic and the second is a sink
connector that reads messages from a Kafka topic and produces each as a line in
an output file.
During startup you'll see a number of log
messages, including some indicating that the connectors are being instantiated.
Once the Kafka Connect process has started, the source connector should start
reading lines from test.txt and producing them to the topic connect-test, and
the sink connector should start reading messages from the topic connect-test
and write them to the file test.sink.txt. We can verify the data has been
delivered through the entire pipeline by examining the contents of the output
file:
> cat test.sink.txt
foo
bar
Note that the data is being stored in the Kafka
topic connect-test, so we can also run a console consumer to see the data in
the topic (or use custom consumer code to process it):
> bin/kafka-console-consumer.sh
--bootstrap-server localhost:9092 --topic connect-test --from-beginning
{"schema":{"type":"string","optional":false},"payload":"foo"}
{"schema":{"type":"string","optional":false},"payload":"bar"}
...
The connectors continue to process data, so
we can add data to the file and see it move through the pipeline:
> echo "Another line" >>
test.txt
You should see the line appear in the console
consumer output and in the sink file.
Kafka Streams is a client library of Kafka
for real-time stream processing and analyzing data stored in Kafka brokers.
This quickstart example will demonstrate how to run a streaming application
coded in this library. Here is the gist of the WordCountDemo example code (converted
to use Java 8 lambda expressions for easy reading).
// Serializers/deserializers (serde) for String and
Long types
final Serde<String> stringSerde =
Serdes.String();
final Serde<Long> longSerde = Serdes.Long();
// Construct a `KStream` from the input topic
""streams-file-input", where message values
// represent lines of text (for the sake of this
example, we ignore whatever may be stored
// in the message keys).
KStream<String, String> textLines =
builder.stream(stringSerde, stringSerde, "streams-file-input");
KTable<String, Long> wordCounts = textLines
// Split
each text line, by whitespace, into words.
.flatMapValues(value ->
Arrays.asList(value.toLowerCase().split("\\W+")))
// Group
the text words as message keys
.groupBy((key, value) -> value)
// Count
the occurrences of each word (message key).
.count("Counts")
// Store the running counts as a changelog stream
to the output topic.
wordCounts.to(stringSerde, longSerde,
"streams-wordcount-output");
It implements the WordCount algorithm, which
computes a word occurrence histogram from the input text. However, unlike other
WordCount examples you might have seen before that operate on bounded data, the
WordCount demo application behaves slightly differently because it is designed
to operate on an infinite, unbounded stream of data. Similar to the
bounded variant, it is a stateful algorithm that tracks and updates the counts
of words. However, since it must assume potentially unbounded input data, it
will periodically output its current state and results while continuing to
process more data because it cannot know when it has processed "all"
the input data.
As the first step, we will prepare input data
to a Kafka topic, which will subsequently be processed by a Kafka Streams
application.
> echo -e "all streams lead to
kafka\nhello kafka streams\njoin kafka summit" > file-input.txt
Or on Windows:
> echo all streams lead to kafka>
file-input.txt
> echo hello kafka streams>>
file-input.txt
> echo|set /p=join kafka summit>>
file-input.txt
Next, we send this input data to the input
topic named streams-file-input using the console producer, which reads
the data from STDIN line-by-line, and publishes each line as a separate Kafka
message with null key and value encoded a string to the topic (in practice,
stream data will likely be flowing continuously into Kafka where the
application will be up and running):
> bin/kafka-topics.sh --create \
--zookeeper
localhost:2181 \
--replication-factor
1 \
--partitions
1 \
--topic
streams-file-input
> bin/kafka-console-producer.sh --broker-list
localhost:9092 --topic streams-file-input < file-input.txt
We can now run the WordCount demo application
to process the input data:
> bin/kafka-run-class.sh
org.apache.kafka.streams.examples.wordcount.WordCountDemo
The demo application will read from the input
topic streams-file-input, perform the computations of the WordCount
algorithm on each of the read messages, and continuously write its current
results to the output topic streams-wordcount-output. Hence there won't
be any STDOUT output except log entries as the results are written back into in
Kafka. The demo will run for a few seconds and then, unlike typical stream
processing applications, terminate automatically.
We can now inspect the output of the
WordCount demo application by reading from its output topic:
> bin/kafka-console-consumer.sh
--bootstrap-server localhost:9092 \
--topic
streams-wordcount-output \
--from-beginning \
--formatter
kafka.tools.DefaultMessageFormatter \
--property
print.key=true \
--property
print.value=true \
--property
key.deserializer=org.apache.kafka.common.serialization.StringDeserializer \
--property
value.deserializer=org.apache.kafka.common.serialization.LongDeserializer
with the following output data being printed
to the console:
all 1
lead 1
to 1
hello 1
streams 2
join 1
kafka 3
summit 1
Here, the first column is the Kafka message
key in java.lang.String format, and the second column is the message value in
java.lang.Long format. Note that the output is actually a continuous stream of
updates, where each data record (i.e. each line in the original output above)
is an updated count of a single word, aka record key such as "kafka".
For multiple records with the same key, each later record is an update of the
previous one.
The two diagrams below illustrate what is
essentially happening behind the scenes. The first column shows the evolution
of the current state of the KTable<String, Long> that is counting word
occurrences for count. The second column shows the change records that result
from state updates to the KTable and that are being sent to the output Kafka
topic streams-wordcount-output.
First the text line “all streams lead to
kafka” is being processed. The KTable is being built up as each new word
results in a new table entry (highlighted with a green background), and a
corresponding change record is sent to the downstream KStream.
When the second text line “hello kafka
streams” is processed, we observe, for the first time, that existing entries in
the KTable are being updated (here: for the words “kafka” and for “streams”).
And again, change records are being sent to the output topic.
And so on (we skip the illustration of how
the third line is being processed). This explains why the output topic has the
contents we showed above, because it contains the full record of changes.
Looking beyond the scope of this concrete
example, what Kafka Streams is doing here is to leverage the duality between a
table and a changelog stream (here: table = the KTable, changelog stream = the
downstream KStream): you can publish every change of the table to a stream, and
if you consume the entire changelog stream from beginning to end, you can
reconstruct the contents of the table.
Now you can write more input messages to the streams-file-input
topic and observe additional messages added to streams-wordcount-output
topic, reflecting updated word counts (e.g., using the console producer and the
console consumer, as described above).
You can stop the console consumer via Ctrl-C.
Use cases
Here is a description of a few of the popular
use cases for Apache Kafka™. For an overview of a number of these areas in
action, see this blog post.
Kafka works well as a replacement for a more
traditional message broker. Message brokers are used for a variety of reasons
(to decouple processing from data producers, to buffer unprocessed messages,
etc). In comparison to most messaging systems Kafka has better throughput,
built-in partitioning, replication, and fault-tolerance which makes it a good
solution for large scale message processing applications.
In our experience messaging uses are often
comparatively low-throughput, but may require low end-to-end latency and often
depend on the strong durability guarantees Kafka provides.
The original use case for Kafka was to be
able to rebuild a user activity tracking pipeline as a set of real-time
publish-subscribe feeds. This means site activity (page views, searches, or
other actions users may take) is published to central topics with one topic per
activity type. These feeds are available for subscription for a range of use
cases including real-time processing, real-time monitoring, and loading into
Hadoop or offline data warehousing systems for offline processing and
reporting.
Activity tracking is often very high volume
as many activity messages are generated for each user page view.
Kafka is often used for operational
monitoring data. This involves aggregating statistics from distributed
applications to produce centralized feeds of operational data.
Many people use Kafka as a replacement for a
log aggregation solution. Log aggregation typically collects physical log files
off servers and puts them in a central place (a file server or HDFS perhaps)
for processing. Kafka abstracts away the details of files and gives a cleaner
abstraction of log or event data as a stream of messages. This allows for
lower-latency processing and easier support for multiple data sources and
distributed data consumption. In comparison to log-centric systems like Scribe
or Flume, Kafka offers equally good performance, stronger durability guarantees
due to replication, and much lower end-to-end latency.
Many users of Kafka process data in
processing pipelines consisting of multiple stages, where raw input data is
consumed from Kafka topics and then aggregated, enriched, or otherwise
transformed into new topics for further consumption or follow-up processing.
For example, a processing pipeline for recommending news articles might crawl
article content from RSS feeds and publish it to an "articles" topic;
further processing might normalize or deduplicate this content and published
the cleansed article content to a new topic; a final processing stage might
attempt to recommend this content to users. Such processing pipelines create
graphs of real-time data flows based on the individual topics. Starting in
0.10.0.0, a light-weight but powerful stream processing library called Kafka Streams is available in Apache
Kafka to perform such data processing as described above. Apart from Kafka
Streams, alternative open source stream processing tools include Apache Storm and Apache Samza.
Event sourcing is a style of application
design where state changes are logged as a time-ordered sequence of records.
Kafka's support for very large stored log data makes it an excellent backend
for an application built in this style.
Kafka can serve as a kind of external
commit-log for a distributed system. The log helps replicate data between nodes
and acts as a re-syncing mechanism for failed nodes to restore their data. The log compaction feature in Kafka helps
support this usage. In this usage Kafka is similar to Apache BookKeeper project.
This is a Excellent Information on Hadoop admin Online Training Hyderabad
ReplyDeleteGood work, Thanks for the proper explanation about kafka installation. I found one of the good resource related to Big data and Hadoop. It is providing in-depth knowledge on Big data and Hadoop. which I am sharing a link with you where you can get more clear on Big data and hadoop. To know more Just have a look at this link : https://goo.gl/dr92Ha
ReplyDeletewow very well information you had shared here. This is important thing because when we are running a business first we have to make our focusing area and what we are ready for serve among the people. And really i am much inspired with this 10 steps. Surely it will be useful for craeting the better mindset among our business. Thank you and i am looking forward your more information here
ReplyDeleteHadoop Training in Chennai
Base SAS Training in Chennai
MSBI Training in Chennai