重要的配置文件: /opt/module/kafka/config/server.properties
#broker的全局唯一编号,不能重复.一台kafka服务器就是一个broker
broker.id=0
#删除topic功能使能
delete.topic.enable=true
#kafka运行日志存放的路径 (log也是存放topic的位置)
log.dirs=/opt/module/kafka/logs
#segment文件保留的最长时间,超时将被删除 (默认7天)
log.retention.hours=168
#配置连接Zookeeper集群地址
zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181
#文件大小达到1G后滚动.log文件,log文件以当前segment的第一条消息的offset命名
log.segment.bytes=1073741824
基础架构: consumer_group 消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响 一个topic的每个分区都有若干个副本,一个leader和若干个follower
启动集群: 依次在hadoop102、hadoop103、hadoop104节点上启动kafka ,指定配置文件 bin/kafka-server-start.sh -daemon config/server.properties
关闭集群: bin/kafka-server-stop.sh stop
kafka群起脚本略.
1.创建topic
bin/kafka-topics.sh --zookeeper hadoop102:2181 --create --replication-factor 3 --partitions 1 --topic first
-
生产者
bin/kafka-console-producer.sh --topic first --broker-list hadoop102:9092 -
消费者(保存offset到zk或本地) /从头消费
①.bin/kafka-console-consumer.sh --topic first --zookeeper hadoop102:2181 --from-beginning ②.bin/kafka-console-consumer.sh --topic first --bootstrap-server hadoop102:9092 (0.9版本后维护到本地)
存到本地,kafka的log文件下会有50个文件,代表50个分区,topic名是 _consumer_offset-,消费者消费数据时,会将offset写入_consumer_offset-的topic里,相当于这个topic的生产者
4.查看当前服务器中的所有topic
bin/kafka-topics.sh --zookeeper hadoop102:2181 --list
5.查看某个Topic的详情
bin/kafka-topics.sh --zookeeper hadoop102:2181 --describe --topic first
6.删除Topic
bin/kafka-topics.sh --delete --topic gx_topic --zookeeper hadoop102:2181
topic是逻辑上的概念,而partition是物理上的概念。每个partition对应于一个log文件,该log文件中存储的就是producer生产的数据 Kafka采取了分片和索引机制,将每个partition分为多个segment。每个segment对应两个文件——“.index”文件和“.log”文件。 这些文件位于一个文件夹下,该文件夹的命名规则为:topic名称+分区序号。例如,first这个topic有三个分区,则其对应的文件夹为first-0,first-1,first-2
生产者分区策略
将producer发送的数据封装成一个ProducerRecord对象。 (1)指明 partition 的情况下,直接将指明的值直接作为 partiton 值; (2)没有指明 partition 值但有 key 的情况下,将 key 的 hash 值与 topic 的 partition 数进行取余得到 partition 值; (3)既没有 partition 值又没有 key 值的情况下,第一次调用时随机生成一个整数(后面每次调用在这个整数上自增), 将这个值与 topic 可用的 partition 总数取余得到 partition 值,也就是常说的 round-robin 算法
数据可靠性保证
为保证producer发送的数据,能可靠的发送到指定的topic,topic的每个partition收到producer发送的数据后, 都需要向producer发送ack(acknowledgement确认收到),如果producer收到ack,就会进行下一轮的发送,否则重新发送数据
1)副本数据同步策略 1.全部完成同步,才发送ack ->选举新的leader时,容忍n台节点的故障,需要n+1个副本 2.Leader维护了一个动态的in-sync replica set (ISR),意为和leader保持同步的follower集合.当ISR中的follower完成数据的同步之后,leader就会给producer发送ack。 如果follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.lag.time.max.ms参数设定。Leader发生故障之后,就会从ISR中选举新的leader
ack应答机制
0:producer不等待broker的ack,这一操作提供了一个最低的延迟,broker一接收到还没有写入磁盘就已经返回,当broker故障时有可能丢失数据 1:producer等待broker的ack,partition的leader落盘成功后返回ack,如果在follower同步成功之前leader故障,那么将会丢失数据 -1(all):producer等待broker的ack,partition的leader和follower全部落盘成功后才返回ack。但是如果在follower同步完成后, broker发送ack之前,leader发生故障,那么会造成数据重复
故障处理细节
LEO:指的是每个副本最大的offset; HW:指的是消费者能见到的最大的offset,ISR队列中最小的LEO。 (1)leader发生故障之后,会从ISR中选出一个新的leader,之后,为保证多个副本之间的数据一致性,其余的follower会先将各自的log文件高于HW的部分截掉,然后从新的leader同步数据 (2)follower发生故障后会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次的HW,并将log文件高于HW的部分截取掉,从HW开始向leader进行同步。 等该follower的LEO大于等于该Partition的HW,即follower追上leader之后,就可以重新加入ISR了
这只能保证副本之间的数据一致性,并不能保证数据不丢失或者不重复
Kafka消费者
1)消费方式 consumer采用pull(拉)模式从broker中读取数据,push(推)模式很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的,pull模式则可以根据consumer的消费能力以适当的速率消费消息。 pull模式不足之处是,如果kafka没有数据,消费者可能会陷入循环中,一直返回空数据。针对这一点,Kafka的消费者在消费数据时会传入一个时长参数timeout, 如果当前没有数据可供消费,consumer会等待一段时间之后再返回,这段时长即为timeout。 2)分区分配策略 RoundRobin 前提:一个consumer group中有多个consumer订阅的主题是一样的, 因为roundrobin默认会把消费者组订阅的所有topic当做一个整体轮询给到所有的消费者,这样某些消费者可能会消费到他没订阅的topic的partition Range 以topic为单位分配分区,是kafka默认的消费者分区策略
offset的维护 Kafka 0.9版本之前,consumer默认将offset保存在Zookeeper中,从0.9版本开始,consumer默认将offset保存在Kafka一个内置的topic中,该topic为__consumer_offsets
维护在zk时, get /consumers/消费者组/offsets/topic名/partition号 (gtp)
维护在本地,修改配置文件consumer.properties exclude.internal.topics=false
0.11.0.0之后版本(含):
bin/kafka-console-consumer.sh --topic __consumer_offsets --zookeeper hadoop102:2181 --formatter "kafka.coordinator.group.GroupMetadataManager\$OffsetsMessageFormatter" --consumer.config config/consumer.properties --from-beginning
消费者组案例 修改/opt/module/kafka/config/consumer.properties配置文件中的group.id属性为任意组名
bin/kafka-console-consumer.sh --zookeeper hadoop102:2181 --topic first --consumer.config config/consumer.properties (指定配置文件)
Kafka 高效读写数据 顺序写磁盘 零复制技术(linux技术)
Zookeeper在Kafka中的作用 Kafka集群中有一个broker会被选举为Controller,负责管理集群broker的上下线,所有topic的分区副本分配和leader选举等工作
Kafka API
ProducerConfig ConsumerConfig CommonClientConfig
默认分区器 DefaultPartitioner
//byte[] keyBytes和 byte[] valueBytes是key,value序列化后得到的字节数组
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
if (keyBytes == null) {
...
轮询
// no partitions are available, give a non-available partition
return Utils.toPositive(nextValue) % numPartitions;
} else {
// hash the keyBytes to choose a partition
return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
}
Consumer API
Consumer消费数据时的可靠性是很容易保证的,因为数据在Kafka中是持久化的,故不用担心数据丢失问题。由于consumer在消费过程中可能会出现断电宕机等故障,consumer恢复后,需要从故障前的位置的继续消费,所以consumer需要实时记录自己消费到了哪个offset,以便故障恢复后继续消费。 所以offset的维护是Consumer消费数据是必须考虑的问题
数据漏消费和重复消费分析
无论是同步提交还是异步提交offset,都有可能会造成数据的漏消费或者重复消费。先提交offset后消费,有可能造成数据的漏消费;而先消费后提交offset,有可能会造成数据的重复消费
自定义存储offset
offset的维护是相当繁琐的,因为需要考虑到消费者的Rebalace。 当有新的消费者加入消费者组、已有的消费者推出消费者组或者所订阅的主题的分区发生变化,就会触发到分区的重新分配,重新分配的过程叫做Rebalance。 消费者发生Rebalance之后,每个消费者消费的分区就会发生变化。因此消费者要首先获取到自己被重新分配到的分区,并且定位到每个分区最近提交的offset位置继续消费
拦截器略.