概述

本文主要介绍kafka的安装与简单使用,其中zookeepr是kafka自带的,本文基本按照官网文档进行安装启动的,在此之前需要安装scala
系统环境:centos7

1、下载
可直接在官网下载与scala对应的版本(不要下载成源文件了),,大家可以根据自己的实际情况选择对应的版本。执行以下命令即可下载到本地了。

wget https://www.apache.org/dyn/closer.cgi?path=/kafka/2.3.0/kafka_2.12-2.3.0.tgz

2、解压到指定目录

tar -zxvf kafka_2.12-2.3.0.tgz  -C /opt/

3、启动服务
3.1 启动zookeeper
kafka用到zookeeper,因此如果您的机器上没有zookeeper服务,则需要先启动zookpeer服务,本文使用kafka自带的zookeeper。

cd /opt/kafka_2.12-2.3.0/
bin/zookeeper-server-start.sh config/zookeeper.properties

启动后会有一些日志,下面是最后打出的日志

[2019-08-23 17:12:32,813] INFO binding to port 0.0.0.0/0.0.0.0:2181 (org.apache.zookeeper.server.NIOServerCnxnFactory)
[2019-08-23 17:12:41,375] INFO Expiring session 0x100063d407b0000, timeout of 6000ms exceeded (org.apache.zookeeper.server.ZooKeeperServer)
[2019-08-23 17:12:41,382] INFO Processed session termination for sessionid: 0x100063d407b0000 (org.apache.zookeeper.server.PrepRequestProcessor)
[2019-08-23 17:12:41,383] INFO Creating new log file: log.170 (org.apache.zookeeper.server.persistence.FileTxnLog)

可以看到zookeeper服务的端口为2181

3.2 启动kafka服务
打开第二个终端

bin/kafka-server-start.sh config/server.properties

部分日志信息

[2019-08-23 17:14:57,616] INFO [GroupMetadataManager brokerId=0] Finished loading offsets and group metadata from __consumer_offsets-39 in 0 milliseconds. (kafka.coordinator.group.GroupMetadataManager)
[2019-08-23 17:14:57,617] INFO [GroupMetadataManager brokerId=0] Finished loading offsets and group metadata from __consumer_offsets-42 in 1 milliseconds. (kafka.coordinator.group.GroupMetadataManager)
[2019-08-23 17:14:57,617] INFO [GroupMetadataManager brokerId=0] Finished loading offsets and group metadata from __consumer_offsets-45 in 0 milliseconds. (kafka.coordinator.group.GroupMetadataManager)
[2019-08-23 17:14:57,682] INFO [GroupCoordinator 0]: Loading group metadata for test with generation 2 (kafka.coordinator.group.GroupCoordinator)
[2019-08-23 17:14:57,683] INFO [GroupMetadataManager brokerId=0] Finished loading offsets and group metadata from __consumer_offsets-48 in 66 milliseconds. (kafka.coordinator.group.GroupMetadataManager)

4、创建一个主题
打开第三个个终端

bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
Created topic "test".

可以通过list topic命令查看所有的主题

bin/kafka-topics.sh --list --zookeeper localhost:2181

test

或者,您也可以将代理配置为在发布不存在的主题时自动创建主题,而不是手动创建主题。

5、发送消息
Kafka带有一个命令行客户端,它将从文件或标准输入中获取输入,并将其作为消息发送到Kafka集群。默认情况下,每行将作为单独的消息发送。
启动生产者

bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test

输入几条消息发送到服务器

>hello
>kafka

6、启动消费者,消费者可以将消息转储到标准输出
打开第四个终端

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning

然后就可以在命令行看到生产者发送的消息了

hello
kafka

8、设置多个broker的集群
到目前为止,我们设置的是单个broker,这样并不好,下面我们还是在这一台机器上设置三个节点。

8.1 为每个broker创建一个配置文件

cp config/server.properties config/server-1.properties
cp config/server.properties config/server-2.properties

然后用vim修改 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

(其中listeners需要把前面的注释也就是#去掉)
broker.id是集群中每个节点唯一且永久的名称,因为我们实在同一个机器上运行这些文件,所以为了避免端口冲突和数据彼此覆盖,我们必须重写它的端口和日志目录。

8.2 启动新节点
我们已经启动了一个节点了(broker.id=0),现在启动两个新节点

bin/kafka-server-start.sh config/server-1.properties &
bin/kafka-server-start.sh config/server-2.properties &

8.3 创建三个副本的新主题:

bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic my-replicated-topic

运行describe topics查看主题的信息

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: 0	Replicas: 0,1,2	Isr: 0,1,2

下面解释一下这些输出,第一行是所有分区的摘要,另外的每一行是一个分区的信息,因为这个主题只有一个分区,所以只有一行。
leader:负责所有读和写,是这个分区从所有节点随机选择的。
replicas:是为这个分区复制日志的节点列表,无论他们是领导者还是他们现在还活着。
isr:是同步副本的集合,是还活着的副本的自己并被leader捕获(caught-up)。

在我的示例中节点0是该主题唯一分区的leader。
我们可以用相同的命令查看之前创建的主题 test

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

8.4 发送消息

bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-replicated-topic

my test message 1
my test message 2

8、5 消费消息

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic

my test message 1
my test message 2

8.6 测试容错及发现的问题
我的leader是节点0,现在kill掉

ps aux | grep server.properties

得到对应的进程号

root      9716  5.9 54.4 4276552 271584 pts/1  Sl+  17:14   0:28 java -Xmx1G -Xms1G -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -Djava.awt.headless=true -Xloggc:/home/vagrant/kafka_2.11-

然后kill掉第一个(第二个是grep命令本身的)

kill -9 4276552

kill掉之后再描述下topic

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: 0,1,2	Isr: 1,2

现在leader已经切换到节点1,Isr也只有节点1和2了

官网上说:但是即使原来的leader失败,这些消息仍然可用于消费,但是下面又有一些坑
首先执行下面这句

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic

发现会报错

[2018-05-22 03:55:13,304] WARN [Consumer clientId=consumer-1, groupId=console-consumer-29320] Connection to node -1 could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)