zoukankan      html  css  js  c++  java
  • kafka的特性初探

    本篇文章将从kafka的存储特性、生产者特性、消费者特性和消费确认这四个方面初探kafka的设计特性, 详细内容可查看官方文档第四章节kafka设计动机

    一、存储特性

    根据kafka官网描述,kafka的消息存储是基于磁盘文件系统存储的,当时我内心就留下了一个大大的❓,我们知道kafka在业界以高吞吐量和低延迟著称,但是它的消息又是基于磁盘存储的,那它是怎么做到的呢?

    带着这个疑问我继续阅读发现,其实我读漏了一些信息,真实是kafka消息存储是基于磁盘文件系统和页缓存的存储方式。

    如上图, 是kafka消息流程示意图,流程如下:

    1.生产者把消息发送到broker的page cache中,

    2.消费者根据自身存储的offset,和partition从page cache去消费消息

    3.异步线程将page cache中的消息flush到磁盘中

    4.还有图中未标注的,异步线程将page cache中的消息同步到副本上

    看完以后可能会疑惑page cache是什么?

    学过操作系统我们知道操作系统的内存存储管理方式有页式存储、段式存储和段页式存储,在页式存储方式中,操作系统把内存空间按照一定大小(1,2,4k)进行划分,划分后的单个空间称为页,理解这个概念后我们看page cache顾名思义页缓存,可以理解成在内存中占据4k内存的缓存空间。当生产者向消息队列中发消息时,消息将按照顺序存储在page cache中,当page cache装满后,就再分配一个新的page cache。

    了解完page cache后,我们知道其实kafka的低延迟本质上还是因为是基于内存的,只有当消费者要消费的数据不在内存时,kafka需要去磁盘中查找数据,然后缓存到内存中,具体过程是kafka根据消费者传的partiton key和offset信息去磁盘中把数据所在页的数据缓存到内存中,因为消息是顺序存储的所以消费者可以很方便访问后面的数据。

    多琢磨一下你会发现,kafka的消息存储方式跟mysql索引的存储方式是一样一样的,寻找一条数据的时候,也会把数据所在页缓存到内存中,不同点在于mysql索引的存储结构是B+TREE,kafka消息的存储结构是BTREE。

    当然kafka能实现消息消费的高吞吐,低延迟肯定不止上述原因,还有考虑到jvm,gc,还有linux对磁盘读写的优化等。

    二、生产者特性

    kafka集群在接收生产者的消息时有负载均衡机制,我们知道如果对一个主题进行分区时,我们可以指定分区的数量,每个单元称为partition,多个partition会平均分配到各个broker上,当生产者向该主题发送消息时,kafka会根据一定算法将消息发送到一个partiton中,如hash取模算法,随机算法等。

     生产者发送消息的方式为批处理发送:用户可以指定消息总数量和等待消息时间(不超过系统配置的超时时间)将一批消息统一发送到broker上。而不是一条消息接一条消息的发送,有效地提升发送效率。

    除了批处理方式的话,还有同步发送,和异步发送两种方式,跟rabbitmq的消息发送方式一样。

    三、消费者特性

    kafka消费者消费消息是pull的模式,和很多消息队列如rabbitmq的push模式不一样。我们肯定不自觉冒出一个Why?

    官方的解释是这样的:push模式和pull模式各有优劣。push模式很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的。push模式的目标是尽可能以最快速度传递消息,但是这样很容易造成消费者来不及处理消息,典型的表现就是拒绝服务以及网络拥塞。而pull模式则可以根据consumer的消费能力以适当的速率消费消息。pull模式还有一个优点是,它可以决定已从从broker中pull多少条消息,可以减少不必要的等待时间。同时pull模式在broker中数据为空时使用“长轮询”进行阻塞,知道数据到达,而不是不断地重复轮询占用大量资源。

    常规的消息队列的消费模式是:broker推送消息到消费者处,消费者消费成功后给broker返回一个ack确认信息,broker收到确认信息后删除消息

    kafka消费模式是: 消费者传partiton_id和offset给broker, broker找到对应的partition,然后根据offset找到对应的消息返回给消费者而不删除消息,然后消费者会更新offset+n(取到的消息的数量)。直观的看,broker有点像一个超大的消息数组,消费者根据索引去取数组中对应的值。

    kafka这样的处理模式有个好处,消费者可以根据自身情况消费队列中的消息,如消费旧的消息。

    四、消息传递确认

    这部分跟我想象的有些出入,待更新。。。。。。。

  • 相关阅读:
    无休止的项目,何来快感!!
    [From HTTP to AWS][4]使用LibcURL with OpenSSL support
    [From HTTP to AWS][2]Analyze TCP/IP Packets
    The setup of Piaoger
    从Adobe Subscription editions扯到破坏性创新
    SaaS窘境[欣赏然后翻译之]
    Algodoo,很棒的物理引擎
    浮水法POJ2528
    蛤的旅行
    题解 CF712A 【Memory and Crow】
  • 原文地址:https://www.cnblogs.com/lifei01/p/13471371.html
Copyright © 2011-2022 走看看