kafka

kafka 管道,分布式流 消息系统
特点:
消息持久化:通过o(1)的磁盘数据结构提供数据的持久化。
对磁盘的顺序访问,操作系统的预读和后写比对内存的随机访问还要快
搞吞吐量:每秒百万级的消息读写
分布式:扩展能力强
多客户端支持
实时性:生产者生产的message立即被消费者可见。 kafka的数据单位:message
kafka的目标:成为一个队列平台,不仅支持离线,还支持在线。

kafka基本组件
Broker:每一台机器叫一个Broker
Producer:消息生产者,用来写数据
Consumer:消息的消费者,用来读数据
Topic:不同消费者去指定的Topic中读,不同的生产者往不同的Topic中写。消息的类型
Partition:在Topic基础上做了进一步区分分层
topic是一个逻辑概念,partition是一个物理实现--以文件夹的形式存在。一个Topic是由一个或多个Partition实现的,不太好保证消息的顺序性,在同一个partition内是顺序的。
kafka内部是分布式的,一个kafka集群通常包含多个broker
负载均衡:将Topic分成多个分区(Partition),每个Broker存储一个或多个Partition
多个Producer和Consumer同时生产和消费消息

zk只存Broker和Consumer的信息;Producer写数据的时候可以指定往哪个Broker上写,不需要zk帮助分发。
producer和broker之间不存在负载均衡,consumer和broker之间存在负载均衡--zookeeper;负载均衡,出现个别节点不稳定,会提现rebalance机制
producer和broker之间:push模式
consumer和broker之间:pull模式

topic
一个Topic是一个用于发布消息的分类或feed名,kafka集群使用分区的日志,每个分区都是有顺序且不变的消息序列。物理上不同的topic分开存储,但是用户不需要关心。消息根据key取模落到不同的partition中。
commit的log可以不断追加,消息在每个分区中都分配一个叫offset的id序列来唯一识别分区中的消息
可以把topic近似想象成一个队列queue,发送一个消息,或者消费一个消息,必须明确指定topic
多个partition,并发,吞吐率线性提高
kafka把更多的主导权交给了消费者(client来保存各自的offset)
无论发布的消息是否被消费,kafka都会持久化一定时间(可配置 默认7天)
在每个消费者都持久化这个offset在日志中。通常消费者读消息时会是offset值线性的增长,但实际上其位置是有消费者控制,它可以按任意顺序来消费信息。比如复位到老的offset来重新处理
每个分区代表一个并行单元。

Message是通信的基本单位,每个producer可以向一个topic主题发布一些消息。如果consumer订阅了这个主题,那么新发布的消息就会广播给这些consumer

Producer
生产者可以发布数据到它指定的topic中,并可以指定在topic里哪些消息分配到哪些分区(比如简单的轮流分发各个分区或通过指定分区语义分配key到对应分区)
生产者直接把消息发送给对应分区的broker,而不需要任何路由层
批处理发送,当message积累到一定数量或等待一定时间后进行发送

Consumer
一种更抽象的消费方式:消费组(consumer group)
该方式包含了传统的queue和发布订阅方式
– 首先消费者标记自己一个消费组名。消息将投递到每个消费组中的某一个消费者实例上。
– 如果所有的消费者实例都有相同的消费组,这样就像传统的queue方式。
– 如果所有的消费者实例都有不同的消费组,这样就像传统的发布订阅方式。
– 消费组就好比是个逻辑的订阅者,每个订阅者由许多消费者实例构成(用于扩展或容错)。
相对于传统的消息系统, kafka拥有更强壮的顺序保证。
由于topic采用了分区,可在多Consumer进程操作时保证顺序性和负载均衡。
一个partition同时只能给一个consumer读数据

持久化
kafka存储布局简单:Topic的每个Partition对应一个逻辑日志;Partition对应一个或多个Segment文件
每次生产者发布消息到一个分区,代理就将消息追加到最后一个segment文件中
与传统的消息系统不同,kafka系统中存储的消息没有明确的消息id
消息通过日志中的逻辑偏移量开公开

传输效率
生产者提交一批消息最为一个请求,消费者虽然利用api遍历消息是一个一个的,但背后也是一次请求获取一批数据,从而减少网络请求数量
kafka层采用无缓存设计,而是依赖于底层的文件系统页缓存。这有助于避免双重缓存,即消息只缓存了一份在页缓存中。同时这在kafka重启后保存缓存warm也有额外的优势。因kafka不缓存消息在进程中,故gc开销很小

无状态的broker
kafka代理是无状态的:意味着消费者必须维护已消费的状态信息,。这些信息由消费者自己维护,代理完全不管。
–从代理删除消息变得很棘手,因为代理并不知道消费者是否已经使用了该消息。 Kafka将一个简单的基于时间的SLA应用于保留策略。当消息在代理中超过一定时间后,将会被自动删除。
– 这种创新设计有很大的好处,消费者可以故意倒回到老的偏移量再次消费数据。这违反了队列的常见约定,但被证明是许多消费者的基本特征。

交付保证
Kafka默认采用at least once的消息投递策略。即在消费者端的处理顺序是获得消息->处理消息->保存位置。这可能导致一旦客户端挂掉,新的客户端接管时处理前面客户端已处理过的消息
三种保证策略:
– At most once 消息可能会丢,但绝不会重复传输
– At least one 消息至少发送一次,消息绝不会丢,但可能会重复传输
– Exactly once 每条消息肯定会被传输一次且仅传输一次

副本管理
kafka将日志(数据)复制到指定多个服务器上
针对partition副本管理,如果有f+1个broker,允许挂掉f个
副本的单元是partition,在正常情况下,每个分区有一个leader和0到多个follower
leader处理对应分区上所有的读写请求,分区可以多于broker数,leader也是分布式的。
follower的日志和leader的日志是相同的,follower被动的复制leader。如果leader挂了,其中一个follower会自动变成新的leader
ISR(In-Sync Replicas):kafka在zk动态维护了一个set(里面表示的所有副本,都是跟上了leader的节奏)
ISR里副本需要删除的两种情况:1、消息延迟 2、数据落后太多
replica.lag.max.messages如果设为4,表名follower不能落后于leader超过3个消息,否则从ISR中删除

分布式协调
由于kafka中一个topic中的不同分区只能被消费组中的一个消费者消费,就避免了多个消费者消费相同的分区时会导致额外的开销(如要协调哪个消费者消费哪个消息,还有锁及状态的开销)。 kafka中消费进程只需要在代理和同组消费者有变化时时进行一次协调(这种协调不是经常性的,故可以忽略开销)
kafka使用zookeeper做以下事情:
– 探测broker和consumer的添加或移除
– 当1发生时触发每个消费者进程的重新负载。
– 维护消费关系和追踪消费者在分区消费的消息的offset。

zookeeper的使用
Broker Node Registry
• /brokers/ids/[0...N] --> host:port (ephemeral node)
– broker启动时在/brokers/ids下创建一个znode,把broker id写进去。
– 因为broker把自己注册到zookeeper中实用的是瞬时节点,所以这个注册是动态的,如果broker宕机或者没有响应该节点就会被删除。
Broker Topic Registry
• /brokers/topics/[topic]/[0...N] --> nPartions (ephemeral node)
– 每个broker把自己存储和维护的partion信息注册到该路径下
Consumers and Consumer Groups
– consumers也把它们自己注册到zookeeper上,用以保持消费负载平衡和offset记录。
– group id相同的多个consumer构成一个消费租,共同消费一个topic,同一个组的consumer会尽量均匀的消费,其中的一个consumer只会消费一个partion的数据。
Consumer Id Registry
• /consumers/[group_id]/ids/[consumer_id] --> {"topic1": #streams, ...,"topicN": #streams} (ephemeral node)
– 每个consumer在/consumers/[group_id]/ids下创建一个瞬时的唯一的consumer_id,用来描述当前该group下有哪些consumer是alive的,如果消费进程挂掉对应的consumer_id就会从该节点删除
Consumer Offset Tracking
• /consumers/[group_id]/offsets/[topic]/[partition_id] -->offset_counter_value ((persistent node)
– consumer把每个partition的消费offset记录保存在该节点下。
Partition Owner registry
• /consumers/[group_id]/owners/[topic]/[broker_id-partition_id] -->consumer_node_id (ephemeral node)
– 该节点维护着partion与consumer之间的对应关系

posted on   何苦->  阅读(69)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示