<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Kafka | Liao Lile</title>
    <link>https://liaolile.com/tag/kafka/</link>
      <atom:link href="https://liaolile.com/tag/kafka/index.xml" rel="self" type="application/rss+xml" />
    <description>Kafka</description>
    <generator>Wowchemy (https://wowchemy.com)</generator><language>zh-Hans</language><lastBuildDate>Sat, 31 Mar 2018 23:13:00 +0000</lastBuildDate>
    <image>
      <url>https://liaolile.com/media/icon_hu0b7a4cb9992c9ac0e91bd28ffd38dd00_9727_512x512_fill_lanczos_center_3.png</url>
      <title>Kafka</title>
      <link>https://liaolile.com/tag/kafka/</link>
    </image>
    
    <item>
      <title>The Basic Elements of Kafka</title>
      <link>https://liaolile.com/post/tech/distributesystem/the_basic_elements_of_kafka/</link>
      <pubDate>Sat, 31 Mar 2018 23:13:00 +0000</pubDate>
      <guid>https://liaolile.com/post/tech/distributesystem/the_basic_elements_of_kafka/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Kafka是一种高吞吐量的分布式&lt;em&gt;发布订阅&lt;/em&gt;消息系统，它可以处理消费者规模的网站中的所有动作流数据。由LinkedIn开发的一个分布式的消息系统，使用Scala编写。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;!-- more --&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/05/15/6RCijK5npvfzyLM.png&#34; alt=&#34;kafka1&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote&gt;
&lt;h2 id=&#34;特点&#34;&gt;特点：&lt;/h2&gt;
&lt;/blockquote&gt;
&lt;p&gt;1、通过O(1)的磁盘数据结构提供消息的持久化，这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能。保证常数时间复杂度的访问性能。
2、高吞吐量  ：即使是非常普通的硬件Kafka也可以支持每秒数百万的消息。
3、支持通过Kafka服务器和消费机集群来分区消息。支持Kafka Server间的消息分区，及分布式消费，同时保证每个Partition内的消息顺序传输。
4、同时支持离线数据处理和实时数据处理。
5、支持Hadoop并行数据加载。支持在线水平扩展。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;kafka术语&#34;&gt;Kafka术语&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Broker&lt;/code&gt;
Kafka集群包含一个或多个服务器，这种服务器被称为broker。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Topic&lt;/code&gt;
每条发布到Kafka集群的消息都有一个类别，这个类别被称为Topic。（物理上不同Topic的消息分开存储，逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处）Topic在逻辑上可以被认为是一个queue，每条消费都必须指定它的Topic，可以简单理解为必须指明把这条消息放进哪个queue里。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Partition&lt;/code&gt;
Partition是物理上的概念，每个Topic包含一个或多个Partition，注意消费者数量超过分区数量，多余消费者会闲置。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Producer&lt;/code&gt;
负责发布消息到Kafka broker&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Consumer&lt;/code&gt;
消息消费者，向Kafka broker读取消息的客户端。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Consumer Group&lt;/code&gt;
每个Consumer属于一个特定的Consumer Group（可为每个Consumer指定group name，若不指定group name则属于默认的group）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/05/15/iADIMN9EfX3Gbea.png&#34; alt=&#34;kafka2&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Kafka通过Zookeeper管理集群配置，选举leader，以及在Consumer Group发生变化时进行rebalance。
kafka集群有多个kafka实例组成，每个实例(server)成为broker。无论是kafka集群，还是producer和consumer都依赖于zookeeper来保证系统可用性集群保存一些meta信息。
kafka 在 zookeeper 中的存储结构如下图所示：&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/05/15/Wj8ClScpEUVR4rF.png&#34; alt=&#34;kafka3&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;物理上把Topic分成一个或多个Partition，每个Partition在物理上对应一个文件夹，该文件夹下存储这个Partition的所有消息和索引文件。&lt;/p&gt;
&lt;p&gt;每个日志文件都是一个log entry序列，每个log entry包含一个4字节整型数值（值为N+5），1个字节的&amp;quot;magic value&amp;quot;，4个字节的CRC校验码，其后跟N个字节的消息体。每条消息都有一个当前Partition下唯一的64字节的offset，它指明了这条消息的起始位置。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;message length ： 4 bytes (value: 1+4+n)
&amp;ldquo;magic&amp;rdquo; value ： 1 byte
crc ： 4 bytes
payload ： n bytes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个log entries并非由一个文件构成，而是分成多个segment，每个segment以该segment第一条消息的offset命名并以“.kafka”为后缀。另外会有一个索引文件，它标明了每个segment下包含的log entry的offset范围，如下图所示。&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/05/15/2As8knHywVGP9M1.png&#34; alt=&#34;kafka4&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;因为每条消息都被append到该Partition中，属于顺序写磁盘，因此效率非常高（经验证，顺序写磁盘效率比随机写内存还要高，这是Kafka高吞吐率的一个很重要的保证）。&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/05/15/LboJe1sWxpSYd4I.png&#34; alt=&#34;kafka5&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;多个Partition属于同一个topic，但是如何保证topic消息的顺序呢&lt;/em&gt;？&lt;/p&gt;
&lt;p&gt;对于传统的message queue而言，一般会删除已经被消费的消息，而Kafka集群会保留所有的消息，无论其被消费与否。当然，因为磁盘限制，不可能永久保留所有数据（实际上也没必要），因此Kafka提供两种策略删除旧数据。一是基于时间，二是基于Partition文件大小。例如可以通过配置$KAFKA_HOME/config/server.properties，让Kafka删除一周前的数据，也可在Partition文件超过1GB时删除旧数据。&lt;/p&gt;
&lt;p&gt;Kafka会为每一个Consumer Group保留一些metadata信息——当前消费的消息的position，也即offset。这个offset由Consumer控制。正常情况下Consumer会在消费完一条消息后递增该offset。当然，Consumer也可将offset设成一个较小的值，重新消费一些消息。因为offet由Consumer控制，所以Kafka broker是无状态的，它不需要标记哪些消息被哪些消费过，也不需要通过broker去保证同一个Consumer Group只有一个Consumer能消费某一条消息，因此也就不需要锁机制，这也为Kafka的高吞吐率提供了有力保障。&lt;/p&gt;
&lt;p&gt;在发送一条消息时，可以指定这条消息的key，Producer根据这个key和Partition机制来判断应该将这条消息发送到哪个Partition。Partition机制可以通过指定Producer的partition. class这一参数来指定，该class必须实现kafka.producer.Partitioner接口。
回答了上述的疑问！！&lt;/p&gt;
&lt;p&gt;使用Consumer high level API时，同一Topic的一条消息只能被同一个Consumer Group内的一个Consumer消费（可以多次消费），但多个Consumer Group可同时消费这一消息。&lt;/p&gt;
&lt;p&gt;​		















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://s2.loli.net/2022/05/15/MTEejwBDgJfy6rA.png&#34; alt=&#34;kafka6&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;Kafka的设计理念之一就是同时提供离线处理和实时处理。根据这一特性，可以使用Storm这种实时流处理系统对消息进行实时在线处理，同时使用Hadoop这种批处理系统进行离线处理，还可以同时将数据实时备份到另一个数据中心，只需要保证这三个操作所使用的Consumer属于不同的Consumer Group即可。&lt;/p&gt;
&lt;p&gt;push模式很难适应消费速率不同的消费者，因为消息发送速率是由broker决定的。push模式的目标是尽可能以最快速度传递消息，但是这样很容易造成Consumer来不及处理消息，典型的表现就是拒绝服务以及网络拥塞。而pull模式则可以根据Consumer的消费能力以适当的速率消费消息。&lt;/p&gt;
&lt;p&gt;对于Kafka而言，pull模式更合适。pull模式可简化broker的设计，Consumer可自主控制消费消息的速率，同时Consumer可以自己控制消费方式——即可批量消费也可逐条消费，同时还能选择不同的提交方式从而实现不同的传输语义。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可靠的数据传递&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;保证：指的是确保系统在各种不同环境下能够发生一致的行为。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kafka 可以保证分区消息的顺序。同一个分区&lt;/li&gt;
&lt;li&gt;只有当消息被写入分区的所有同步副本（但不一定要写入磁盘），他才被认为是已提交的。&lt;/li&gt;
&lt;li&gt;只要还有一个副本是活跃的，那么已经提交的消息就不会丢失&lt;/li&gt;
&lt;li&gt;消费者只能读取已经提交的信息&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
