Kafka 3.x.x 入门到精通(08)------对标尚硅谷Kafka教程
- [5. Kafka优化](#5. Kafka优化)
-
- [5.1 资源配置](#5.1 资源配置)
-
- [5.1.1 操作系统](#5.1.1 操作系统)
- [5.1.2 磁盘选择](#5.1.2 磁盘选择)
- [5.1.3 网络带宽](#5.1.3 网络带宽)
- [5.1.4 内存配置](#5.1.4 内存配置)
- [5.1.5 CPU选择](#5.1.5 CPU选择)
- [5.2 集群容错](#5.2 集群容错)
-
- [5.2.1 副本分配策略](#5.2.1 副本分配策略)
- [5.2.2 故障转移方案](#5.2.2 故障转移方案)
- [5.2.3 数据备份与恢复](#5.2.3 数据备份与恢复)
- [5.3 参数配置优化](#5.3 参数配置优化)
- [5.4 数据压缩和批量发送](#5.4 数据压缩和批量发送)
- [6. Kafka常见问题](#6. Kafka常见问题)
-
- [6.1 Kafka都有哪些组件?](#6.1 Kafka都有哪些组件?)
- [6.2 Kafka的LSO、LEO、 HW 的含义?](#6.2 Kafka的LSO、LEO、 HW 的含义?)
- [6.3 Controller选举是怎么实现的?](#6.3 Controller选举是怎么实现的?)
- [6.4 分区副本AR, ISR, OSR的含义?](#6.4 分区副本AR, ISR, OSR的含义?)
- [6.5 Producer生产消息是如何实现的?](#6.5 Producer生产消息是如何实现的?)
- [6.6 Producer ACK应答策略?](#6.6 Producer ACK应答策略?)
- [6.7 Producer 消息重复或消息丢失的原因?](#6.7 Producer 消息重复或消息丢失的原因?)
- [6.8 Consumer消息重复或消息丢失的原因?](#6.8 Consumer消息重复或消息丢失的原因?)
- [6.9 Kafka数据如何保证有序?](#6.9 Kafka数据如何保证有序?)
本文档参看的视频是:
本文档参看的文档是:
- 尚硅谷官方文档,并在基础上修改 完善!非常感谢尚硅谷团队!!!!
在这之前大家可以看我以下几篇文章,循序渐进:
❤️Kafka 3.x.x 入门到精通(01)------对标尚硅谷Kafka教程
❤️Kafka 3.x.x 入门到精通(02)------对标尚硅谷Kafka教程
❤️Kafka 3.x.x 入门到精通(03)------对标尚硅谷Kafka教程
❤️Kafka 3.x.x 入门到精通(04)------对标尚硅谷Kafka教程
❤️Kafka 3.x.x 入门到精通(05)------对标尚硅谷Kafka教程
❤️Kafka 3.x.x 入门到精通(06)------对标尚硅谷Kafka教程
❤️Kafka 3.x.x 入门到精通(07)------对标尚硅谷Kafka教程
5. Kafka优化
5.1 资源配置
5.1.1 操作系统
Kafka的网络客户端底层使用Java NIO的Selector方式,而Selector在Linux的实现是epoll,在Windows上实现机制为select。因此Kafka部署在Linux会有更高效的I/O性能。
数据在磁盘和网络之间进行传输时候,在Linux上可以享受到零拷贝机制带来的快捷和便利高效,而Windows在一定程度上会使用零拷贝操作。
所以建议Kafka部署在Linux操作系统上。
5.1.2 磁盘选择
Kafka 存储方式为顺序读写,机械硬盘的最大劣势在于随机读写慢。所以使用机械硬盘并不会造成性能低下。所以磁盘选用普通机械硬盘即可,Kafka自身已经有冗余机制,而且通过分区的设计,实现了负载均衡的功能。不做磁盘组raid阵列也是可以的。
磁盘空间需要多少,需要根据具体场景进行简单估算
设计场景:日志数据每天向kafka发送1亿条数据,每条数据有两个副本防止数据丢失,数据保存两周,每条消息平均大小为1KB。
-
每天1亿条1KB消息,保存两份,则每天总大小为:
- ( 100000000 ∗ 1 K B ∗ 2 ) / 1024 / 1024 ≈ 200 G B (100000000*1KB*2)/1024/1024≈200GB (100000000∗1KB∗2)/1024/1024≈200GB
-
kafka除了消息数据还有其他类型的数据,故增加10%的冗余空间,则需要220GB
-
两周时间则为 220GB*14≈3TB
-
如果启用压缩,压缩比约在 0.75 左右,则总存储空间规划为3TB*0.75=2.25TB
5.1.3 网络带宽
如果网络为万兆带宽,基本不会出现网络瓶颈,如果数据量特别大,按照下文中的设计场景进行计算。如果网络为百兆或者千兆带宽,在处理较大数据量场景下会出现网络瓶颈,可按照下面的传统经验公式进行计算处理,也可按照下述场景按照自己生产实际情况进行设计。
经验公式: 服务器台数 = 2 × ( 生产者峰值生产速率 × 副本数 ÷ 100 ) + 1 服务器台数 = 2 × (生产者峰值生产速率 × 副本数 ÷ 100) + 1 服务器台数=2×(生产者峰值生产速率×副本数÷100)+1
带宽情况最容易成为 kafka 的瓶颈。
设计场景:如果机房为千兆带宽,我们需要在一小时内处理1TB的数据,需要多少台kafka 服务器?
- 由于带宽为千兆网,1000Mbps=1Gbps,则每秒钟每个服务器能收到的数据量为 1Gb=1000Mb
- 假设 Kafka 占用整个服务器网络的70%(其他 30%为别的服务预留),则Kafka可以使用到700Mb 的带宽,但是如果从常规角度考虑,我们不能总让Kafka顶满带宽峰值,所以需要预留出2/3甚至3/4的资源,也就是说,Kafka单台服务器使用带宽实际应为 700Mb/3=240Mb
- 1 小时需要处理1TB数据, 1 T B = 1024 ∗ 1024 ∗ 8 M b = 8000000 M b 1TB=1024*1024*8Mb=8000000Mb 1TB=1024∗1024∗8Mb=8000000Mb,则一秒钟处理数据量为: 8000000 M b / 3600 s = 2330 M b 8000000Mb/3600s=2330Mb 8000000Mb/3600s=2330Mb 数据。
- 需要的服务器台数为: 2330 M b / 240 M b ≈ 10 台 2330Mb/240Mb≈10 台 2330Mb/240Mb≈10台。
- 考虑到消息的副本数如果为 2,则需要20台服务器,副本如果为3,则需要30台服务器。
5.1.4 内存配置
Kafka运行过程中设计到的内存主要为JVM的堆内存和操作系统的页缓存,每个Broker节点的堆内存建议10-15G内存,而数据文件(默认为1G)的25%在内存就可以了。综合上述,Kafka在大数据场景下能够流畅稳定运行至少需要11G,建议安装Kafka的服务器节点的内存至少大于等于16G。
5.1.5 CPU选择
观察所有的Kafka与线程相关的配置,一共有以下几个
在生产环境中,建议CPU核数最少为16核,建议32核以上,方可保证大数据环境中的Kafka集群正常处理与运行。
5.2 集群容错
5.2.1 副本分配策略
Kafka采用分区机制对数据进行管理和存储,每个Topic可以有多个分区,每个分区可以有多个副本。应根据业务需求合理配置副本,一般建议设置至少2个副本以保证高可用性。
5.2.2 故障转移方案
当Kafka集群中的某个Broker节点发生故障时,其负责的分区副本将会被重新分配到其他存活的Broker节点上,并且会自动选择一个备份分区作为新的主分区来处理消息的读写请求。
5.2.3 数据备份与恢复
Kafka采用基于日志文件的存储方式,每个Broker节点上都有副本数据的本地备份。在数据备份方面,可以通过配置Kafka的数据保留策略和数据分区调整策略来保证数据的持久性和安全性;在数据恢复方面,可以通过查找备份数据并进行相应的分区副本替换来恢复数据。
5.3 参数配置优化
参数名 | 默认参数值 | 位置 | 优化场景 | 备注 |
---|---|---|---|---|
num.network.threads | 3 | 服务端 | 低延迟 | |
num.io.threads | 8 | 服务端 | 低延迟 | |
socket.send.buffer.bytes | 102400(100K) | 服务端 | 高吞吐 | |
socket.receive.buffer.bytes | 65536(64K) | 服务端 | 高吞吐场景 | |
max.in.flight.requests.per.connection | 5 | 生产端 | 幂等 | |
buffer.memory | 33554432(32M) | 生产端 | 高吞吐 | |
batch.size | 16384(16K) | 生产端 | 提高性能 | |
linger.ms | 0 | 生产端 | 提高性能 | |
fetch.min.bytes | 1 | 消费端 | 提高性能 | 网络交互次数 |
max.poll.records | 500 | 消费端 | 批量处理 | 控制批量获取消息数量 |
fetch.max.bytes | 57671680 (55M) | 消费端 | 批量处理 | 控制批量获取消息字节大小 |
5.4 数据压缩和批量发送
通过压缩和批量发送可以优化Kafka的性能表现。Kafka支持多种数据压缩算法,包括Gzip、Snappy、LZ4和zstd。在不同场景下,需要选择合适的压缩算法,以确保性能最优。
下面的表格为网络上不同压缩算法的测试数据,仅作参考
压缩算法 | 压缩比率 | 压缩效率 | 解压缩效率 |
---|---|---|---|
snappy | 2.073 | 580m/s | 2020m/s |
lz4 | 2.101 | 800m/s | 4220m/s |
zstd | 2.884 | 520m/s | 1600m/s |
从表格数据可以直观看出,zstd有着最高得压缩比,而LZ4算法,在吞吐量上表现得非常高效。对于Kafka而言,在吞吐量上比较:lz4 > snappy>zstd>gzip。
而在压缩比上:zstd > lz4 > gzip > snappy
Kafka支持两种批处理方式:异步批处理和同步批处理。在不同场景下,需要选择合适的批处理方式,进行性能优化。同时需要合理设置批处理参数,如batch.size、linger.ms等。
6. Kafka常见问题
6.1 Kafka都有哪些组件?
生产者、 消费者、管理员 。。。。。。
6.2 Kafka的LSO、LEO、 HW 的含义?
LSO,LEO,HW其实都是kafka中的偏移量。只不过它们代表的含义是不相同的。
这里的LSO有两层含义:
- 一个是Log Start Offset, 一个是Log Stable Offset,第一个表示数据文件的起始偏移量,同学们还记的,咱们的log文件的文件名吗,文件名中的那个数字就是当前文件的LSO
- 第二个表示的位移值是用来判断事务型消费者的可见性,就是所谓的事务隔离级别,一个叫read_commited, 一个叫read_uncommited。当然了,如果你的生产者或消费者没有使用事务,那么这个偏移量没有任何的意义。
LEO 表示 Log End Offset,就是下一个要写入的数据偏移量,所以这个偏移量的数据是不存在的
HW表示高水位线偏移量的意思。是kafka为了数据的一致性所增加的一种数据隔离方式。简单的理解,就是消费者只能消费到,小于高水位线偏移量的数据。
6.3 Controller选举是怎么实现的?
这里的controller选举主要指的还是Kafka依赖于ZK实现的controller选举机制,也就是说,kafka的所有broker节点会监听ZK中的一个controller临时节点,如果这个节点没有创建,那么broker就会申请创建,一旦创建成功,那么创建成功的broker就会当选为集群的管理者controller,一旦失去了和ZK的通信,那么临时节点就会消失,此时就会再次进行controller的选举,选举的规则是完全一样的,一旦新的controller选举,那么controller纪元会被更新。
6.4 分区副本AR, ISR, OSR的含义?
这里的AR可以理解为分区的所有副本集合。而ISR表示的就是正在同步数据的副本列表,列表的第一个就是分区的Leader副本,其他的副本就是Follower副本。
OSR就是没有处于同步数据的副本列表。
一旦副本拉取数据满足了特点的条件,那么会从OSR中移除并增加到ISR中。同样,如果副本没有拉取数据满足了特定的条件,就会从ISR中移除,放入到OSR中。这就是所谓的ISR列表的收缩和扩张。kafka使用这种ISR的方式有效的权衡了数据可靠性和性能之间的关系
6.5 Producer生产消息是如何实现的?
这里所谓的生产消息。指的就是生产者客户端的生产数据的基本流程。咱们之前的图形中,就把这个流程已经画出来了。我相信图形比文字应该更容易记忆,所以请大家参考前面的生产者组件。
6.6 Producer ACK应答策略?
ACK应答机制其实就是生产者发送数据后kafka接收确认方式。Kafka确认的方式有3种:
-
第一种是当生产者数据发送到网络客户端的缓冲区后,Kafka就认为数据收到了,那么就会进行响应,也就是应答。但是这种方式,数据可靠性是非常低的,因为不能保证数据一定会写入日志文件。但是发送效率影响不大。
-
第二种是当主题分区的Leader副本将数据写入日志后,Kafka才认为数据收到了,然后再对生产者进行响应。这种方式,发送数据的效率会降低,但是可靠性会高一些。而可靠性最高的就是第三种方式
-
第三种方式就是主题分区的ISR副本列表种所有的副本都已经将数据写入日志后。Kafka才认为数据收到了,然后再对生产者进行响应。这种方式,发送数据的效率会非常低。生产者对象可以根据生产环境和业务要求对应答机制进行配置。
三种方式分别对应0,1和-1(all)。另外,生产者数据幂等性操作要求ACK应答处理机制必须为-1,而ACK的参数默认值也是-1
6.7 Producer 消息重复或消息丢失的原因?
Producer消息重复和消息丢失的原因,主要就是kafka为了提高数据可靠性所提供的重试机制,如果禁用重试机制,那么一旦数据发送失败,数据就丢失了。而数据重复,恰恰是因为开启重试机制后,如果因为网络阻塞或不稳定,导致数据重新发送。那么数据就有可能是重复的。所以kafka提供了幂等性操作解决数据重复,并且幂等性操作要求必须开启重试功能和ACK取值为-1,这样,数据就不会丢失了。
kafka提供的幂等性操作只能保证同一个生产者会话中同一个分区中的数据不会重复,一旦数据发送过程中,生产者对象重启,那么幂等性操作就会失效。那么此时就需要使用Kafka的事务功能来解决跨会话的幂等性操作。但是跨分区的幂等性操作是无法实现的。(引入了事务)
6.8 Consumer消息重复或消息丢失的原因?
这里主要说的是消费者提交偏移量的问题。消费者为了防止意外情况下,重启后不知道从哪里消费,所以会每5s
时间自动保存偏移量。但是这种自动保存偏移量的操作是基于时间的,一旦未达到时间,消费者重启了,那么消费者就可能重复消费数据。
Kafka提供自动保存偏移量的功能的同时,也提供了手动保存偏移量的2种方式,一个是同步提交,一个是异步提交。本质上都是提交一批数据的最后一个偏移量的值,但是可能会出现,偏移量提交完毕,但是拉取的数据未处理完毕,消费者重启了。那么此时有的数据就消费不到了,也就是所谓的数据丢失。
6.9 Kafka数据如何保证有序?
这里的有序我们要考虑的点比较多,但是总结起来就是生产有序,存储有序,消费有序。
所谓的生产有序就是生产者对象需要给数据增加序列号用于标记数据的顺序,然后再服务端进行缓存数据的比对,一旦发现数据是乱序的,那么就需要让生产者客户端进行数据的排序,然后重新发送数据,保证数据的有序。不过这里的缓存数据的比对,最多只能有5条数据比对,所以生产者客户端需要配置参数,将在途请求缓冲区的请求队列数据设置为5,否则数据依然可能乱序。因为服务端的缓存数据是以分区为单位的,所以这就要求生产者客户端需要将数据发送到一个分区中,如果数据发送到多个分区,是无法保证顺序的。这就是生产有序的意思。
那存储有序指的是kafka的服务端获取数据后会将数据顺序写入日志文件,这样就保证了存储有序,当然也只能是保证一个分区的数据有序。
接下来就是消费有序。所谓的消费有序其实就是kafka在存储数据时会给数据增加一个访问的偏移量值,那消费者只能按照偏移量的方式顺序访问,并且一个分区的数据只能被消费者组中的一个消费者消费,那么按照偏移量方式的读取就不会出现乱序的情况。
所以综合以上的描述。Kafka就能够实现数据的有序。