2024年《Apache Kafka实战》笔记_apache kafka实战 下载(1),字节跳动厂内部超高质量Flutter+Kotlin笔记

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

吞吐量/延时

消息持久化

负载均衡和故障转移

伸缩性

Kafka架构

消息

基本概念

Kafka使用场景

Kafka Producer

Kafka Consumer

Kafka部署

操作系统选型

磁盘规划

磁盘容量规划

内存规划

CPU规划

带宽规划

Kafka实践

环境部署

创建kafka主题(topic)

测试消息发送和消费

参数配置


序言

有时候再去看原来看过的书,发现有些东西仍然是似曾相识却又一点都不记得,还是再次去把它捡起来吧,开发过程中可能没有怎么使用到kafka,不过不要等到用时再手忙脚乱。

Kafka即高性能的消息发送与高性能的消息消费的消息引擎系统。

Kafka设计概要

消息引擎

设计一个消息引擎系统(也有称消息队列或消息中间件)需要考虑的两个重要因素:

  • 消息设计:考虑语义的清晰和格式上的通用型,通常采用结构化设计。如SOAP协议中的消息采用XML格式,Web Service支持JSON格式的消息,Kafka的消息则使用二进制来保存。
  • 传输协议设计:消息传输协议制定了消息在不同系统之间的传输方式。主流协议包含AMQP、Web Service+SOAP以及微软的MSMQ等。

传输协议作为一个基础构建块(building block),其服务于消息引擎系统实现的消息引擎范型(给予网络的架构范型,描述了消息引擎系统的两个不同子部分是如何互联且交互的)。

常见的消息引擎范型有:

  • 消息队列(message queue)模型:基于队列提供消息传输服务,多用于进程间通信以及线程间通信。
  • 发布/订阅(punish/subscribe)模型:topic可以理解为逻辑语义相近的消息的容器,发布者将消息生产出来发送到指定topic,消费者订阅了该topic则可以接收到该topic下的所有消息。

下面是基于队列的消息引擎模型:

下面是基于发布/订阅的消息引擎模型:

吞吐量/延时

Kafka的设计主要是根据吞吐量和延时考虑,吞吐量即每秒能够处理的消息数或者每秒能够处理的字节数,延时可以表示为客户端发起请求与服务器处理请求并发送响应给客户端之间的时间。kafka之所以能够做到高吞吐、低延时是由于它对磁盘的使用方法不同。Kafka持久化所有数据到磁盘本质上是每次写入操作都只是把数据写入到操作系统的页缓存(page cache)中,然后由操作系统自行决定什么时候把页缓存中的数据回写到磁盘上。这样做的优势主要是:

  • 操作系统页缓存是在内存中分配的,所以消息写入速度快。
  • Kafka不必直接与底层的文件系统打交道。所有繁琐的I/O操作都交由操作系统来处理。
  • Kafka写入操作采用追加写入(append)的方式,避免了磁盘随机写操作。

普通SAS随机读/写的吞吐量很慢,但是磁盘的顺序读/写其实非常快,它的速度甚至可以匹配内存的随机I/O速度。鉴于这一特点,Kafka在设计时采用追加写入的方式。

同样,Kafka读取消息时会首先尝试从OS的页缓存中读取,如果命中便把消息经页缓存直接发送到网络的Socket上。这个过程就是利用Linux平台的sendfile系统调用完成的,也叫零拷贝(Zero Copy)技术。

在零拷贝技术出现之前,一个I/O操作会将同一份数据进行多次拷贝,如下图——无零拷贝数据传输,传输过程中涉及内核态和用户态的上下文切换,CPU的开销非常大,因此极大地限制了OS的数据传输能力。其中DMA拷贝也叫直接存储器访问技术(Direct Memory Access)拷贝。

零拷贝技术很好的改善了这个问题:在内核驱动程序处理I/O数据的时候,它不再需要进行上下文切换,节省了内核缓冲区与用户态应用程序缓冲区之间的数据拷贝,同时它利用直接存储器访问技术执行I/O操作,因此也避免了OS内核缓冲区之间的数据拷贝。如下图,其中transferTo方法是java.nio.channels.FileChannel接口的方法(Linux提供的sendfile系统调用)。

综上所述,Kafka就是依靠下面四点达到高吞吐量、低延时的设计目标。

  • 大量使用操作系统页缓存,内存操作速度快且命中率高。
  • Kafka不直接参与物理I/O操作,而是交由最擅长此事的操作系统来完成。
  • 采用追加写入方式(顺序读写),摒弃了缓存的磁盘随机读/写操作。
  • 使用以sendfile为代表的零拷贝技术加强网络间的数据传输效率。

消息持久化

Kafka消息持久化的好处是:

  • 解耦消息发送和消息消费。
  • 实现灵活的消息处理

负载均衡和故障转移

负载均衡(Load Balancing):让系统的负载根据一定的规则均衡地分配在所有参与工作的服务器上,从而最大限度地提升系统整体的运行效率。leader选举算法来实现。

故障转移(fail-over):当服务器意外中止时,整个集群可以快速地检测到该失效(failure),并立即将服务器上的应用或服务自动转移到其他服务器上。通常以“心跳”或“会话”的机制实现。

伸缩性

伸缩性(scalability)表示向分布式系统中增加额外的计算资源(比如CPU、内存、存储或带宽)时吞吐量提升的能力。举个例子,对于计算密集型(computation-intensive)的业务而言,CPU的消耗一定时最大的,这类系统上的操作我们称之为CPU-bound。那么如果一个CPU的运算能力是U,我们自然希望两个CPU的运算能力是2U,即可以线性地扩容计算能力,这种线性伸缩性是最理想的状态,但实际中几乎不可能达到,毕竟分布式系统中有很多隐藏的“单点”瓶颈制约了这种线性的计算能力扩容。阻碍线性扩容的一个很常见的因素就是状态的保存。Kafka服务器上的状态统一交由Zookeeper保存,这样整个集群的服务器之间就无须繁重的状态共享,极大地降低了维护复杂度。

Kafka架构

Kafka随着不断发展,把交由下游数据处理平台的事情自己做,演进成了流式处理组件。其架构图如下,Kafka服务器官方名称broker。

消息

Kafka的消息格式由很多字段组成,下面以V1版本消息格式为例,消息头部包括CRC码、消息版本号、属性、时间戳、键长度和消息体长度等信息。CRC循环冗余校验码、版本号比较常见,下面介绍一下其他字段:

  • 属性:8bit(1B即1byte,1B=8bit)的属性用于保存消息的压缩类型,压缩类型只用到了最低的三位,目前支持的4种压缩类型:0(无压缩),1(GZIP),2(Snappy)和3(LZ4)。
  • 时间戳(TimeStamp):消息发送时间戳,用于流式处理及其他依赖时间的处理语义,默认当前时间。
  • Key:消息键,对消息做partition时使用,即决定消息被保存在某topic下的哪个partition。
  • Value:消息体,保存实际的消息数据。

Kafka使用紧凑的二进制字节数组来保存上面的字段,如果要使用Java对象保存上面的消息格式,则如下,

public class Message {
    //循环冗余校验码
    private CRC32 crc;
    //版本号
    private short version;
    //编码类开关
    private boolean codecEnabled;
    //编码类序数
    private short codecClassOrdinal;
    //消息键,对消息做partition时使用,即决定消息被保存在某topic下的哪个partition
    private String key;
    //消息体,保存实际的消息数据
    private String value;
}

看CRC32源码中的crc是int类型占用4个字节,short类型占用2个字节,boolean类型占用1个字节(占用1个字节和占用4个字节取决于JVM),String看具体字符串内容,所以一个Message类的实例大概需要消耗40个字节左右,其中7字节只是为了补齐(原因是对象由8字节markword + 8字节或4字节classPointer+instance data+padding补充8的倍数字节)。并且,Java的操作系统通常默认开启了页缓存机制,也就是说保存的对象很有可能在页缓存中还保留一份,这造成了极大的资源浪费。因此Kafka在消息设计时避开了繁重的Java堆上内存分配,直接使用紧凑的二进制字节数组ByteBuffer而不是独立的对象,因此至少能够访问多一倍的可用内存。除此之外,当出现kafka broker进程崩溃时,页缓存的数据不会像堆内存上的数据消失。

基本概念

主题(topic):逻辑概念,代表一类消息,也可以认为是消息被发送到的地方。通常用topic区分实际业务,不同业务使用不同的topic。

分区(partition):kafka采用topic-partition-message的三级结构来分散负载,每个Kafka tpic都由若干个partition组成。

位移(offset):topic partition下的每条消息都被分配一个位移值。每条消息在某个partition的位移是固定的,但消息该partition的消费者的位移会随着消费进度不断前移。

副本(replica):partition是有序消息日志,分布式系统要实现高可靠性就的备份日志(replica)防止数据丢失。副本分两类:领导者副本(leader replica)和追随者副本(follower replica)。follower replica不负责响应客户端发来的消息写入和消费请求,它只是被动地向leader replica获取数据,而一旦leader replica所在的broker宕机,Kafka会从剩余的replica中选举出新的leader继续提供服务。

领导者(leader)和追随者(follower):与传统主备系统(Master-Slave,如Mysql)不同的是,Leader-Follower系统中通常只有leader对外提供服务,follower只是被动地追随leader的状态,保持与leader的同步。

ISR(in-sync replica):与leader replica保持同步的replica集合。Kafka为partition动态维护一个replica集合,该集合中的所有replica(含leader replica)保存的消息日志都与leader replica保持同步状态。只有这个集合中的replica才能被选举为leader,也只有该集合中所有replica都收到了同一条消息,Kafka才会将该消息置于“已提交”状态,即认为这条消息发送成功。Kafka对于没有提交成功的消息不做任何交付保证,它只保证在ISR存活的情况下”已提交“的消息不会丢失。

Kafka使用场景

  • 消息传输:替代传统的消息总线(message bus)或消息代理(message broker),解耦生产者和消费者以及批量处理消息。
  • 网站行为日志追踪:收集并分析用户的点击流数据。
  • 审计数据收集:对关键的操作和运维进行监控和审计。
  • 日志收集:对企业产生的服务日志进行全量收集,并集中送往下游的分布式存储中(比如HDFS(Hadoop Distributed File System)等)。
  • Event Sourcing:它是领域驱动设计(Domain-Driven Design,DDD)的名词,使用事件序列来表示状态变更。
  • 流式处理:比如Kafka社区推出的流式处理组件Kafka Streams。

Kafka Producer

Kafka生产者在经过几个版本的重写后,降低了系统的维护成本,它的整体工作流程如下图,它将用户待发送的信息封装成一个ProducerRecord对象,然后使用KafkaPrducer.send方法进行发送。KafkaProducer拿到消息后先对其进行序列化,然后结合本地缓存的元数据信息确立目标分区,最后写入内存缓冲区。

Producer的几个特点:

  • 发送过程被划分到两个不同的线程:用户主线程和Sender I/O线程,逻辑更易把控。
  • 完全是异步发送消息,并提供回调机制(callback)用于判断发送是否成功。
  • 分批机制(batching),每个批次中包括多个发送请求,提升整体吞吐量。
  • 合理的分区策略:对于没有指定key的消息旧版本的Producer策略是默认一段时间内将消息发送到固定分区,这容易造成消息倾斜(skewed)。新版本的Producer策略是采用轮询方式,消息发送更均匀化。
  • 底层使用基于Java Selector的网络客户端,结合Java的Future实现更加健壮和优化的声明周期管理。

Kafka Consumer

在旧版本的Consumer中,消费位移(offset)的保存与管理都是依托于Zookeeper来完成的,当数据量很大且消费频繁时,Zookeeper的读/写性能往往容易成为系统瓶颈。新版本的Zookeeper位移的管理和保存不再依赖Zookeeper。

Kafka Consumer的实现依赖中,比较重要的是KafkaConsumer.poll方法,它是实现消息消费的主要逻辑入口方法。新版本的Consumer摒弃旧版本多线程消费不同分区的思想,采用类似于Linux epoll的轮询机制,使得Consumer只使用一个线程就可以管理不同broker的多个Socket,既减少了线程间的开销成本,又简化了系统设计。

Consumer的几个特点:

  • 单线程设计——单个consumer线程可以管理多个分区的消费Socket连接,极大地简化了实现。
  • 位移提交与保存交由Kafka来处理——位移不再保存在Zookeeper中,而是单独保存在Kafka的内部topic中。
  • 消费者组的集中式管理——新版本的Consumer使用集中式协调者(coordinator)角色去管理整个消费者组(consumer group)的成员。

Kafka部署

kafka环境部署我们需要考虑多种因素,如操作系统、磁盘规划、容量规划、内存规划、带宽规划等。

操作系统选型

目前部署Kafka最多的3类操作系统分别是Linux、OS X 和 Windows,其中部署在Linux上的最多,Linux系统更加适合部署Kafka,主要是由于两个原因:I/O模型的使用和数据网络传输效率。

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

转存中…(img-CX0YcKvW-1715710245090)]
[外链图片转存中…(img-Ac2RhnA9-1715710245091)]
[外链图片转存中…(img-Y8bE9bI2-1715710245091)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值