Kafka权威指南-学习笔记---第三章

深入Kafka

1.1集群成员关系

Kafka使用zookeeper来维护集群成员的信息。每个broker都有一个唯一的标识符,这个标识符可以在配置文件里指定,也可以自动生成。在broker启动的时候,他通过创建临时节点把自己的ID注册到zookeeper上。Kafka组件订阅zookeeper的/brokers/ids路径,当有broker加入集群时,这些组件就会收到通知。
所有启动一个具有相同ID的broker就会报错误。在broker停机以及出现网络分区或者长时间垃圾回收停顿时,broker就会从zookeeper上断开连接,此时broker在启动时创建的临时节点就会自动从zookeeper上移除。监听broker列表的kafka组件会被告知该broker已经被移除。在关闭broker时,它对应的节点也会消失。如果使用相同的ID启动另一个全新的broker的时候,他就会立即加入集群,并拥有与就broker相同的分区和主题。

1.2控制器

控制器其实就是一个broker。他除了具有一般的broker的功能之外,他负责分区首领的选举,集群中的第一个启动的broker通过在zookeeper里创建一个临时的节点,让自己成为控制器。实际上其他的broker在创建的时候也会创建这样的一个节点,但是会收到一个节点已经存在的错误。这样可以确保集群中只有一个控制器。

1.3复制

复制功能是kafka架构的核心,kafka可以被描述为:一个分布式的、可分区的、可以复制的提交日志的服务。kafka使用主题来组织数据,每个主题被分为若干个分区,每个分区有多个副本,那个副本被保存在broker上,每个broker可以保存成百上千属于不同主题的和分区的副本。
副本主要有两种类型:

  • 首领副本: 每个分区都有一个首领副本,为了保持一致性,所有的生产者以及消费者都会请求到这个副本。首领副本也需清楚那个跟随者的副本跟自己是一致的。
  • 跟随者副本:除首领副本外的所有副本均称为跟随者副本。跟随者副本不处理客户端请求,作用为仅从首领副本哪里复制消息,保持与首领一致的状态。如果首领副本出现崩溃,其中的跟随者就会被提升成新首领。
    假如首领副本与跟随者副本同步失败,两个分区会直到broker重启之后复制才会继续。若一个跟随者副本的数据跟首领的不同步,那么在首领失效的时候,他就不会成为新首领。只有同步的副本才有可能被选为新的首领。
    跟随者副本发送给首领副本获取数据的请求,这种的请求与消费者发送的请求是一样的。这个请求包含了跟随者想要的获取消息的偏移量,而且偏移量是有序的。
    除了当前首领之外,每个分区都有一个首选首领(创建主题时选定的首领就是分区的首选首领)

1.4处理请求

broker大部分的工作是处理客户端、分区副本和控制器发送给分区首领的请求。broker会按照请求的顺序来处理他们,这种顺序保证了kafka具有了消息队列的特性,同时也保证了保存的消息也是有序的。
所有的请求消息都包含了一个标准的信息头:

  • request type(也就是API key)
  • request version(broker可以处理不同版本的客户端请求,并根据客户端版本做出不同的响应)
  • correlation ID(一个具有唯一性的数字,用于标识请求消息,同时也会出现在响应消息和错误日志中)
  • client ID用于标识发送请求的客户端
    broker会在他监听的端口上运行一个acceptor线程,这个线程会创建一个连接,并把他交给processor线程去处理。processor数量是可以配置的。processor负责从客户端获取请求消息,把他们放进请求队列,然后从响应队列获取响应消息,把他们发送给客户端。
    Alt
    kafka处理请求的内部流程
    但是如果broker收到一个针对特定分区的请求,但是这个分区的首领在另一个broker上。那么发送请求的客户端就会收到一个“非分区首领”的错误响应。为解决这个问题,客户端使用了另一种请求类型----元数据请求。此请求包括了客户端可能感兴趣的主题列表,服务端响应消息包括了这些主题所包含的分区、每个分区都有哪些副本、以及每个副本是首领。元数据请求可以发送给任意一个broker,因为所有broker都缓存了这些消息。
    一般情况下客户端会把这些信息缓存起来,并直接往目标broker上发送生产请求和获取请求。他们需要不时的发送元数据来刷新这些信息。从而知道元数据是否发生了改变。例如在新broker加入集群时,部分副本就会被移动到新的broker上。
    Alt
    图:客户端路由请求
1.4.1生产请求

生产者关键配置参数:acks
该参数指定了需要多个broker确认次啊可以认为一个消息写入是成功的,不同的配置对“写入成功”的界定是不一样的。

  • 若acks=1,俺么只要首领收到消息就会认为写入成功;
  • 若acks=all,表示需要所有的同步副本消息才算写入成功;
  • 若acks=0,那么生产者在把消息发出去就不需要等待broker的响应。

该参数指定了需要多个broker确认次啊可以认为一个消息写入是成功的,不同的配置对“写入成功”的界定是不一样的。
包含首领副本的broker收到生产请求时,会对请求作出一些验证。

  • 发送数据的用户是否有写入权限
  • 请求中的acks是否有效
  • 若acks=all,是否有足够多的副本保证已经被安全写入。

在消息被写入分区的首领之后,broker开始检查acks配置参数,若acks被设置为all,那么请求会被保存在一个炼狱的缓存区中,知道首领发现所有跟随者副本都复制了消息,响应才会被返回给客户端。

1.4.2获取请求

broker处理获取请求的方式预处理生产者请求的方式很相似。客户端发送请求,想beoker请求主题分区中具有特定偏移量的消息。

  • 客户端还可以指定broker最多可以从一个分区返回多少数据(保证客户单的内存不被打满);
  • 客户端也可以设置返回数据的下限,以减少网络IO消耗;
  • 当然客户端不能一直等待broker累计数据,所以需要设置一个过期时间,若在规定时间内没有达到数据下限,就进行数据返回。

Alt
图:broker延迟做出响应以便累积足够的数据
若请求的消息不存在,则返回错误。
kafka采用的是零复制技术向客户端发送消息-也就是说,kafka直接把消息从文件(linux文件系统缓存)里发送到网络通道,而不需要经过任何中间缓存区。这个kafka与其他大部分数据库不同的地方,其他数据库在将数据发送给客户端之前会保存在本地。所以kafka拥有更好的性能。
但是分区首领在消息还没有被写入所有同步副本中之前,是不会发送给消费者的。尝试这些消息的请求会得到空的响应而不是错误。因为没有被足够多的副本复制的消息被认为是不安全的,若首领发生崩溃,另一个副本成为新的首领,那么这写信息就丢失了。所有会等到所有同步副本复制了这些消息,才允许消费者获取,
Alt
图:消费者只能看到已经复制到ISR的消息

1.5物理存储

kafka的基本存储单元是分区,分区无法在多个broker间再细分,也无法在同一个broker的多个磁盘上进行细分。所以分区的大小收到单个挂载点可用空间的限制。
在配置kafka的时候,管理员指定了一个用于存储分区的目录清单(log.dirs)参数的值。该参数一般会包含每个挂载点的目录。

1.5.1分区分配

kafka首先会决定如何在broker间分配分区。假设你有6个broker,打算创建爱你一个包含10个分区的主题,并且复制系数为3。那么Kafka就会有30个分区副本,他们被分配到6个broker中。分配时要遵循以下规则:

  • 在broker间平均为分布分区副本,所以对于上述例子,每个broker中需要有5个副本。
  • 确保每个分区的每个副本分布在不同的broker上。
  • 若broker指定了机架信息,那么尽可能把每个分区的副本分配到不同的机架的broker上,这样就是为了保证一个机架的不可用不会导致整体分区不可用。

为分区跟副本选择好合适的broker之后,需要为每个分区单独分配目录,规则为:计算每个目录里面的分区数量,新的分区总是被添加到数量最小的那个目录中,若果添加了个一个新的磁盘,所有新的分区就会被创建到这个磁盘上,

1.5.2文件管理

Kafka管理员为每个主题配置了数据保留期限,规定数据被删除之前可以保留多长时间,或者清理数据之前可以保留的数据大小。所以为了方便查找,将分区分为若干个片段,每个片段包含1GB或者一周的数据,以较小的那个为准。在broker写入数据时,达到片段上限,就关闭当前文件,并打开一个新文件。

1.5.3文件格式

我们将kaka的消息个偏移量保存在文件中,保存在磁盘上的数据格式与从生产者发送过来或者发送给消费者的消息格式是一样的。
除了键、值、偏移量之外,消息里还包含了消息的大小、检验和、消息格式版本号、压缩算法(snappy、Gzip)等和时间戳(可以为生产者发送消息的时间,也可以是消息到达broker的时间,这个可以配置)
生产者发送给broker的消息为压缩过的消息,broker会将此压缩过的消息发送给消费者。消费者在解压这个消息之后,会看到这个消息。
Alt
图:普通消息与包装消息

1.5.4索引

消费者可以从Kafka的任意可用偏移量位置开始读取消息。假设消费者要读取从偏移量100开始的1MB消息,那么 broker必须立即定位到偏移量 100 (可能是在分区的任意一个片段里),然后开始从这个位置读取消息。为了帮助broker更快地定位到指定的偏移量,Kafka 为每个分区维护了一个索引。索引把偏移量映射到片段文件和偏移量在文件里的位置。
索引也被分成片段,所以在删除消息时,也可以删除相应的索引。 Kafka不维护索引的 校验和。如果索引出现损坏,Kafka会通过重新读取消息并录制偏移量和位置来重新 生 成索引。如果有必要,管理员可以删除索引,这样做是绝对安全的,Kafka会自动重新生成这些索引。

1.5.5清理

一般情况下,Kafka会根据设置的时间保留数据,把超过时效的旧数据删除掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值