kafka架构:
kafka应用场景:
1)大数据领域
2)数据集成
3)流计算集成
kafka消息生产者发送消息是批量发送,默认是16Kb发送一次
pros.put("batch.size", 16384) #16kb
批量发送等待时间
pros.put("linger.er", 5)
若5秒钟内未到达16kb也发送,批量发送时间和发送等待时间满足一个即可发送
kakfa消息生产者只支持pull模式获取消息
原因:因为kafka使用于大量消息处理,在大量消息发送到broker中时若使用push模式推送消息给消息消费者,很容易由于消息生产者达到消费能力极限,导致消费者宕机
kafka消费者一次活动多少条消息可配置:
conusmer.poll(Duration.ofMillis(1000)) #默认每次获取1000条消息
生产者和消费者通过topic关联
kafka消息在服务器上默认的存储位置:/tmp/kafka-logs
每个分区有一套文件:.index文件、.log文件、.timeindex文件
具体消息存储在.log文件内,消息会不断追加到.log文件内不会删除(和rabbitmq不同,rabbitmq中消费过的消息会被删除)
这样做的好处:可以实现顺序写(针对一个分区),速度高;提供了消费历史消息的能力
kafka topic 可分区 partition
注意:
- kafka启动时,设置副本数量不可比节点broker数量大,否则会报错
不同节点中副本有不同的角色(leader节点、fellow节点)只有leader才提供读(消费者读)写(生产者写)功能,fellow节点只有备份功能
为什么kafka的设计不实现不同节点读写分离功能:
避免了读写一致性问题
.log文件达到阈值kafka会对文件进行分段segment,每个segment会有一条文件(index文件、.log文件、.timeindex文件)
阈值大小:log.sement.bytes = 1G
同一个kafka消息消费者组内的消费者不会同时消费同一个topic下相同的partition的消息;当消费者数量大于partition数量时,多余的消费者没有可以消费的partition;当partition数量大于消费者数量时,消费者组中某个消费者可以消费多个partition
consumer offset:用于记录消费者消费消息的位置,保存在_consumer_offset-0(存储了某一个partition和某一个消费者消费消息的偏移量也就是位置)
kafka防止消息重复消费问题(幂等),消息生产者配置开关:
kafka只能保证一次会话里针对单个partition的消息幂等
props.put("enable.idempotence", true)
在broker会生成幂等标志
kafka针对过个分区的幂等(kafka的事务,保证多消息的原子性):
解释: 保证多个消息同时成功或者同时失败
事务消息使用场景:
1、发送多条消息
2、发送消息到多个topic或者多个partition
3、消费以后发出消息 consume-process-produce(解释:从一个上游系统接收消息,同时又将消息发送到一个下游系统)
代码实现(伪代码):
#初始化事务
producer.initTransactions();
try{
#开启事务
producer.beginTransaction()
producer.send();
producer.send();
...
#提交事务
producer.commitTransaction()
} catch(KafkaException e){
#终止事务
producer.abortTransaction()
}
#应用于上面场景3(消费以后发出消息)
producer.sendOffsetsToTransaction()
producer.close();
kafka事务原理:
分布式事务的思想:2pc ,3pc, TCC
1、kafka应用了分布式事务里的两阶段思想:第一阶段是预提交,第二阶段才是真正的提交,
2、两阶段必须需要一个协调者的角色(Transaction Coordinator: 在kafka服务端)
3、事务日志:topic_transaction_state,当服务异常等极端情况kafka服务重启以后,会通过查找事务日志检查每一个事务状态(topic_transaction_state),处理未完成的事务消息。
4、生产者事务ID:transaction.id,极端情况下生成者挂了事务发送执行到一半,当生产者重启时,服务当如何判断是哪一个事务就是通过生产者事务ID来判断的
网友评论