Kafka详解

Kafka是一种分布式的、基于发布/订阅的消息缓存系统。(依赖于zookeeper)

一、特性:

  • 消息持久化
  • 高吞吐量,每秒百万级
  • 扩展能力强
  • 支持多种语言
  • 实时性:生产者的message立即被消费者可见

 

二、要点:

1、kafka是一个分布式的消息缓存系统。

2、kafka集群中的服务器都叫做broker。

3、kafka有两类客户端,一类叫producer(消息生产者),一类叫做consumer(消息消费者),客户端和broker服务器之间采用TCP协议连接。

4、kafka中不同业务系统的消息可以通过topic进行区分(partition),而且每一个消息topic都会被分区,以分担消息读写的负载。

5、每一个分区都可以有多个副本,以防止数据的丢失。

6、某一个分区中的数据如果需要更新,都必须通过该分区所有副本中的leader来更新。

7、消费者可以分组,比如有两个消费者组A和B,消费同一个topic,A和B各自消费各自的消息,互不影响。但是,在同一个消费者组下的不同消费者的消费是互补的。

8、消费者在具体消费某个topic中的消息时,可以指定起始偏移量。

 

三、基本组件详解:

Broker每台机器叫一个broker,也即当前服务器上的Kafka进程,只管数据存储,不管是谁生产,不管是谁消费。且Kafka代理(broker)是无状态的,即代理并不知道消费者是否已经使用了该消息,当消息在代理中超过一定时间后,将会被自动删除。集群中每个broker都有一个唯一broker_id,不得重复。

Producer消息生产者,数据的分发策略由producer决定,默认是defaultPartition  Utils.abs(key.hashCode) % numPartitions。生产者可以发布数据到指定的topic中,并可以指定在topic中哪些消息分配到哪些分区。生产者直接把消息发送给对应分区的broker,而不需要任何路由层。批处理发送:当message积累到一定数量或等待一定时间后进行发送。

Consumer消息消费者

ConsumerGroup:数据消费者组,ConsumerGroup可以有多个,每个ConsumerGroup消费的数据都是一样的。可以把多个consumer线程划分为一个组,组里面所有成员共同消费一个topic的数据,组员之间不能重复消费。

Topic不同的消费者去指定topic中读,不同的生产者向不同topic中写。这是一个逻辑上的概念,落到磁盘上是一个partition的目录。partition的目录中有多个segment组合(index,log)。一个Topic对应多个partition[0,1,2,3…],一个partition对应多个segment组合。一个segment有默认的大小是1G。每个partition可以设置多个副本(replication-factor 1),会从所有的副本中选取一个leader出来。所有读写操作都是通过leader来进行的。特别强调,在kafka中读写操作都是leader。无论发布的消息是否被消费,kafka都会持久化一定时间(可配置,默认7天)每个消费者都会持久化offset到日志中,且offset的位置由消费者控制。

Partition在topic基础上做了进一步区分,partition是一个磁盘目录。

 

Kafka内部是分布式的,一个kafka集群通常有多个broker。

负载均衡:将topic分成多个分区,每个broker存储一个或多个partition,如果Broker数大于Partition数,那么有Broker中没有对应的Partition;如果Broker小于Partition数,Broker中会存在多个Partition。

多个producer和consumer同时生产和消费消息。

 

四、consumerGroup的组员和partition之间如何做负载均衡?

最好是一一对应,一个partition对应一个consumer。

如果某consumer group中consumer数量少于partition数量,则至少有一个consumer会消费多个partition的数据,如果consumer的数量与partition数量相同,则正好一个consumer消费一个partition的数据,而如果consumer的数量多于partition的数量时,会有部分consumer无法消费该topic中任何一条消息。实际上,Kafka保证的是稳定状态下每一个Consumer实例只会消费某一个或多个特定Partition的数据,而某个Partition的数据只会被同一个消费组中某一个特定的Consumer实例所消费。

每一个consumer实例都属于一个consumer group,每一条消息只会被同一个consumer group里的一个consumer实例消费。(不同consumer group可以同时消费同一条消息)

 

五、如何保证kafka消费者消费数据是全局有序的?

伪命题。如果要全局有序的,必须保证生产有序,存储有序,消费有序。由于生产可以做集群,存储可以分片,消费可以设置为一个consumerGroup,要保证全局有序,就需要保证每个环节都有序。只有一个可能,就是一个生产者,一个partition,一个消费者。这种场景和大数据应用场景相悖。

 

六、持久化

Topic的每个partition对应一个逻辑日志。

每次生产者发布消息到一个分区,代理就将消息追加到最后一个段文件中。当发布的消息数量达到设定值或者经过一定的时间后(可配置),一段文件真正flush到磁盘中,写入完成后,消息公开给消费者。

partition内部是有一个真正落地的数据,这个数据叫segment,用多个segment去把这个大的segment给它拆分,这样的话比如说我先写1号segment,写完之后再写2号segment,2号写完了写3号。当查询历史数据时,通过offset在segment中用二分查找

与传统的消息系统不同,kafka系统中存储的消息没有明确的消息id。消息通过日志中的逻辑偏移量来公开。

 

七、传输效率

生产者提交一批消息作为一个请求,消费者虽然是一个一个遍历消息,但背后也是一次请求获取一批数据,从而减少网络请求数量。

Kafka不缓存消息在进程中,而是依赖于底层的文件系统页缓存,故GC开销很小。

 

八、kafka如何保证数据的完全生产(producer

ack机制:broker表示发来的数据已确认接收无误,表示数据已经保存到磁盘。通过初始化producer时的producerconfig可以通过配置request.required.acks不同的值来实现。

0:不等待broker返回确认消息

1:等待topic中某个partition leader保存成功的状态反馈

-1:等待topic中某个partition 所有副本都保存成功的状态反馈

 

九、数据传输保证

Kafka默认采用at least once的消息投递策略。

三种保证策略:

at most once:消息可能会丢,但不会重复传输

at least once:消息不会丢,但可能会重复传输

exactly once:每条消息仅传输一次

 

十、副本管理

Kafka将日志复制到多个服务器,副本的单元是partition,每个分区都有一个leader和0到多个follower,Leader处理分区上的所有读写请求,leader也是分布式的,leader的日志和follower的日志是相同的,且follower是被动复制,如果leader挂了,其中一个follower自动变成新的leader。

 

十一、Zookeeper在kafka中的作用

1、探测broker和consumer的添加和移除

2、当1发生时,触发每个消费者进程的重新负载

3、维护消费关系和追踪消费者在分区消费信息的offset

 

Zookeeper具体使用:

1、broker启动时在/brokers/ids下创建一个临时节点znode,把broker id写进去,broker宕机或没响应该节点就会被删除。

2、每个Broker会把自己存储和维护的partition信息注册到/broker/topics/…路径下。

3、consumers也会在zookeeper上注册临时节点,用以保持消费负载平衡和offset记录。

4、每个consumer在/consumers/[group_id]/ids下创建一个临时consumer_id,用来描述当前group下哪些consumer是alive的。

5、group id相同的多个consumer构成一个消费组,共同消费一个topic,并尽量消费均衡。

 

十二、消息传递过程

Producer在发布消息到某个Partition时,先通过Zookeeper找到该Partition的Leader,然后无论该Topic的Replication Factor为多少(也即该Partition有多少个Replica),Producer只将该消息发送到该Partition的Leader。Leader会将该消息写入其本地Log。每个Follower都从Leader pull数据。这种方式上,Follower存储的数据顺序与Leader保持一致。Follower在收到该消息并写入其Log后,向Leader发送ACK。一旦Leader收到了ISR中的所有Replica的ACK,该消息就被认为已经commit了,Leader将增加HW(即offset)并且向Producer发送ACK。

为了提高性能,每个Follower在接收到数据后就立马向Leader发送ACK,而非等到数据写入Log中。因此,对于已经commit的消息,Kafka只能保证它被存于多个Replica的内存中,而不能保证它们被持久化到磁盘中,也就不能完全保证异常发生后该条消息一定能被Consumer消费。但考虑到这种场景非常少见,可以认为这种方式在性能和数据持久化上做了一个比较好的平衡。在将来的版本中,Kafka会考虑提供更高的持久性。Consumer读消息也是从Leader读取,只有被commit过的消息(offset低于HW的消息)才会暴露给Consumer。

具体步骤总结下来如下:

1. producer 先从 zookeeper 的 "/brokers/.../state" 节点找到该 partition 的 leader

2. producer 将消息发送给该 leader

3. leader 将消息写入本地 log

4. followers 从 leader pull 消息,写入本地 log 后向leader 发送 ACK

5. leader 收到所有 ISR 中的 replica 的 ACK 后,增加 HW(high watermark,最后 commit 的 offset)并向 producer 发送 ACK

 

十三、Kafka和flume的区别和联系:

1.kafka做日志缓存, flume偏向于数据采集,flume可以定制很多数据源,减少开发量。所以比较流行flume+kafka模式。                         如果为了利用flume写hdfs的能力,可以采用kafka+flume的方式实现从Kafka到Hadoop的流数据,配置Kafka为Source读取数据,就没有必要实现自己的消费者。直接利用Flume与HDFS及HBase的结合的所有好处。使用Cloudera Manager对消费者的监控,甚至可以添加拦截器进行一些流处理。

2.Kafka和Flume都是可靠的系统,通过适当的配置能保证零数据丢失。然而,Flume不支持副本事件。如果Flume代理的一个节点崩溃了,即使使用了可靠的文件管道方式,你也将丢失这些事件,直到你恢复这些磁盘。如果你需要一个高可靠行的管道,那么使用Kafka是个更好的选择。

十四、Kafka和redis的区别

1. redis是内存数据库,只是它的list数据类型刚好可以用作消息队列而已;kafka是消息队列,消息的存储模型只是其中的一个环节,还提供了消息ACK和队列容量、消费速率等消息相关的功能。

2. redis 发布订阅除了表示不同的 topic 外,并不支持分组。kafka每个consumer属于一个特定的consumer group(default group), 同一topic的一条消息只能被同一个consumer group内的一个consumer消费,但多个consumer group可同时消费这一消息,这样可以用作负载均衡。

3. redis消息推送(基于分布式 pub/sub)多用于实时性较高的消息推送,并不保证可靠,redis-pub/sub断电就清空。其他的mq和kafka保证可靠但有一些延迟(非实时系统没有保证延迟)。

4. 处理数据大小的级别不同。

  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值