一、Kafka
Kafka 是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域。
1.1 消息队列
MQ传统应用场景之异步处理
使用消息队列的好处
1)解耦
允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
2)可恢复性
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
3)缓冲
有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。
4)灵活性 & 峰值处理能力
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
5)异步通信
很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
1.2 消息队列的两种模式
(1)点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
消息生产者生产消息发送到Queue中,然后消息消费者从Queue中取出并且消费消息。
消息被消费以后,queue 中不再有存储,所以消息消费者不可能消费到已经被消费的消息。
Queue 支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。
(2)发布/订阅模式(一对多,消费者消费数据之后不会清除消息)
消息生产者(发布)将消息发布到 topic 中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不同,发布到 topic 的消息会被所有订阅者消费。
1.3 Kafka 基础架构
1)Producer :消息生产者,就是向 kafka broker 发消息的客户端;
2)Consumer :消息消费者,向 kafka broker 取消息的客户端;
3)Consumer Group (CG):消费者组,由多个 consumer 组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
4)Broker :一台 kafka 服务器就是一个 broker。一个集群由多个 broker 组成。一个 broker可以容纳多个 topic。
5)Topic :可以理解为一个队列,生产者和消费者面向的都是一个 topic;
6)Partition:为了实现扩展性,一个非常大的 topic 可以分布到多个 broker(即服务器)上,一个 topic 可以分为多个 partition,每个 partition 是一个有序的队列;
7)Replica:副本,为保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失,且 kafka 仍然能够继续工作,kafka 提供了副本机制,一个 topic 的每个分区都有若干个副本,一个 leader 和若干个 follower。
8)leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是 leader。
9)follower:每个分区多个副本中的“从”,实时从 leader 中同步数据,保持和 leader 数据的同步。leader 发生故障时,某个 follower 会成为新的 follower。
二、Kafka 快速入门
2.1 集群规划
hadoop101 | hadoop102 | hadoop103 |
---|---|---|
zk | zk | zk |
kafka | kafka | kafka |
2.2 jar 包下载
官网链接:https://kafka.apache.org/downloads.html.
1)安装包解压到linux或者直接linux上下载
[root@hadoop103 ~]# tar -zxvf kafka_2.12-3.0.0.tgz
[root@hadoop103 local]# mv kafka_2.12-3.0.0/ /usr/local/kafka
2)/usr/local/kafka 目录下创建 logs 文件夹
[root@hadoop103 kafka]# mkdir logs
3)修改配置文件
[root@hadoop103 kafka]# cd config/
[root@hadoop103 config]# vim server.properties
参考
#broker 的全局唯一编号,不能重复
broker.id=3
# 开启listeners
listeners=PLAINTEXT://ip地址:9092
#处理网络请求的线程数量
num.network.threads=3
#用来处理磁盘 IO 的现成数量
num.io.threads=8
#发送套接字的缓冲区大小
socket.send.buffer.bytes=102400
#接收套接字的缓冲区大小
socket.receive.buffer.bytes=102400
#请求套接字的缓冲区大小
socket.request.max.bytes=104857600
#kafka 运行日志存放的路径
log.dirs=/usr/local/kafka/logs
#topic 在当前 broker 上的分区个数
num.partitions=1
#用来恢复和清理 data 下数据的线程数量
num.recovery.threads.per.data.dir=1
#segment 文件保留的最长时间,超时将被删除
log.retention.hours=168
#配置连接 Zookeeper 集群地址
zookeeper.connect=hadoop101:2181,hadoop102:2181,hadoop103:2181
低版本种需要设置delete.topic.enable=true
#删除 topic 功能使能
delete.topic.enable=true
4)配置环境变量
[root@hadoop103 config]# sudo vim /etc/profile
# KAFKA_HOME
export KAFKA_HOME=/usr/local/kafka
export PATH=$PATH:$KAFKA_HOME/bin
5)分发安装包
[root@hadoop103 config]# rsync -r /usr/local/kafka root@192.168.182.143:/usr/local
[root@hadoop103 config]# rsync -r /usr/local/kafka root@192.168.182.144:/usr/local
分别在 hadoop101 和 hadoop102 上修改配置文件/usr/local/kafka/config/server.properties
中的 broker.id=1、broker.id=2以及配置环境变量
注:broker.id 不得重复
6)启动集群(hadoop101、hadoop102、hadoop103)
启动前先确定zookeeper集群已经启动,并且关闭防火墙
bin/kafka-server-start.sh config/server.properties
或
bin/kafka-server-start.sh -daemon config/server.properties
7)关闭集群
bin/kafka-server-stop.sh stop
8)kafka 群起关脚本
如果Kafka的默认/usr/bin/java路径与我们实际的$JAVA_HOME/bin/java路径不一致的话。就需要给jdk配置软链接
软链接可参考改博客:https://blog.csdn.net/xiaminli/article/details/73381562.
[root@hadoop101 bin]# echo $JAVA_HOME
/usr/local/jdk1.8.0_311
[root@hadoop101 bin]# ln -s /usr/local/jdk1.8.0_311/bin/java /usr/bin/java
脚本参考
#!/bin/bash
case $1 in
"start"){
for i in hadoop101 hadoop102 hadoop103
do
echo "========== $i kafka 启动 =========="
ssh $i "/usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties"
done
};;
"stop"){
for i in hadoop101 hadoop102 hadoop103
do
echo "========== $i kafka 关闭 =========="
ssh $i "/usr/local/kafka/bin/kafka-server-stop.sh stop"
done
};;
esac
2.3 Kafka 命令行操作
1)查看当前服务器中的所有 topic
高版本已经不支持bin/kafka-topics.sh --zookeeper hadoop101:2181 --list
[root@hadoop101 kafka]# bin/kafka-topics.sh --list --bootstrap-server 192.168.182.143:9092
2)创建 topic
[root@hadoop101 kafka]# bin/kafka-topics.sh --create --partitions 1 --replication-factor 1 --topic quickstart-events --bootstrap-server 192.168.182.143:9092
选项说明:
–topic 定义 topic 名
–replication-factor 定义副本数
–partitions 定义分区数
显示使用信息
[root@hadoop101 kafka]# bin/kafka-topics.sh --describe --topic quickstart-events --bootstrap-server 192.168.182.143:9092
Topic: quickstart-events TopicId: 7oU1qo1FRgCC48hBrS0JFQ PartitionCount: 1 ReplicationFactor: 1 Configs: segment.bytes=1073741824
Topic: quickstart-events Partition: 0 Leader: 1 Replicas: 1 Isr: 1
可以到zookeeper种查看一下
3)删除 topic
[root@hadoop101 kafka]# bin/kafka-topics.sh --bootstrap-server 192.168.182.143:9092 --delete --topic quickstart-events
低版本需要 server.properties 中设置 delete.topic.enable=true 否则只是标记删除。
delete.topic.enable=true ; auto.create.topics.enable=false ; 只有这两个参数同时开启,kafka-manager才可以将某个topic删除干净。
auto.create.topics.enable意思是:produce可以推送消息到一个不存在的topic(即:发消息到一个不存在的topic,系统会帮你按默认参数自动帮你建立这个topic),所以只要这个topic有produce向它推送消息,那么这个topic你是没办法被删除的。
4)将一些事件写入主题
[root@hadoop101 kafka]# bin/kafka-console-producer.sh --topic quickstart-events --bootstrap-server 192.168.182.143:9092
>This is my first event
>This is my second event
Ctrl+c终止
5)阅读事件
[root@hadoop101 kafka]# bin/kafka-console-consumer.sh --topic quickstart-events --from-beginning --bootstrap-server 192.168.182.143:9092
This is my first event
This is my second event
–from-beginning:会把主题中以往所有的数据都读取出来。
6)修改分区数
[root@hadoop101 kafka]# bin/kafka-topics.sh --bootstrap-server 192.168.182.143:9092 --alter --topic quickstart-events --partitions 6
[root@hadoop101 kafka]# bin/kafka-topics.sh --describe --topic quickstart-events --bootstrap-server 192.168.182.143:9092
Topic: quickstart-events TopicId: aNUicMWzRP2VINaJnToxjg PartitionCount: 6 ReplicationFactor: 1 Configs: segment.bytes=1073741824
Topic: quickstart-events Partition: 0 Leader: 1 Replicas: 1 Isr: 1
Topic: quickstart-events Partition: 1 Leader: 1 Replicas: 1 Isr: 1
Topic: quickstart-events Partition: 2 Leader: 1 Replicas: 1 Isr: 1
Topic: quickstart-events Partition: 3 Leader: 1 Replicas: 1 Isr: 1
Topic: quickstart-events Partition: 4 Leader: 1 Replicas: 1 Isr: 1
Topic: quickstart-events Partition: 5 Leader: 1 Replicas: 1 Isr: 1
三、Kafka中的关键细节
1.消息的顺序存储
消息的发送⽅会把消息发送到broker中,broker会存储消息,消息是按照发送的顺序进⾏存储。因此消费者在消费消息时可以指明主题中消息的偏移量。默认情况下,是从最后⼀个消息的下⼀个偏移量开始消费。
2.单播消息的实现
单播消息:⼀个消费组⾥ 只会有⼀个消费者能消费到某⼀个topic中的消息。于是可以创建多个消费者,这些消费者在同⼀个消费组中
bin/kafka-console-consumer.sh --topic group --bootstrap-server 192.168.182.143:9092 --consumer-property group.id=testGroup
3.多播消息的实现
在⼀些业务场景中需要让⼀条消息被多个消费者消费,那么就可以使⽤多播模式。kafka实现多播,只需要让不同的消费者处于不同的消费组即可。
bin/kafka-console-consumer.sh --topic group --bootstrap-server 192.168.182.143:9092 --consumer-property group.id=testGroup1
bin/kafka-console-consumer.sh --topic group --bootstrap-server 192.168.182.143:9092 --consumer-property group.id=testGroup2
4.查看消费组及信息
# 查看当前主题下有哪些消费组
bin/kafka-consumer-groups.sh --bootstrap-server 192.168.182.143:9092 --list
# 查看消费组中的具体信息:⽐如当前偏移量、最后⼀条消息的偏移量、堆积的消息数量
bin/kafka-consumer-groups.sh --bootstrap-server 192.168.182.144:9092 --describe --group testGroup1
Currennt-offset: 当前消费组的已消费偏移量
Log-end-offset: 主题对应分区消息的结束偏移量(HW)
Lag: 当前消费组未消费的消息数
四、主题、分区的概念
图:此示例主题有四个分区 P1–P4。两个不同的生产者客户端通过网络将事件写入主题的分区,彼此独立地向主题发布新事件。具有相同键的事件(在图中由它们的颜色表示)被写入同一个分区。请注意,如果合适的话,两个生产者都可以写入同一个分区。
1.主题Topic
主题Topic可以理解成是⼀个类别的名称。
2.partition分区
分区的作⽤:
可以分布式存储
可以并⾏写