文档章节

kafka学习笔记:知识点整理(一)

 惜0623
发布于 2017/04/27 10:17
字数 1034
阅读 8
收藏 0

一、kafka 架构

1.1 拓扑结构

如下图:

图.1

1.2 相关概念

如图.1中,kafka 相关名词解释如下:

 

1.producer:
  消息生产者,发布消息到 kafka 集群的终端或服务。
2.broker:
  kafka 集群中包含的服务器。
3.topic:
  每条发布到 kafka 集群的消息属于的类别,即 kafka 是面向 topic 的。
4.partition:
  partition 是物理上的概念,每个 topic 包含一个或多个 partition。kafka 分配的单位是 partition。
5.consumer:
  从 kafka 集群中消费消息的终端或服务。
6.Consumer group:
  high-level consumer API 中,每个 consumer 都属于一个 consumer group,每条消息只能被 consumer group 中的一个 Consumer 消费,但可以被多个 consumer group 消费。
7.replica:
  partition 的副本,保障 partition 的高可用。
8.leader:
  replica 中的一个角色, producer 和 consumer 只跟 leader 交互。
9.follower:
  replica 中的一个角色,从 leader 中复制数据。
10.controller:
  kafka 集群中的其中一个服务器,用来进行 leader election 以及 各种 failover。
12.zookeeper:
  kafka 通过 zookeeper 来存储集群的 meta 信息。

 

1.3 zookeeper 节点

kafka 在 zookeeper 中的存储结构如下图所示:

 

图.2

二、producer 发布消息

2.1 写入方式

producer 采用 push 模式将消息发布到 broker,每条消息都被 append 到 patition 中,属于顺序写磁盘(顺序写磁盘效率比随机写内存要高,保障 kafka 吞吐率)。

2.2 消息路由

producer 发送消息到 broker 时,会根据分区算法选择将其存储到哪一个 partition。其路由机制为:

1. 指定了 patition,则直接使用;
2. 未指定 patition 但指定 key,通过对 key 的 value 进行hash 选出一个 patition
3. patition 和 key 都未指定,使用轮询选出一个 patition。

 附上 java 客户端分区源码,一目了然:

//创建消息实例
public ProducerRecord(String topic, Integer partition, Long timestamp, K key, V value) {
     if (topic == null)
          throw new IllegalArgumentException("Topic cannot be null");
     if (timestamp != null && timestamp < 0)
          throw new IllegalArgumentException("Invalid timestamp " + timestamp);
     this.topic = topic;
     this.partition = partition;
     this.key = key;
     this.value = value;
     this.timestamp = timestamp;
}

//计算 patition,如果指定了 patition 则直接使用,否则使用 key 计算
private int partition(ProducerRecord<K, V> record, byte[] serializedKey , byte[] serializedValue, Cluster cluster) {
     Integer partition = record.partition();
     if (partition != null) {
          List<PartitionInfo> partitions = cluster.partitionsForTopic(record.topic());
          int lastPartition = partitions.size() - 1;
          if (partition < 0 || partition > lastPartition) {
               throw new IllegalArgumentException(String.format("Invalid partition given with record: %d is not in the range [0...%d].", partition, lastPartition));
          }
          return partition;
     }
     return this.partitioner.partition(record.topic(), record.key(), serializedKey, record.value(), serializedValue, cluster);
}

// 使用 key 选取 patition
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
     List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
     int numPartitions = partitions.size();
     if (keyBytes == null) {
          int nextValue = counter.getAndIncrement();
          List<PartitionInfo> availablePartitions = cluster.availablePartitionsForTopic(topic);
          if (availablePartitions.size() > 0) {
               int part = DefaultPartitioner.toPositive(nextValue) % availablePartitions.size();
               return availablePartitions.get(part).partition();
          } else {
               return DefaultPartitioner.toPositive(nextValue) % numPartitions;
          }
     } else {
          //对 keyBytes 进行 hash 选出一个 patition
          return DefaultPartitioner.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
     }
}

2.3 写入流程

 producer 写入消息序列图如下所示:

图.3

流程说明:

 

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

 

2.4 producer delivery guarantee

 一般情况下存在三种情况:

1. At most once 消息可能会丢,但绝不会重复传输
2. At least one 消息绝不会丢,但可能会重复传输
3. Exactly once 每条消息肯定会被传输一次且仅传输一次

当 producer 向 broker 发送消息时,一旦这条消息被 commit,由于 replication 的存在,它就不会丢。但是如果 producer 发送数据给 broker 后,遇到网络问题而造成通信中断,那 Producer 就无法判断该条消息是否已经 commit。虽然 Kafka 无法确定网络故障期间发生了什么,但是 producer 可以生成一种类似于主键的东西,发生故障时幂等性的重试多次,这样就做到了 Exactly once,但目前还并未实现。所以目前默认情况下一条消息从 producer 到 broker 是确保了 At least once,可通过设置 producer 异步发送实现At most once。

 

 

源码来源:http://minglisoft.cn/technology

有兴趣的朋友们可以加球球哦~:2042849237

© 著作权归作者所有

粉丝 1
博文 44
码字总数 73777
作品 0
惠州
私信 提问
加载中

评论(1)

猫改不了吃鱼
写的不错!1和2是连一起的~谢谢分享
kafka学习笔记:知识点整理(一)

一、kafka 架构 1.1 拓扑结构 如下图: 图.1 1.2 相关概念 如图.1中,kafka 相关名词解释如下: 1.producer:  消息生产者,发布消息到 kafka 集群的终端或服务。2.broker:  kafka 集群...

愉快的鱼儿
2017/06/05
0
0
kafka学习笔记:知识点整理(二)

三、kafka HA 3.1 replication 如图.1所示,同一个 partition 可能会有多个 replica(对应 server.properties 配置中的 default.replication.factor=N)。没有 replica 的情况下,一旦 brok...

愉快的鱼儿
2017/06/05
0
0
我就是靠这个软件实现第2职业的

今天我来分享一下我是如何利用印象笔记来做个人知识管理的。 (以下内容都是基于印象笔记来做的解说,虽然没拿钱,但是广告嫌疑很大,如有不适,请自行脑补替换成其他的软件) 如果你之前没有...

彭小六
2016/04/05
0
0
程序员最佳学习方法(干货总结)

前言 这里筑梦师,是一名正在努力学习的iOS开发工程师,目前致力于全栈方向的学习,希望可以和大家一起交流技术,共同进步,用简书记录下自己的学习历程. 环境 一个程序员在萌芽之中,唯一的天敌并...

筑梦师Winston
2018/06/18
0
0
Kafka笔记整理(三):消费形式验证与性能测试

[TOC] Kafka笔记整理(三):消费形式验证与性能测试 Kafka消费形式验证 前面的《Kafka笔记整理(一)》中有提到消费者的消费形式,说明如下: 下面就来验证Kafka的消费形式,不过需要说明的...

xpleaf
2018/03/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

REST接口

文章来源 https://zhuanlan.zhihu.com/p/28674721?group_id=886181549958119424 http://www.ruanyifeng.com/blog/2014/05/restful_api.html REST 对请求的约定 REST 用来规范应用如何在 HTTP......

Airship
6分钟前
0
0
Spring Cloud Config 统一配置中心

Spring Cloud Config 统一配置中心 一、统一配置中心 统一管理配置 通常,我们会使用配置文件来管理应用的配置。如一个 Spring Boot 的应用,可以将配置信息放在 application.yml 文件中,如...

非摩尔根
22分钟前
0
0
android ------ AAPT2 error: check logs for details解决方法

AAPT 是全称是 Android Asset Packaging Tool,它是构建 App,甚至是构建 Android 系统都必不可少的一个工具。它的作用是将所有资源文件压缩打包到Android APK 当中。我们在 Android SDK 目录...

切切歆语
今天
1
0
今天的学习

今天学到了<select></select>标签: <label for="unittype">Select unit type: </label><select id="unittype" name="unittype" autofocus > <option value="1"> Miner </option> ......

墨冥
今天
1
0
程序员随想-关于分享

最早的时候,文字是贵族这些上层人士才会学习的,底层人士没有资格和渠道去学习,同样用文字、图像等其他载体承载的知识大部分也只有贵族阶层才能享受的。后来有了造纸术、印刷术,成本降低,...

Lubby
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部