JavaDriver JavaDriver
首页
  • 基础
  • 并发
  • JVM
  • 设计模式
  • 计算机网络
  • 操作系统
  • 数据结构
  • 算法
  • MYSQL
  • REDIS
  • Netty
  • Kafka
系统设计
非技术
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

YoungAnn

西二旗Java老司机一枚 致力于社会主义添砖Java
首页
  • 基础
  • 并发
  • JVM
  • 设计模式
  • 计算机网络
  • 操作系统
  • 数据结构
  • 算法
  • MYSQL
  • REDIS
  • Netty
  • Kafka
系统设计
非技术
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Netty

  • Kafka

    • Kafka
    • 生产者
    • 消费者
    • 集群下的Kafka要考虑哪些事情
    • 如何保证Kafka的可靠性
  • 中间件
  • Kafka
YoungAnn
2022-05-21

集群下的Kafka要考虑哪些事情

# 集群成员关系

Kafka使用 Zookeeper来维护集群成员的信息. 每个broker都有唯一的标识符,可以配置指定,也可以自动生成。 在broker启动时,他通过创建临时节点把自己注册到zk。 broker订阅zk的/brokers/ids路径,当有broker加入或者退出集群时,这些组件可以获得通知。

在关闭 broker时,它对应的节点也会消失,不过它的 ID会继续存在于其他数据结构中。例如,主题的副本列表(下面会介绍)里就可能包含这些ID。 在完全关闭一个 broker之 后,如果使用相同的 ID 启动另一个全新的 broker,它会立即加入集群,井拥有与旧 broker 相同的分区和主题。

# 控制器

控制器其实就是 一 个 broker,只不过它除了具有一般 broker 的功能之外,还负责分区 首领的选举。 哪个broker可以成为控制器? 在集群启动时,所有broker都会尝试在zk创建节点/controller,但是只有一个broker可以创建成功,它就是控制器。 非控制器的broker节点会在控制器节点创建zk watch对象,用于接收这个节点的变更通知。 通过watch对象得知控制器节点消失,那么其他broker节点会进入下一轮的首领选举,选举成功会有一个新的递增的ID产生。 新broker加入集群会发生什么? 控制器会检查新broker是否包含现有分区的副本,如果有,则通知其他broker,允许新的broker同步分区副本。 broker退出集群会发生什么? 控制器监听到broker离开集群的消息,check哪些分区首领在该broker上。然后再其他broker上选举新的分区首领,并通知所有broker新的分区首领。

# 复制

kafka是一个分布式的、可分区的、可复制的提交日志服务。 复制什么? 每个topic由对个partition、每个partition有多个副本,其中一个是首领副本,其他是跟随者副本。 该partition的生产者和消费者请求都会经过首领副本。 复制就发生在首领副本和跟随者副本之间。 当首领副本崩溃时,其中一个跟随者副本可以提升为首领副本。 当首领副本崩溃时,哪个跟随者副本可以提升为首领副本 不同步的跟随者是不能成为首领的 什么标准判断一个跟随者是不同步的? 跟随者请求同步时总是按照offset递增的顺序请求同步的消息,而且总是在收到上一个请求的影响之后才会发出下一个请求。所以当首领收不到follower的请求最新的offset时或者一定时间内收不到follower的同步请求时,认为这个follower是不同步的。这个一定时间可以通过replica.lg.time.max.ms配置。 首选首领是可以优先称为下一届首领的。 首选首领是在创建分区时,为了在broker之间均衡首领选举的分区首领。

# 处理请求

broker 的大部分工作是处理客户端、分区副本和控制器发送给分区首领的请求。 producer的生产请求和consumer的获取请求都必须发送给分区的首领副本。 那么客户端怎么知道谁是首领副本呢? 客户端使用了另一 种请求类型,也就是元数据请求。请求到元数据后缓存在本地。 通过配置matedata.max.age.ms设置定时刷新元数据。

生产者请求 包含首领副本的 broker在收到生产请求时,会对请求做一些验证

  • 发送数据的用户是否有主题的写权限
  • 请求里的acks值是否是有效值(只允许0、1、all)
  • 如果acks=all,是否有足够的读本保证消息已经被安全写入? 以上都做完给客户端相应。

消费者请求 客户端可以指定broker最多从一个分区里返回多少数据,这是有必要的,因为broker返回大量的数据有可能撑爆客户端的buffer broke会check请求是否有效,比如请求的偏移量是否存在,如果存在,则用零拷贝的方式返回数据。 客户端也可以指定broker积攒一定的数据再返回,避免频繁的网络IO。 并不是首领副本上的消息都可以返回给客户端,只有被所有follower同步了的消息才可以返回给客户端。

# 物理存储

kafka的基本存储单元是分区。 log.dirs配置用于指定存储分区的目录。 如何做分区和broker之间的分配 加入要在6个broker的kafka集群上创建分区数为10复制系数为3的主题,那么这30个分区副本如何分配给6个broker? 做分区和broker之间的分配要遵循以下原则:

  • 在broker间平均的分布分区副本
  • 每个分区的副本尽可能的分布在不同的broker上
  • 如果制定了broker的机架信息,尽可能的把每个分区的副本分配到不同的机架上

依照这个规则,分配方式可以如下:

  1. 先均匀分配首领分区。随机选一个broker,轮训的方式给每个broker分配分区来确定首领分区的位置。
  2. 再均匀分配分区副本。以首领分区为起点,了轮训分配分区副本。
  3. 指定机架信息的时候,均匀分配分区的方式。假设 broker0、 broker1和 broker2放置在同一个机架上, broker3、 broker4 和 broker5分别放置在其他不同的机架上,那么在轮训分配的时候,我们不是按照从 0到 5的顺序来选择 broker,而 是按照 0, 3, 1, 4, 2, 5 的顺序来选择。

如何做文件管理 因为在一个大文件中查找和删除是非常耗时的,所以我们把分区分成若干个片段。默认每个片段包含1G或者1周的数据。 当前正在写入数据的片段叫做活跃片段。活跃片段永远不会被删除。 broker会为分区的每个片段打开一个文件句柄,这会导致打开过多的文件句柄,所以操作系统必须根据实际情况做一些调优。 broker如何在一个分区的众多文件中定位指定的offset位置? kakfa为每个分区文件建立索引,根据索引可以快速定位offset在文件中的位置。

如果有必要,管理员可以删除索引,kafka会重新生成这些索引。

编辑 (opens new window)
上次更新: 2022/05/22, 00:01:01
消费者
如何保证Kafka的可靠性

← 消费者 如何保证Kafka的可靠性→

最近更新
01
电商-商品系统设计
12-17
02
关于如何写OKR
12-09
03
对事不对人 vs 对人不对事
12-09
更多文章>
Theme by Vdoing | Copyright © 2022-2023 YoungAnnn | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式