1.Kafka是一个分布式的消息缓存系统(与stome的区别)
2.Kafka集群中的服务器都叫broker
3.Kafka又两类客户端,一类叫producer(消息生产者),一类叫consumer(消息消费者),客户端和broker服务器之间采用tcp协议连接
4.Kafka中不同业务系统的消息可以通过topic进行区分,而且每一个消息的topic都会被分区,以分担消息读写的负载
5.每一个分区都可以有多个副本,以防止数据丢失
6.某一个分区中的数据如果需要更新,都必须通过分区所有副本中leader来更新
7.消费者可以分组,同一组中的消费者不能同事消费同一个消息,比如有两个消费者A和B,属于同一组,他们共同消费一个topic:order_info中的100个消息,那A消费的消息与B消费的消息不会重复,如A消费1~49,B消费50~99.
8.消费者在具体消费某个topic中消息时,可以指定起始偏移量。
一 Kafka安装及部署
1.首先,Kafka是一个集群,所以他需要依赖Zookeeper,部署的时候一般要三台机器才算是一个集群,那我们具体部署如下:
Hadoop01 Hadoop02 Hadoop03
ZK ZK ZK
Kafka Kafka Kafka
2.下载好Kafka 后,首先是解压
tar -zxvf kafka_2.7.3-0.11.tgz -C /hadoop/app
mv kafka_2.7.3-0.11/ kafka
然后在kafka目录下创建 logs文件,该文件会在后续配置文件中配置,用于log的存放
mkdir logs
修改配置文件
cd kakfa
vi server.properties
然后输入如下内容:
为了能更好的进行命令操作,可以配置下环境变量
3.将配置好的Kafka copy到另外两台机器
scp -r kafka hadoop@hadoop02:/home/hadoop/app
复制到另外两台机器后,还要注意Hadoop02 和Hadoop03的Kafka配置文件,home/hadoop/app/kafka/config/server.properties中的 broker.id=1,broker.id=2;
注意,broker.id是唯一的,不能重复
4.配置好后就可以去启动集群
注意,启动集群前,要先启动zookeeper。启动后就可以按照官方文档去操作了(读写)
5.关闭集群
如果觉得这样启动比较麻烦,可以自行去写一个启动脚本与关闭脚本
二.Kafka常见的命令操作(所有的命令都是在kafka路径下操作)
1.查看当前服务器中所有的topic
bin/kafka-topics.sh --zookeeper hadoop01:2181 --list
2.创建topic(创建一个名为first的topic,其中分区2个,副本3个)
bin/kafka-topic.sh --zookeeper hadoop01:2181 --create --replication-factor 3 --partitions 2 --topic first
3.删除topic
bin/kafka-topics.sh --zookeeper hadoop01:2181 --delete --topic first
注意:需要server.properties中设置delete.topic.enable=true才能删除,否则只是标记删除
4.发送消息
bin/kafka-console-producer.sh --broker-list hadoop01:9092 --topic first
此命令就是创建一个生产者,其中对应的topic为 first,创建好后,此时就可以输入要发送的消息
5.消费消息
bin/kafka-console-consumer.sh --zookeeper hadoop01:2181 --topic first --from-beginning
此命令是创建一个消费者,需要注意的是这个是在基于zookeeper上的消费者是在0.9之前的版本,在0.9之后的Kafka版本的offset是存在broker里面,所有0.9之后的启动方式为
bin/kafka-console-consumer.sh --bootstrap-server hadoop01:9092 --from-beginning --topic first
其中 --from-beginning 会从最初的消息开始读,如果不加则是从当前收到的消息开始读
6.查看某个topic的详情
bin/kafka-topics.sh --zookeeper hadoop01:2181 --describe --topic first
7.修改分区(将topic first修改成6个分区)
bin/kafka-topics.sh --zookeeper hadoop01:2181 --alter --topic first --partitions 6
存储文件
1.partation分区是属于物理概念,Topic是属于逻辑概念,Kafka中生产者传入的数据存入在partation分区中(一般在/logs/分区名称-num中的.log文件)如图:其中.index文件为索引文件,.log文件就是存储数据的文件,该文件的大小可以在server.properties(log.segment.bytes)里面配置,当写入的文件超过这个值后就会重新生成一个新的.log文件,命名以偏移量来命名。
由于生产者产生的消息会不断追加到log文件末尾,为了防止log文件过大导致数据定位效率低,kafka采取分片和索引机制,将每个partation分为多个segment,每个segment对应两个文件--“.index"和".log"文件,这些文件位于同一个文件夹下,命名规制topic名称+分区序列号,例如first这个topic有三个分区,则其对应的文件夹为first-0,first-1,firsr-2
.log文件与.index文件对应如上图,index中存了每条消息的起始偏移量以及消息长度大小,以便后续获取相关数据
Kafka 分区策略
生产者数据的可靠性保证(基于TCP机制)
为了保证producer发送数据能可靠的发送到指定的topic,topic的每个partition收到producer发送的数据后都需要向producer发送ack(acknowledgement 确认收到),如果producer收到ack,就会进行下一轮的发送,否则重新发送数据。
当producer发送完数据给topic的partition后,topic会进行副本同步,只有在全部副本同步完后topic才会发送ack给producer。
ISR
假设以下情景:leader收到数据,所有的follower都开始同步数据,但是有一个follower因为某种故障,迟迟不能与leader进行同步,那leader就要一直等下去,直到它同步完成,才能发送ack,这个问题怎么解决?
Leader维护了一个动态的in-sync replica set(ISR),意为和leader保持同步的follower集合,当ISR中的follower完成数据的同步值后,leader就会给follower发送ack,如果follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.lag.time.max.ms参数设定,Leader发生故障后,会从ISR中选举新的leader
ACK 应答机制
对于某些不太重要的数据,对数据的可靠性要求不是很高,能容忍数据的少量丢失,所有没有必要等ISR中的follower全部接收成功后再发送ack.所有Kafka为用户提供了三种可靠性级别,用户根据对可靠性和延迟的要求进行权衡选择配置。
acks的具体参数配置如下:
0:producer不等待broker的ack,数据是一条一条的发,完全不管borker是否接收到数据,这个操作提供了一个最低的延迟,broker一接收到还没写入磁盘就已经返回,这个的缺点是当broker故障时有可能丢失数据
1:producer等待broker的ack,只有当partition的leader落盘成功后返回ack,缺点是在follower同步成功之前leader故障,那么就会丢失数据。
-1(all):producer等待broker的ack,待partition的leader和follower全部落盘成功后返回ack,但是如果在follower同步完成后,broker发送ack之前,leader发生故障,那么就会造成数据重复(producer会从新发送数据)。
故障处理
LEO:指的是每个副本最大的offset;
HW:指的是消费者能见到的最大的offset,ISR 队列中最小的LEO
1)follower 故障
follower发生故障后会被踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次的HW,并将log文件高鱼HW的部分截取掉,从HW开始向leader进行同步。等该follower的LEO大于等于该partition的HW,即follower追上leader之后,就可以从新加入ISR了。
2)Leader故障
leader发生故障之后,会从ISR中选出一个新的leader,之后,为保证多个副本之间数据一致性,其余follower会先将各自的log文件高于HW的部分截掉,然后从新的leader同步数据。
注意:这个只能保证副本与leader之间的数据一致性,并不能保证数据不丢失或者不重复。