Kafka 2.5.0
1. 简介
Kafka是一个实时数据处理系统,可以横向扩展、高可靠,而且还很快,已经被很多公司使用。
实时数据处理系统就是数据一旦产生,就要能快速进行处理的系统。
对于实时数据处理,我们最常见的,就是消息中间件了,叫MQ(Message Queue,消息队列),也有叫Message Broker的。
消息中间件指利用高效可靠的消息传递机制进行平台无关的数据交流,主要有两点作用:
- 解耦消息的生产和消费。
- 缓冲。
2. 基本概念
消息
Kafka的数据单元被称为消息。可以把消息看成是数据库里的一个“数据行”或一条“记录”。消息由字节数组组成,所以对于Kafka 来说,消息里的数据没有特别的格式或含义。
批次
批次就是一组消息,这些消息属于同一个主题和分区。如果每一个消息都单独穿行于网络,会导致大量的网络开销,把消息分成批次传输可以减少网络开销。
模式
对于Kafka来说,消息不过是晦涩难懂的字节数组,所以有人建议用一些额外的结构来定义消息内容,让它们更易于理解。根据应用程序的需求,消息模式(schema)有许多可用的选项。像JSON 和XML这些简单的系统,不仅易用,而且可读性好。不过,它们缺乏强类型处理能力,不同版本之间的兼容性也不是很好。
Kafka的许多开发者喜欢使用Apache Avro,它最初是为Hadoop开发的一款序列化框架。Avro提供了一种紧凑的序列化格式,模式和消息体是分开的,当模式发生变化时,不需要重新生成代码。
主题
Kafka的消息通过主题进行分类。主题可以被分为若干个分区,一个分区就是一个提交日志。消息以追加的方式写入分区,然后以先入先出的顺序读取。由于一个主题一般包含几个分区,因此无法在整个主题范围内保证消息的顺序,但可以保证消息在单个分区内的顺序。
下图中所示的主题有4个分区,消息被追加写入每个分区的尾部。Kafka通过分区来实现数据冗余和伸缩性。
分区可以分布在不同的服务器上,也就是说,一个主题可以横跨多个服务器,以此来提供比单个服务器更强大的性能。
分区
每个Topic由多个分区组成,每个分区内部的数据保证了有序性,即是按照时间序列,append到分区的尾部。分区是有固定大小的,容量不够时,会创建新的分区。Kafka在一定时间内会定期清理过期的文件。
这种连续性的文件存储,一方面有效的利用磁盘的线性存取;另一方面减轻了内存的压力。
生产者
生产者创建消息。一般情况下,一个消息会被发布到一个特定的主题上。
生产者在默认情况下把消息均衡地分布到主题的所有分区上,而并不关心特定消息会被写到哪个分区。
不过,在某些情况下,生产者会把消息直接写到指定的分区。这通常是通过消息键和分区器来实现的,分区器为键生成一个散列值,并将其映射到指定的分区上。这样可以保证包含同一个键的消息会被写到同一个分区上。
生产者也可以使用自定义的分区器,根据不同的业务规则将消息映射到分区。
消费者
消费者读取消息。消费者订阅一个或多个主题,并按照消息生成的顺序读取它们。
消费者通过检查消息的偏移盘来区分已经读取过的消息。偏移量是另一种元数据,它是一个不断递增的整数值,在创建消息时,Kafka会把它添加到消息里。在给定的分区里,每个消息的偏移量都是唯一的。消费者把每个分区最后读取的消息偏移量保存在Zookeeper或Kafka 上,如果消费者关闭或重启,它的读取状态不会丢失。
消费者是消费者群组的一部分,会有一个或多个消费者共同读取一个主题。群组保证每个分区只能被一个消费者使用。
下图中,有3个消费者同时读取一个主题。其中的两个消费者各自读取一个分区,另外一个消费者读取其他两个分区。
消费者与分区之间的映射通常被称为消费者对分区的所有权关系。通过这种方式,消费者可以消费包含大量消息的主题。而且,如果一个消费者失效,群组里的其他消费者可以接管失效消费者的工作。
Broker
一个独立的Kafka服务器被称为Broker。
Broker接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存。
Broker为消费者提供服务,对读取分区的请求作出响应,返回已经提交到磁盘上的消息。
根据特定的硬件及其性能特征,单个Broker可以轻松处理数千个分区以及每秒百万级的消息量。
Broker是集群的组成部分。每个集群都有一个Broker同时充当了集群控制器的角色(自动从集群的活跃成员中选举出来)。控制器负责管理工作,包括将分区分配给Broker和监控Broker。
在集群中,一个分区从属于一个Broker,该Broker被称为分区的首领;一个分区可以分配给多个Broker,这个时候会发生分区复制。这种复制机制为分区提供了消息冗余,如果有一个Broker失效,其他Broker可以接管领导权。不过,相关的消费者和生产者都要重新连接到新的首领。
3. 安装
Zookeeper 单机及集群安装
启动Zookeeper。Kafka虽有自带Zookeeper,这里并没有使用。
3.1 单机
修改 conf/server.properties
配置Zookeeper
修改目录路径log.dirs,需要先创建该日志文件夹
前台启动
bin/kafka-server-start.sh config/server.properties
后台启动
bin/kafka-server-start.sh -daemon config/server.properties
测试
创建主题
用一个分区和一个副本创建一个名为 test 的主题
bin/kafka-topics.sh --create \
--bootstrap-server localhost:9092 \
--replication-factor 1 \
--partitions 1 \
--topic test
--replication-factor
:每一个分区的副本数量
--partition
:分区数
查看所有主题
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
启动生产者
Kafka带有一个命令行客户端,它将从文件或标准输入中获取输入,并将其作为消息发送到Kafka集群。默认情况下,每行将作为单独的消息发送。启动生产者,然后在控制台中键入一些消息以发送到服务器。
bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic test
启动消费者
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
--from-beginning
:从头消费
查看主题描述
bin/kafka-topics.sh -describe --bootstrap-server localhost:9092 --topic test
删除主题
bin/kafka-topics.sh --bootstrap-server localhost:9092 --delete --topic test
停止
bin/kafka-server-stop.sh
3.2 集群
伪集群,创建kafka-cluster文件夹,在一台虚拟机上启动3个kafka实例,组成集群。
复制单机版安装包,修改 config/server.properties
修改broker.id
修改监听端口listeners
topic的分区数和分区复制改成3
修改目录路径log.dirs,然后清空logs文件夹。
再复制修改kafka-2,kakfa-3,修改broker.id为2和3,监听端口为9093和9094。
新增启动脚本
vi start-all.sh
cd kafka-1
./bin/kafka-server-start.sh -daemon ./config/server.properties
cd ..
cd kafka-2
./bin/kafka-server-start.sh -daemon ./config/server.properties
cd ..
cd kafka-3
./bin/kafka-server-start.sh -daemon ./config/server.properties
chmod u+x start-all.sh
新增停止脚本
vi stop-all.sh
cd kafka-1
./bin/kafka-server-stop.sh
cd ..
cd kafka-2
./bin/kafka-server-stop.sh
cd ..
cd kafka-3
./bin/kafka-server-stop.sh
chmod u+x stop-all.sh
由于启动过上面单机的Kafka,并且和集群Kafka用的同一个Zookeeper,所以要清空Zookeeper中Kafka创建的目录。
测试
创建topic
bin/kafka-topics.sh --create --bootstrap-server 192.168.110.40:9092 --topic test-3
查看主题描述
bin/kafka-topics.sh -describe --bootstrap-server 192.168.110.40:9092 --topic test-3
该主题有3个分区,3个分区复制。
Leader
:负责给定分区的所有读取和写入的节点,每个节点将成为分区的随机选择部分的领导者。
Replicas
:为该分区复制日志的节点列表,无论它们是引导者还是当前处于活动状态。
Isr
:是“同步”副本的集合。这是副本列表的子集,当前仍处于活动状态并追随Leader。
启动生产者
bin/kafka-console-producer.sh --bootstrap-server 192.168.110.40:9092 --topic test-3
启动两个消费者
bin/kafka-console-consumer.sh --bootstrap-server 192.168.110.40:9093 --topic test-3 --from-beginning
bin/kafka-console-consumer.sh --bootstrap-server 192.168.110.40:9094 --topic test-3 --from-beginning
两个消费者都会消费生产者的消息
启动分组的消费者
bin/kafka-console-consumer.sh --bootstrap-server 192.168.110.40:9093 --topic test-3 --from-beginning --group test-3-group
bin/kafka-console-consumer.sh --bootstrap-server 192.168.110.40:9094 --topic test-3 --from-beginning --group test-3-group
--group
:消费组为 test-3-group
两个消费者一个组,消息只会消费一次。
测试高可用
kill掉分区0的Leader
分区0的Leader变成2
参考:
Kafka 官方快速开始
Kafka 权威指南
Kafka 简明教程
搭建kafka及zookeeper集群