Kafka 流数据缓冲存储工具
分布式 缓冲作用 限流削峰 异步 ,Scala 编写
基于发布-订阅模式的消息队列:一对多,消费者拉取数据之后不会清除数据
1. Kafka 架构
-
Producer 生产消息
-
Broker Kafka集群
- Topic 主题 消息分类
- Partition 分区
- Leader Follower 副本
-
Consumer 消费消息
- Consumer group :一个主题分区数据 只能 对应一个消费者组 提高消费能力
-
Zookeeper 注册消息
-
管理Kafka集群消息
-
0.9 版本之前 存储offset
-
Kafka 0.9 版本之后,offset 存储在本地
2. Kafka 安装
- 下载安装包
- 解压安装包
- 修改配置文件
server.properties
broker.id=0
delete.topic.enable=true
# kafka data dir
log.dirs=/opt/module/kafka_2.11-0.10.2.0/logs
# zk
zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181
- 分发Kafka,并修改broker.id的值
- 启动ZK
- 启动Kafka
bin/kafka-server-start.sh -daemon /opt/module/kafka_2.11-0.10.2.0/config/server.properties
- Jps查看进程
------hadoop102-------
2790 QuorumPeerMain
3850 Kafka
3931 Jps
------hadoop103-------
2635 Jps
2572 Kafka
1599 QuorumPeerMain
------hadoop104-------
2608 Jps
2545 Kafka
1574 QuorumPeerMain
3. Kafka Shell
3.1 topic
replication 数目 <= Broker 数目
# create topic
bin/kafka-topics.sh --create --zookeeper hadoop102:2181 --topic test2 --partitions 3 --replication-factor 1
# delete topic
bin/kafka-topics.sh --delete --topic test1 --zookeeper hadoop102:2181
# topic list
bin/kafka-topics.sh --list --zookeeper hadoop102:2181
# topic describe
bin/kafka-topics.sh --describe --topic test2 --zookeeper hadoop102:2181
3.2 producer
bin/kafka-console-producer.sh --topic test2 --broker-list hadoop102:9092
3.3 consumer
bin/kafka-console-consumer.sh --topic test2 --bootstrap-server hadoop102:9092
4. Kafka 重装
修改kafka 数据存放目录 log.dirs
- 删除 logs/ 目录
- 创建 data/ 目录
- 修改配置文件
- 删除zk zkData/version-2 目录
- 重启zk
- 重启kafka
5. Kafka 文件存储
- 一个Topic -> 多个Partition
- 一个Partition -> Segment
- 一个Segment -> xxx.log xxx.index
6. Kafka 生产者
- 分区策略
- 指定分区号,进入指定分区
- 没有分区号,指定K,按照 Key 的hash / partition 数,进入分区
- 都没有,轮询,进入分区
- 生产数据可靠性
-
ISR 机制 : ISR列表中的Leader 和所有 Follower 同步成功 才算成功,当 Follower 超过一定时间未发起拉取数据请求,则 Leader 把此 Follower 从ISR 移除
-
Acks机制
- 0:不管Leader 和Follower 状态 ,可能数据丢失
- 1:Leader 写完即返回,可能数据丢失
- -1 | all : ISR 的Leader 和 所有Follower 全部写完才返回 ,极小可能数据丢失,可能数据重复
- 消费数据一致性
- LEO:每个副本最大offset
- HW:消费者能见的最大的offset = ISR 最小 LEO
当Leader 挂了,新Leader 为了保证 数据存储一致性,截掉超过HW的部分
- Exactly Once 不能跨会话 <PID,Partition,SeqNumber>
Exactly Once = At Least Once + 幂等性(0.11)
7. Kafka 消费者
-
消费方式
pull 从broker拉取数据,问题:空数据
-
分区分配策略
当消费者组内消费者数目发生变化时触发,重新分配
- RoundRobin:TopicAndPartition 按照组划分【组内默认策略】
- Range:按照主题划分
-
Offset
Offset = Group + Topic + Partition
8. Kafka 高效读写
- 顺序写磁盘,节省寻址时间
- 零复制技术(页缓存技术)
9. Kafka 事务
生产者事务 跨会话,引入一个全局唯一用户定义好的一个 Transaction ID ,最终实现Exactly Once
10. Kafka API
10.1 Producer API
异步发送,和ACK没关系,涉及两个线程:main 和 sender ,经过 Interceptors -> Serializer -> Partitioner
- 简单生产者
package com.ipinyou.kafka.producer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;
public class ProducerDemo {
public static void main(String[] args) {
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "hadoop102:9092");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(props);
for (int i = 0; i < 10; i++) {
kafkaProducer.send(new ProducerRecord<String, String>("test2", "a"+i));
}
kafkaProducer.close();
}
}
- 带回调生产者
package com.ipinyou.kafka.producer;
import org.apache.kafka.clients.producer.*;
import java.util.Properties;
public class CallBackProducerDemo {
public static