(一)Kafka生产优化之如何全面规划 Kafka 的线上部署方案
共 5906字,需浏览 12分钟
·
2022-02-18 15:35
如何全面规划 Kafka 的线上部署方案
一、操作系统
先说结论:建议部署在 Linux 上。
由于以下三个原因
- I/O 模型
- 数据网络传输效率
- Kafka的社区支持度
① I/O 模型层面
I/O 模型是操作系统执行 IO 指令的方法。
分别有五种类型
- 阻塞式 IO
- 非阻塞式 IO
- IO 多路复用
- 信号驱动 IO
- 异步 IO
可以简单认为后面的模型比前面的模型要更高效,epoll 模型介于第三种和第四种之间,select 属于第三种。
Kafka 的客户端底层使用了 Java 的 selector,而 selector 在 Linux 的实现是 epoll,在 Windows 上实现机制为 select。因此 Kafka 部署在 Linux 会有更高效的 I/O 性能。
② 网络传输效率
数据在磁盘和网络之间进行传输时候,在 Linux 上可以享受到零拷贝机制带来的快捷和便利高效,而 Windows 则不行。
③ 社区支持度
Linux 平台出现的问题,社区会优先解决。
Windows 平台出问题,一般不会解决。
二、磁盘
先说结论:
- 选用普通机械硬盘即可。
- 如果资金充裕可以将硬盘组 Raid;
- 如果资金紧张,不使用 Raid 方案也可以保证读写性能。
问题一:选用普通机械硬盘还是固态硬盘?
使用普通机械硬盘即可,Kafka 存储方式为顺序读写,机械硬盘的最大劣势在于随机读写慢。所以使用机械硬盘并不会造成性能低下。
问题二:是否需要将磁盘组 raid?
raid 的优势在于:提供冗余磁盘存储空间,提供负载均衡。
但是 Kafka 自身已经有冗余机制,而且通过分区的设计,实现了负载均衡的功能。所以如果有经济能力可以放在组 raid 的存储空间上,如果考虑性价比,可以直接不做 raid。
三、磁盘容量
先说结论,需要考虑的因素有以下几个:
- 每天的消息数
- 每条消息大小
- 副本数
- 消息保留时间
- 是否启用压缩
问题讨论:Kafka 需要多大的存储空间?
设计场景:日志数据每天向 kafka 发送 1 亿条数据,每条数据有两个副本防止数据丢失,数据保存两周,每条消息平均大小为 1KB。
每天 1 亿条 1KB 消息,保存两周两份,则每天总大小为:1 亿*1KB*2/1000/1000=200GB
kafka 除了消息数据还有其他类型的数据,故增加 10%的冗余空间,则需要 220GB
两周时间则为 220GB*14≈3TB
如果启用压缩,压缩比约在 0.75 左右,则总存储空间规划为 3TB*0.75=2.25TB
四、带宽
先说结论:
如果网络为万兆带宽,基本不会出现网络瓶颈,如果数据量特别大,按照下文中的设计场景进行计算。
如果网络为百兆或者千兆带宽,在处理较大数据量场景下会出现网络瓶颈,可按照下面的传统经验公式进行计算处理,也可按照下述场景按照自己生产实际情况进行设计。
经验公式:
服务器台数 = 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 数据,1TB=1024*1024*8Mb=8000000Mb,则一秒钟处理数据量为:8000000Mb/3600s=2330Mb 数据。
需要的服务器台数为:2330Mb/240Mb≈10 台。
考虑到消息的副本数如果为 2,则需要 20 台服务器,副本如果为 3,则需要 30 台服务器。
五、内存
先说结论:建议安装 Kafka 的服务器节点的内存至少大于等于 16G。
Kafka 的内存由堆内存+页缓存组成。
① 堆内存配置
建议每个节点 10G-15G
需要在kafka-server-start.sh
进行修改
if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then
export KAFKA_HEAP_OPTS="-Xmx10G -Xms10G"
fi
② Kafka 的 GC 情况查询
通过 jps 命令查看 Kafka 的进程号
[atguigu@hadoop102 kafka]$ jps
2321 Kafka
5255 Jps
1931 QuorumPeerMain
根据 Kafka 进程号,查看 Kafka 的 GC 情况
[atguigu@hadoop102 kafka]$ jstat -gc 2321 1s 10
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
0.0 7168.0 0.0 7168.0 103424.0 60416.0 1986560.0 148433.5 52092.0 46656.1 6780.0 6202.2 13 0.531 0 0.000 0.531
0.0 7168.0 0.0 7168.0 103424.0 60416.0 1986560.0 148433.5 52092.0 46656.1 6780.0 6202.2 13 0.531 0 0.000 0.531
0.0 7168.0 0.0 7168.0 103424.0 60416.0 1986560.0 148433.5 52092.0 46656.1 6780.0 6202.2 13 0.531 0 0.000 0.531
0.0 7168.0 0.0 7168.0 103424.0 60416.0 1986560.0 148433.5 52092.0 46656.1 6780.0 6202.2 13 0.531 0 0.000 0.531
0.0 7168.0 0.0 7168.0 103424.0 60416.0 1986560.0 148433.5 52092.0 46656.1 6780.0 6202.2 13 0.531 0 0.000 0.531
0.0 7168.0 0.0 7168.0 103424.0 61440.0 1986560.0 148433.5 52092.0 46656.1 6780.0 6202.2 13 0.531 0 0.000 0.531
0.0 7168.0 0.0 7168.0 103424.0 61440.0 1986560.0 148433.5 52092.0 46656.1 6780.0 6202.2 13 0.531 0 0.000 0.531
0.0 7168.0 0.0 7168.0 103424.0 61440.0 1986560.0 148433.5 52092.0 46656.1 6780.0 6202.2 13 0.531 0 0.000 0.531
0.0 7168.0 0.0 7168.0 103424.0 61440.0 1986560.0 148433.5 52092.0 46656.1 6780.0 6202.2 13 0.531 0 0.000 0.531
0.0 7168.0 0.0 7168.0 103424.0 61440.0 1986560.0 148433.5 52092.0 46656.1 6780.0 6202.2 13 0.531 0 0.000 0.531
名词解释:
- S0C:第一个幸存区的大小
- S1C:第二个幸存区的大小
- S0U:第一个幸存区的使用大小
- S1U:第二个幸存区的使用大小
- EC:伊甸园区的大小
- EU:伊甸园区的使用大小
- OC:老年代大小
- OU:老年代使用大小
- MC:方法区大小
- MU:方法区使用大小
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- YGC:年轻代垃圾回收次数
- YGCT:年轻代垃圾回收消耗时间
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- GCT:垃圾回收消耗总时间
③ Kafka 的堆内存占用查询
根据 Kafka 进程号,查看 Kafka 的堆内存
[atguigu@hadoop102 kafka]$ jmap -heap 2321
Attaching to process ID 2321, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.212-b10
using thread-local object allocation.
Garbage-First (G1) GC with 8 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 2147483648 (2048.0MB)
NewSize = 1363144 (1.2999954223632812MB)
MaxNewSize = 1287651328 (1228.0MB)
OldSize = 5452592 (5.1999969482421875MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 1048576 (1.0MB)
Heap Usage:
G1 Heap:
regions = 2048
capacity = 2147483648 (2048.0MB)
used = 246367744 (234.95458984375MB)
free = 1901115904 (1813.04541015625MB)
11.472392082214355% used
G1 Young Generation:
Eden Space:
regions = 83
capacity = 105906176 (101.0MB)
used = 87031808 (83.0MB)
free = 18874368 (18.0MB)
82.17821782178218% used
Survivor Space:
regions = 7
capacity = 7340032 (7.0MB)
used = 7340032 (7.0MB)
free = 0 (0.0MB)
100.0% used
G1 Old Generation:
regions = 147
capacity = 2034237440 (1940.0MB)
used = 151995904 (144.95458984375MB)
free = 1882241536 (1795.04541015625MB)
7.471886074420103% used
13364 interned Strings occupying 1449608 bytes
④ Kafka 页缓存
页缓存是 Linux 系统服务器的内存。我们只需要保证 1 个 segment(默认值为 1G)中 25%的数据在内存中就好。
综合上述,Kafka 在大数据场景下能够流畅稳定运行至少需要 11G,建议安装 Kafka 的服务器节点的内存至少大于等于 16G。
六、CPU 选择
先说结论:建议 Kafka 服务器 CPU 核数在 32 以上。
观察所有的 Kafka 与线程相关的配置,一共有以下几个
参数名 | 备注 | 默认值 |
---|---|---|
num.network.threads | 服务器用于接收来自网络的请求并向网络发送响应的线程数 | 3 |
num.io.threads | 服务器用于处理请求的线程数,其可能包括磁盘 I/O | 8 |
num.replica.fetchers | 副本拉取线程数,调大该值可以增加副本节点拉取的并行度 | 1 |
num.recovery.threads.per.data.dir | 每个数据目录在启动时用于日志恢复和在关闭时刷新的的线程数 | 1 |
log.cleaner.threads | 用于日志清理的后台线程数 | 1 |
background.threads | 用于各种后台处理任务的线程数 | 10 |
其中,第 4 个参数在启动和关闭时候才会使用,日志清理也是在一定时间间隔才会有。所以,常驻线程应该有至少 22 个以上。
在生产环境中,建议 CPU 核数最少为 16 核,建议 32 核以上,方可保证大数据环境中的 Kafka 集群正常处理与运行。