目录
what is kafka?
Kafka是一个分布式消息队列。
在流式(实时数据)计算中,Kafka一般用来缓存数据,Storm通过消费Kafka的数据进行计算。storm:实时 hadoop离线
一、基本概念
1、消费者:(Consumer):从消息队列中请求消息的客户端应用程序
2、生产者:(Producer) :向broker发布消息的应用程序
3、AMQP服务端(broker):kafka集群有多个kafka实例组成,每个实例(server)成为broker。
二、Kafka架构
生产者生产消息、kafka集群、消费者获取消息这样一种架构,如下图:
kafka集群中的消息,是通过Topic(主题)来进行组织的,如下图:
一些基本的概念:
1、主题(Topic):理解为一个队列。一个主题类似新闻中的体育、娱乐、教育等分类概念。
2、分区(Partition):一个Topic多个分区组织,分区是kafka消息队列组织的最小单位,一个分区可以看作是一个FIFO( First Input First Output的缩写,先入先出队列)的队列。
kafka分区是提高kafka性能的关键所在,当你发现你的集群性能不高时,常用手段就是增加Topic的分区,分区里面的消息是按照从新到老的顺序进行组织,消费者从队列头订阅消息,生产者从队列尾添加消息。
工作图:
zookeeper注册消息,注册kafaka以及consumer信息
为什么使用kafka
1)解耦 2)冗余 3)扩展性:
4)灵活性 & 峰值处理能力:
客户端A、B读写速度可能不一样
如果数据很多,需要多个客户端接收者。例如双十一,数据量过大,需要增加机器读取保存数据,但是双十一过后,数据量就不是很大,增加的机器没有用了,成本高。
所以有消息队列,中间商,不用考虑读写速度,数据量大的时候增加broker,不用的时候卸载。
5)可恢复性 6)顺序保证 7)缓冲 8)异步通信:
(1)点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
点对点模型通常是一个基于拉取或者轮询的消息传送模型,这种模型从队列中请求信息,而不是将消息推送到客户端。这个模型的特点是发送到队列的消息被一个且只有一个接收者接收处理,即使有多个消息监听者也是如此。
(2)发布/订阅模式(一对多,数据生产后,推送给所有订阅者)
发布订阅模型则是一个基于推送的消息传送模型。发布订阅模型可以有多种不同的订阅者,临时订阅者只在主动监听主题时才接收消息,而持久订阅者则监听主题的所有消息,即使当前订阅者不可用,处于离线状态。
三、Kafka集群部署
kafka需要事先搭建zookeeper集群,这里不过多介绍
1、解压kafka安装包至/root/app下,在kafka下创建一个文件夹logs
2、修改config/下配置文件server.properties
###为必须修改的
###broker的全局唯一编号,不能重复
broker.id=0
###删除topic功能使能
delete.topic.enable=true
#处理网络请求的线程数量
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=/root/apps/kafka/logs
#topic在当前broker上的分区个数
num.partitions=1
#用来恢复和清理data下数据的线程数量
num.recovery.threads.per.data.dir=1
#segment文件保留的最长时间,超时将被删除
log.retention.hours=168
###配置连接Zookeeper集群地址
zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181
3、启动集群 &是后台运行,也可以先前台然后ctrl+z,bg
[root@hdp-1 kafka]$ bin/kafka-server-start.sh config/server.properties &
关闭进程:
bin/kafka-server-stop.sh
4、脚本实现启动Kafka集群
启动集群start-allkafka.sh
#!/bin/bash
APPHOME="/root/apps/"
APP_NAME="kafka_2.11-2.3.0"
for i in hdp-1 hdp-2 hdp-3
do
echo "Starting ${APP_NAME} on ${i} "
ssh ${i} "source /etc/profile;nohup sh /root/apps/kafka_2.11-2.3.0/bin/kafka-server-start.sh /root/apps/kafka_2.11-2.3.0/config/server.properties > /dev/null 2>&1 &"
if [[ $? -ne 0 ]]; then
echo "Starting ${APP_NAME} on ${i} is ok"
fi
done
echo All $APP_NAME are started
exit 0
停止集群 stop-allkafka.sh
#!/bin/bash
APPHOME="/root/apps/"
APP_NAME="kafka_2.11-2.3.0"
for i in hdp-1 hdp-2 hdp-3
do
echo "Stoppting ${APP_NAME} on ${i} "
ssh ${i} "source /etc/profile;bash /root/apps/kafka_2.11-2.3.0/bin/kafka-server-stop.sh"
if [[ $? -ne 0 ]]; then
echo "Stopping ${KAFKA_HOME} on ${i} is down"
fi
done
echo All $APP_NAME are stopped
exit 0
四、Kafka命令行操作
1、创建topic
--topic 定义topic名
--replication-factor 定义副本数
--partitions 定义分区数
[root@hdp-1 kafka_2.11-2.3.0]# bin/kafka-topics.sh --create --zookeeper hdp-1:2181 --replication-factor 3 --partitions 1 --topic first
2、查看所有topic
bin/kafka-topics.sh --list --zookeeper hdp-1:2181
3、删除topic
bin/kafka-topics.sh --delete --zookeeper hdp-1:2181 --topic first
4、发送消息
[root@hdp-1 bin]# kafka-console-producer.sh --broker-list hdp-1:9092 --topic xin
>hello wangyouxiu
5、消费消息
[root@hdp-2 kafka_2.11-2.3.0]# bin/kafka-console-consumer.sh --topic xin --bootstrap-server hdp-1:9092 --from-beginning
6、查看topic详情
[root@hdp-1 bin]# kafka-topics.sh --zookeeper hdp-1:2181 --describe --topic xin
Topic:xin PartitionCount:1 ReplicationFactor:3 Configs:
Topic: xin Partition: 0 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
四、Message理解
每个partition存储一部分Message,Message由一个固定长度的header和一个变长的消息体body组成
header部分由一个字节的magic(文件格式)和四个字节的CRC32(用于判断body消息体是否正常)构成。当magic的值为1的时候,会在magic和crc32之间多一个字节的数据:attributes(保存一些相关属性,比如是否压缩、压缩格式等等);如果magic的值为0,那么不存在attributes属性
body是由N个字节构成的一个消息体,包含了具体的key/value消息
存储在磁盘的日志采用不同于Producer发送的消息格式,每个日志文件都是一个“log entries”序列,每一个log entry包含一个四字节整型数(message长度,值为1+4+N),一个字节的magic,四个字节的CRC32值,最终是N个字节的消息数据。每条消息都有一个当前Partition下唯一的64位offset,指定该消息的起始下标位置,存储消息格式如下: