一、kafka技术内幕 基础篇(一)

一、入门

1、kafka流式处理平台

1、作为流式平台需要具备3个特点

  • 数据注入功能:类似消息系统,提供事件流的发布和订阅
  • 数据存储功能:存储事件流数据的节点具有故障容错的特点
  • 流处理功能:能够对实时的事件流进行流式地处理和分析

2、消息模型

  • 队列模式(点对点模式):多个消费者读取消息队列,每条消息只会发送给一个消费者。即,同一个消费组的多个消费者,一个主题一条消息只给一个消费者去处理
  • 发布订阅模式:多个消费者订阅主题,主题的每条消息会发布个所有的消费者。即,多个消费组,订阅一个主题,主题的每条消息广播给多个消费组

3、Kafka功能模块

  • 消息系统,支持两种消息模型
  • 存储系统
  • 流处理系统,消息的读取和写入、存储消息流、实时的流式数据处理
  • 将消息系统、消息存储、流处理组合,既可以实时处理消息,也可以处理过去的消息

2、kafka基本概念

1、分区模型

  • 每种类型的消息视为一个主题
  • 一个主题可以有多个分区(类似于分流、横向切分表)
  • 每个分区的消费进度,采用偏移量来标记,即各个分区维护自己的偏移量
  • 每个分区可以有多个备份(高可用)
  • 每个分区在同一个消费组下的消费者内唯一,保证分区的消息在消费组内只会被消费一次,不会被多个消费者绑定从而导致重复消费的情况
  • 分区结构类似于一个队列,队列的意义:有序、可存储。故,消息在分区内部是有序的。一个主题的分区之间是不能保证这个主题的消息是有序。
    假如需要这个消息在整个消费组内有序:
    • 通常情况下消息与消息之间是无状态的,可以采用流式处理的理念,把有状态的消息转换成无状态的消息,即一个主题消息经过处理发送到另一个主题,另一个主题消息时在写业务逻辑
    • 如果硬要保证有序,也可以实现。可以将这个主题只设置一个分区,或者把有状态的消息根据key放到同一个分区中(消息在落入每个分区前会经过一定的算法,默认情况下时轮询、随机算法,也可以对消息的键进行散列化,再与分区的数量取模运算得到分区编号。对一个不要变的键进行的算法结果永远是同一个值,所以只要分区的数量不变,相同的键的所有消息总是会被写到同一个分区中),到此可以发现,虽然可以实现,但总觉得有些鸡肋(大体实现思路都差不多,还不如创建一个只有一个分区的主题)。

2、消费模型

  • 推送模型(push)
  • 拉取模型(pull),kafka采用拉取模型。
  • 为什么kafka采用pull,而不是push?
    同一个消费者组内,消费者客户端希望能够对消息精准一次消费
    • 如果采用push,以下几点弊端
      • 耦合性大、服务端负载大,服务端要做的事情太多了,要负责接收数据保存数据,还要负责控制发送消息。服务端每次还要等待客户端的响应。
      • 服务端消息代理控制数据的传输速率,如果消费者会处于超负荷状态(消费者不可控,就不能切合自己能力去处理),那么发送给消费者的消息会越积越多。推送的方式也难以应付不同类型的消费者,因为每个消费者的处理能力各不相同,服务端不好逐一控制
      • 每次服务端推送给客户端,都要等客户端的响应,如果客户端宕机了,服务端会有一个重发补救的措施,此时消息的控制权在服务端,服务端消息代理需要维护每条消息在对于每个消费者的状态,这种状态的一致性和性能没法保障,而且也比较复杂,反倒是让消费者自己维护更加合理
    • 如果采用pull,控制的权利交给消费者客户端,客户端主动拉取消息,对拉取到的消息做标记,这样消费者可以按照自己的意愿拉取消息。可以实时拉取消息也可以拉取历史消息。也有一个缺点,如果消息量很少,消费者需要不停的轮询。解决这个问题的方案时:允许消费者拉取请求以阻塞式、长轮询的方式等待,直到有新的数据到来。可以设置’指定的字节数量’,表示小谢代理在还没有收集足够的数据时,客户端拉取请求就不会立即返回。

3、分布式模型

  • 每个主题的多个分区可以分布式的存储在kafka集群上,每个分区又分为主副本、备份副本,主副本负责读写,副本分区仅仅从主副本同步数据
  • 当主副本故障时,部分副本中的一个副本会被选择为新的主副本。分区副本会均匀的分布在集群服务器上
  • 在代码里写的生产者和消费者实际上在站在kafka的角度来看属于客户端,而集群部署到服务器上的,才是服务端。其源代码在clients包下
  • 分区是消费者线程模型的最小并行单元。
    • 一台服务器、一个主题、三个分区、一个消费者
    • 三台服务器、一个主题、三个分区、三个消费者(一个消费者对应一个消费者线程,可以加快消费者处理消息的速度,从而提高吞吐量)

综上可以看出,增加服务器节点会提升集群的性能,增加消费者数量提升消息的处理能力

3、kafka设计与实现

1、文件系统的持久化与数据传输效率

  • 操作系统针对磁盘的读写的优化方案
    • 预读:提前讲一个比较平大的磁盘块读入内存
    • 后写:将很多小的逻辑写操作合并起来组成一个大的物理写操作
    • 操作系统会将驻内存剩余的所有空间都用作磁盘缓存,所有的磁盘读写操作都会经过磁盘缓存,如果是针对磁盘的顺序访问,某些情况下可能要比随机的内存访问要快,甚至可以和网络的速度相差无几
  • kafka数据持久化优化方案
    • 应用程序写入数据到文件系统的过程:在内存中保存尽可能多的数据,并在需要时将这些数据刷新到文件系统
    • kafka写入数据到文件系统的过程:数据直接写到持久化日志文件(磁盘缓存),但不进行刷新操作,之后操作系统定期自动刷新到物理磁盘
  • 生产者采用批量发送数据的方式
    • 防止请求过多,而是按照收集一定量的消息,批量发送的方式
      • 收集xxx字节发送
      • 一定时间内发送
  • 读取磁盘文件的数据发送到网络上
    • 传统做法:
      • 操作系统将数据从磁盘中读取文件到内核空间里的页面缓存(内核缓冲区)
      • 应用程序将数据从内核空间读入用户空间的缓冲区
      • 应用程序将读取到的数据写回内核空间并放入socket缓冲区
      • 操作系统将数据从socket缓冲区复制到网卡接口,此时数据才能通过网络发送出去
    • 零拷贝技术(kafka):
      • 操作系统将数据从磁盘读取到文件的内核空间里的页面缓存
      • 操作系统将内核缓冲区数据和应用程序共享(这样就不需要把内核缓冲区的数据拷贝到用户空间,也不需要用户空间再把数据拷贝到内核空间,避免了两次拷贝,内核态与用户态的交互)。
      • 应用程序将数据放入socket缓冲区
      • 操作系统将数据从socket缓冲区复制到网卡接口
    • 例子:假设有10个不同组的消费者(广播,发布订阅模式),一条消息,那么共需要拷贝多少次?
      • 传统做法:(1 + 1 + 1 + 1) * 10 = 40
        • 磁盘->磁盘缓冲区 10次
        • 磁盘缓冲区 -> 用户空间 10次
        • 用户空间 -> 内核空间 10次
        • 内核空间 -> 网卡 10次
      • 零拷贝技术:1 + 1 * 10 = 11
        • 磁盘 -> 磁盘缓冲区 1次(因为共享,下次发送发现磁盘
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

showluu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值