kafka原理详细介绍

Kafka

      Apache Kafka是分布式发布-订阅消息系统。它最初由LinkedIn公司开发,之后成为Apache项目的一部分。Kafka是一种快速、可扩展的、设计内在就是分布式的,分区的和可复制的提交日志服务。

先给大家看下这幅图,让大家脑子里对kafka流程有个大致的印象

             

接下来这幅图就是比较细分的流程图了


      首先kafka中的所有broker都要去zookeeper中注册,选举出一个leader出来,这个leader是临时的,而其它的broker则为follower,这些follower受到leader领导,这时候就有问题了,zookeeper可以有很多台,这些zookeeper给broker投票,谁的票数多谁就是leader,但有可能同时有多个broker得到相同的票数,所以zookeeper的数量只能为单数,比如1,3,5台,也有人说zookeeper和broker数量一样怎么办?这里有一个zookeeper选举机制,能保证选出一台leader,有兴趣的话可以自己去看,假如leader出现异常后,这时候所有的broker又会一起去zookeeper中注册,再选出一台leader出来,如果是所有的broker都没问题同时去注册,那么和上面一样选出一个来,如果是一个个去注册的话,那么第一个就是leader,所有的数据操作都要经过leader。

     producer发送数据到leader的partition中,消息是以队列的方式push推送的,每个partition对应一个逻辑log,由多个segment组成,而消费者是以组的形式pull拉取的,接着这里有问题了,就会有多种情况出现

     1.只有一个消费者组:

一个partition只能被某个consumer消费,那么该partition就不会被其它的consumer消费了

             

      2. 多个消费者组

     如果有多个消费者组的话,那么每个partition都能被每个消费者组消费,如果消费者组中消费者的数量比partition少,那么就只能消费多个。简单来说就是假如有四块石头(partition),有两组和尚分别去搬,第一组有四个和尚,每个人只要搬一块,而第二组只有两个和尚,每个人要搬两块,压力就大多了

            

这里也有一个问题,假如消费者的数量比partition的多怎么办?

 就会有一个消费者不干活,为了避免这种情况出现,所以我们设置时消费者的数量要小于或等于partition的数量

                    


   broker中的topic分区形式:

                                

  topic的partition中数据的偏移量形式:

                                     

     每个Partition中的消息都是有序的,生产的消息被不断追加到Partition log上,其中的每一个消息都被赋予了一个唯一的offset值。

     Kafka集群会保存所有的消息,不管消息有没有被消费;我们可以设定消息的过期时间,只有过期的数据才会被自动清除以释放磁盘空间。比如我们设置消息过期时间为2天,那么这2天内的所有消息都会被保存到集群中,数据只有超过了两天才会被清除。

    Kafka需要维持的元数据只有一个–消费消息在Partition中的offse值,

    Consumer每消费一个消息,offset就会加1。其实消息的状态完全是由Consumer控制的,Consumer可以跟踪和重设这个offset值,这样的话Consumer就可以读取任意位置的消息。

     把消息日志以Partition的形式存放有多重考虑,第一,方便在集群中扩展,每个Partition可以通过调整以适应它所在的机器,而一个topic又可以有多个Partition组成,因此整个集群就可以适应任意大小的数据了;第二就是可以提高并发,因为可以以Partition为单位读写了。


Kafka的特性

        1. 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒

        2. 可扩展性:kafka集群支持热扩展

        3. 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失

        4. 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)

        5. 高并发:支持数千个客户端同时读写

Kafka架构

    它的架构包括以下组件:

        Topic(话题):是特定类型的消息流。消息是字节的有效负载(Payload),话题是消息的分类名或种子(Feed)名。 

        Producer(生产者):是能够发布消息到话题的任何对象。

        Broker(服务代理):Kafka 集群包含一个或多个服务器,这种服务器被称为 broker。(每一个broker都有一个唯一的id,这是一个非负整数,这个id就是broker的"名字",这样就允许broker迁移到别的机器而不会影响消费者。你可以选择任意一个数字,只要它是唯一的。)

        Consumer(消费者):可以订阅一个或多个话题,并从Broker拉数据,从而消费这些已发布的消息,向 Kafka broker 读取消息的客户端。

        Partition(分区):Partition 是物理上的概念,每个 Topic 包含一个或多个 Partition。


Kafka 交互流程

        Kafka 是一个基于分布式的消息发布-订阅系统,它被设计成快速、可扩展的、持久的。与其他消息发布-订阅系统类似,Kafka 在主题当中保存消息的信息。生产者向主题写入数据,消费者从主题读取数据。由于 Kafka 的特性是支持分布式,同时也是基于分布式的,所以主题也是可以在多个节点上被分区和覆盖的。

        信息是一个字节数组,程序员可以在这些字节数组中存储任何对象,支持的数据格式包括 String、JSON、Avro。Kafka 通过给每一个消息绑定一个键值的方式来保证生产者可以把所有的消息发送到指定位置。属于某一个消费者群组的消费者订阅了一个主题,通过该订阅消费者可以跨节点地接收所有与该主题相关的消息,每一个消息只会发送给群组中的一个消费者,所有拥有相同键值的消息都会被确保发给这一个消费者。

        Kafka 设计中将每一个主题分区当作一个具有顺序排列的日志。同处于一个分区中的消息都被设置了一个唯一的偏移量。Kafka 只会保持跟踪未读消息,一旦消息被置为已读状态,Kafka 就不会再去管理它了。Kafka 的生产者负责在消息队列中对生产出来的消息保证一定时间的占有,消费者负责追踪每一个主题 (可以理解为一个日志通道) 的消息并及时获取它们。基于这样的设计,Kafka 可以在消息队列中保存大量的开销很小的数据,并且支持大量的消费者订阅。

  

Kafka存储策略

    1. kafka以topic来进行消息管理,每个topic包含多个partition,每个partition对应一个逻辑log,由多个segment组成。

    2. 每个segment中存储多条消息,消息id由其逻辑位置决定,即从消息id可直接定位到消息的存储位置,避免id到位置的额外映射。 

    3. 每个part在内存中对应一个index,记录每个segment中的第一条消息偏移。

    4. 发布者发到某个topic的消息会被均匀的分布到多个partition上(或根据用户指定的路由规则进行分布),broker收到发布消息往对应partition的最后一个segment上添加该消息,当某个segment上的消息条数达到配置值或消息发布时间超过阈值时,segment上的消息会被flush到磁盘,只有flush到磁盘上的消息订阅者才能订阅到,segment达到一定的大小后将不会再往该segment写数据,broker会创建新的segment。


Kafka一些重要设计思想

        1. Consumergroup:各个consumer可以组成一个组,每个消息只能被组中的一个consumer消费,如果一个消息可以被多个consumer消费的话,那么这些consumer必须在不同的组。

        2. 消息状态:在Kafka中,消息的状态被保存在consumer中,broker不会关心哪个消息被消费了被谁消费了,只记录一个offset值(指向partition中下一个要被消费的消息位置),这就意味着如果consumer处理不好的话,broker上的一个消息可能会被消费多次。

        3. 消息持久化:Kafka中会把消息持久化到本地文件系统中,并且保持极高的效率。

        4. 消息有效期:Kafka会长久保留其中的消息,以便consumer可以多次消费,当然其中很多细节是可配置的。

        5. 批量发送:Kafka支持以消息集合为单位进行批量发送,以提高push效率。

        6. push-and-pull :Kafka中的Producer和consumer采用的是push-and-pull模式,即Producer只管向broker push消息,consumer只管从broker pull消息,两者对消息的生产和消费是异步的。

        7. Kafka集群中broker之间的关系:不是主从关系,各个broker在集群中地位一样,我们可以随意的增加或删除任何一个broker节点。

        8. 负载均衡方面: Kafka提供了一个 metadata API来管理broker之间的负载(对Kafka0.8.x而言,对于0.7.x主要靠zookeeper来实现负载均衡)。

        9. 同步异步:Producer采用异步push方式,极大提高Kafka系统的吞吐率(可以通过参数控制是采用同步还是异步方式)。

        10.分区机制partition:Kafka的broker端支持消息分区,Producer可以决定把消息发到哪个分区,在一个分区中消息的顺序就是Producer发送消息的顺序,一个主题中可以有多个分区,具体分区的数量是可配置的。分区的意义很重大,后面的内容会逐渐体现。

        11.离线数据装载:Kafka由于对可拓展的数据持久化的支持,它也非常适合向Hadoop或者数据仓库中进行数据装载。

        12.插件支持:现在不少活跃的社区已经开发出不少插件来拓展Kafka的功能,如用来配合Storm、Hadoop、flume相关的插件。


复制(Replication

        1. 一个partition的复制个数(replication factor)包括这个partition的leader本身。

        2. 所有对partition的读和写都通过leader。

        3. Followers通过pull获取leader上log(message和offset)

        4. 如果一个follower挂掉、卡住或者同步太慢,leader会把这个follower从”insync replicas“(ISR)列表中删除。

        5. 当所有的”in syncreplicas“的follower把一个消息写入到自己的log中时,这个消息才被认为是”committed“的。

        6. 如果针对某个partition的所有复制节点都挂了,Kafka默认选择最先复活的那个节点作为leader(这个节点不一定在ISR里)


消息投递可靠性

     一个消息如何算投递成功,Kafka提供了三种模式:

        1. 第一种是啥都不管,发送出去就当作成功,这种情况当然不能保证消息成功投递到broker;

        2. 第二种是Master-Slave模型,只有当Master和所有Slave都接收到消息时,才算投递成功,这种模型提供了最高的投递可靠性,但是损伤了性能;

        3. 第三种模型,即只要Master确认收到消息就算投递成功;实际使用时,根据应用特性选择,绝大多数情况下都会中和可靠性和性能选择第三种模型



Consumergroup(消费者组)

        1. 每一个consumer实例都属于一个consumer group。

        2. 每一条消息只会被同一个consumergroup里的一个consumer实例消费。

        3. 不同consumer group可以同时消费同一条消息。



Zookeeper协调控制

        1. 管理broker与consumer的动态加入与离开。

       2. 触发负载均衡,当broker或consumer加入或离开时会触发负载均衡算法,使得一个consumer group内的多个consumer的订阅负载平衡。

        3. 维护消费关系及每个partition的消费信息。





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值