Kafka()

特点

  • 存取消息
  • 临时存储消息

应用场景

  • 异步处理
  • 系统解耦
  • 流量削峰(kafka单机吞吐量10w+,mysql单机只有几千)
  • 日志处理

模型

  • 生产者、消费者

两种模式

  • 点对点(一条消息只能被一个消费者消费)
  • 发布订阅(一条消息被多个消费者消费)

kafka集群必须有zookeeper

topic(主题):逻辑结构,类似mysql表,我们要在一个主题上存取数据

RabbitMQ 更适合业务异步解耦

RocketMQ 更适合金融事务场景

Kafka 更适合高吞吐日志流与实时计算

消费者组:将若干个消费者组合在一起,共同消费kafka中topic的数据

消费者组中活跃消费者数量小于等于topic分区数量

一个topic的一个分区只能由一个消费者消费,防止顺序混乱

消费者从kafka拉取数据需要offset

poll() 机制能保证你的程序在没活干时优雅地睡觉,有活干时瞬间起跳。

使用异步方式生产消息

  • 在发送消息出现异常时,能够及时打印出异常信息
  • 在发送消息成功时,打印kafka的topic名字,分区id,offset

同步:send(消息对象) future.get():阻塞等待返回

异步:send(消息对象,回调函数)

重要概念

  • broker
    一个kafka集群通常由多个broker组成,这样才能实现负载均衡
    无状态,通过zk来维护集群状态
    一个kafka的broker每秒可以处理数十万次读写,每个broker都可以处理TB消息而不影响性能

Kafka幂等性

两个概念

  • PID:每个Producer在初始化时,都会分配一个唯一PID,这个PID对用户透明
  • Sequence Number:针对每个生产者(对应PID)发送到指定主题分区的消息都对应一个从0开始递增的Sequence Number

问题:

生产者 retry 导致消息重复写入

解决:

Kafka Broker 会为每个 (PID, Partition)

维护一个期望的 seq(expectedSeq)。

只有当消息的 seq == expectedSeq 时,

Broker 才会接收并写入消息。

分区和副本机制

生产者分区写入策略

  • 轮询分区策略(默认)
    使用最多的策略,最大限度保证所有消息分配到一个分区
    如果生产消息时,key为null,则使用轮训算法均匀地分配分区
  • 随机分区策略
  • 按key分区分配策略
    根据key的hashcode取模,可以保证同一个key放入相同的分区
  • 自定义分区策略

乱序问题:

轮询分区策略会导致分区内有序,分区间顺序不保证

key分区可以缓解乱序问题,但会导致数据倾斜

实际中应该根据业务选择合适策略

消费者组的Rebalance机制

再均衡,确保消费者组下所有的consumer如何达成一致,分配订阅的topic的每个分区的机制

触发时机:

1、消费者组中消费者的个数发生变化

3、订阅的topic发生变化(本质还是分区改变了)

2、订阅的topic发生分区变化

再均衡不良影响:

消费者组中所有消费者都会协调在一起共同参与,kafka使用分配策略尽可能达到最公平的分配

过程会对消费者组产生非常严重的影响,所有消费者停止工作,直到再均衡完成

消费者分区分配策略

Range范围分配策略(默认)

确保每个消费者组的分区数量是均衡的(rangle范围分配策略针对每个topic)

RoundRobin轮询策略

按照字典序排序(topic和分区的hashcode进行排序),然后通过轮询方式逐个将分区以此分配给每个消费者

粘性分配策略

1、分区尽可能均匀

2、在发生再均衡的时候,分区的分配尽可能与上一次分配保持相同(非全局分配而是局部调整)

副本机制

冗余备份,当某个broker上的分区数据丢失时,依然保证数据可用性,因为其他的broker上的副本是可用的

生产者的acks参数

0:不等待broker确认,直接发送下一条数据,性能最高,可能存在数据丢失问题

1:等待leader副本确认接收后,才会发送下一条数据,性能中等

-1(all):等待所有副本已经将数据同步后,才会发送下一条数据,性能最差

根据业务选择合适参数

分区中有leader和follower概念,为了确保消费者消费的数据是一致的,只能从分区leader去读写消息,follower的事情就是同步数据

API

高级API

直接让kafka帮助管理、处理分配、数据管理

不控制offset,不能从指定位置读取

不能细化控制分区、副本、ZK等

低级API

编写程序自己控制逻辑

自己控制offset,能自定义实现功能,实现复杂

可以指定消费者的topic分区,消费特定数据分区

监控工具Kafka-eagle

监控管理工具

Kafka原理

分区的leader与follower

针对分区(partition)

自动将leader均匀地分配在不同broker中

leader负责读写,follower负责备份(容灾),还有重新选举

leader出现故障,会在follower会选举新leader

AR、ISR、OSR

leader挂掉之后需要选取新的leader

AR(assigned Replicas):分区的所有副本

ISR(In-sync-replicas):所有与leader副本保持一定程度同步的副本

OSR(Out-of-Sync-replicas):同步滞后过多的副本(或者挂掉的follow副本)

leader选举

如何确定某个partition是leader、哪个partition是follower:

随机选取,尽量均匀

某个leader崩溃了如何快速确定另外一个leader:

因为kafka吞吐量高、延迟低,选取一定要快

选取范围:ISR

controller:启动时在所有broker中选择一个controller

  • 所有partition的leader选举都由controller决定
  • controller会将leader的改变直接通过RPC的方式通知对应Broker
  • 通过ISR,选择存活备份,否则随便选,如果备份全宕机,新leader为-1

leader负载均衡

preferred replica:优先副本

生产、消费数据工作流程

生产者优先找到对应分区的leader

先找leader,采用拉模式(默认从最新数据读取)

数据存储形式

  • 一个topic由多个分区组成
  • 一个分区由多个segment组成
  • 一个segment由多个文件组成
    • log:存储数据
    • index:存储offset索引(稀疏索引)
    • timeindxe:存储时间索引

LEO:log-end-offerset日志最后的offset(下一条待写入消息的offset)

定期清理

消息默认7天后开始清理,一次删除一个segment段的日志文件

kafka日志管理器,根据kafka配置,决定那些文件可以被删除

消息不丢失机制

生产者数据不丢失

通过多个副本,leader副本挂了,可以在ISR集合中快速选出新leader副本

生产者数据不丢失

ACK机制,设置为all(-1):保证所有副本数据同步后返回确认

发送数据两种方式:同步(等待ack返回)、异步(提供一个回调函数)

消费者数据不丢失

只要每个消费者记录好offset值即可

消息丢失:自动提交的offset容易出现(消费数据失败,offset已经变化(存在zk中))

重复消费:自动提交offset时,更新zk中offset失败

解决:使用低级api,直接手动管理offset,不将offset存入zk而是从mysql拉取(通过事务保证消息和offset的原子性)

消息传递的语义

at-most-once:最多一次(只管把数据消费到,不管有没有成功,可能会有数据丢失)

at-least-once:最少一次(有可能出现重复消费)

exactly-once:仅有一次(事务性的保障,保证消息有且仅被处理一次)

数据积压

虽然很快,但是网络拥堵,外部IO(消费者进程)也会导致积压,破坏数据实时性

问题一:partition不够

解决:增加partition,增加消费者

问题二:消费者消费慢

解决:一次拉取多条数据,批量操作;通过线程池处理任务

问题三:消费者挂了(比如fullGC)

解决:恢复消费者

问题四:Rebalance 导致暂停消费

解决:增量式rebalance(新版)

问题五:下游故障(mysql挂了,不提交offset)

解决:恢复mysql

避免:监控指标(出现积压赶紧排查问题)

kafka数据清理

日志删除:按照指定的策略直接删除不符合条件的日志

日志压缩:按照消息的key进行整合,有相同key的但有不同value值,只保留最后一个版本

混合模式

以segment为单位进行定期清理

定时删除日志:

  • 基于时间的保留策略
    默认保存7天(168小时)
  • 基于日志大小的保留策略
  • 基于日志起始偏移量的保留策略

kafka事务

幂等性只能保证单次会话幂等性

生产者挂了,重试(新会话,新PID)

解决:引入全局唯一TransactionID

并将PID和TransactionID绑定

当生产者挂了,通过TransactionID拿到自己之前的PID

通过:Transaction coordinator组件管理

消费者事务:不保证,自己保证

相关推荐
此时不提桶,更待何时11 小时前
06-23-A-RabbitMQ生态集成详解
分布式·rabbitmq
m0_6464299716 小时前
RabbitMQ 核心知识总结(生产实战版)
分布式·rabbitmq
DBA_G18 小时前
GBase 8c分布式数据库客户端工具 gsql
数据库·分布式
chunyublog18 小时前
Spark 词频统计练习
大数据·分布式·spark
ClouGence19 小时前
开源数据库管理工具 CloudDM 4.4.0 发布,新增 Kafka、SAP HANA 数据源
数据库·kafka
acrel720 小时前
高速公路分布式光伏并网电能质量与安全保护方案应用
分布式·安全
RobinXYuan20 小时前
【Kafka 源码手记】01 从消息队列到 Event Streaming
kafka·源码阅读
IT小小猪21 小时前
# Hadoop 3.3.6 完全分布式集群部署知识库
hadoop·分布式·eclipse
此时不提桶,更待何时1 天前
06-24-B-RabbitMQ面试与生产事故实战
分布式·面试·rabbitmq
来福猿1 天前
分布式锁 Redis 实现源码分析:SETNX、过期时间与可重入设计
数据库·redis·分布式