因为kafka服务端代码是Scala语言开发的,因此属于JVM系的大数据框架,目前部署最多的3类操作系统主要由Linux ,OS X 和Windows,但是部署在Linux数量最多,为什么呢?因为I/O模型的使用和数据网络传输效率两点。
我们公司物联网平台每天大约能够产生一亿条消息,假设副本replica设置为2 (其实我们设置为3),数据留存时间为1周,平均每条上报事件消息为1K左右,那么每天产生的消息总量为:1亿 乘 2 乘 1K 除以 1000 除以 1000 =200G磁盘。预留10%的磁盘空间,为210G。一周大约为1.5T。采用压缩,平均压缩比为0.5,整体磁盘容量为0.75T。 关联因素主要有:
kafka对于内存的使用,并不过多依赖JVM 内存,而是更多的依赖操作系统的页缓存,consumer若命中页缓存,则不用消耗物理I/O操作。一般情况下,java堆内存的使用属于朝生夕灭的,很快会被GC,一般情况下,不会超过6G,对于16G内存的机器,文件系统page cache 可以达到10-14GB。
kafka不属于计算密集型系统,因此CPU核数够多就可以,而不必追求时钟频率,因此核数选择最好大于8。
带宽主要有1Gb/s 和10 Gb/s 。我们可以称为千兆位网络和万兆位网络。举例如下: 我们的物联网系统一天每小时都要处理1Tb的数据,我们选择1Gb/b带宽,那么需要选择多少机器呢?
kafka-producer-perf-test :是kafka提供的测试Producer性能脚本,通过脚本,可以计算出Producer在一段时间内的平均延时和吞吐量。
在kafka安装目录下面执行如下命令,生产环境中尽量让脚本运行较长的时间,才会有意义:
bin/kafka-producer-perf-test.sh --topic test --num-records 500000 --record-size 200 --througthput -1 --producer-props bootstrap.servers=bd-master:9092,bd-slave1=9092,bd-slave3=9092 acks=1
500000 records sent ,41963 records/sec (8.00 MB/sec),2362.85 ms/avg latency ,3513.00 ms max latency ,2792ms 50h ,3144ms 95th ,3364 ms 99h,3503ms 99.9th
看到上面的结果肯定蒙了,看我细细讲来: kafka 的平均吞吐量是8.00 MB/sec ,即占用64Mb/s左右的带宽,平均每一秒发送41963条消息。平均延时为2362.85 ms,最大延时为3513.00 ms,95%的消息发送需要3144ms,99%的消息发送需要3364ms,99.9%的消息发送需要3503ms。
我们总共测试500万条数据量 bin/kafka-consumer-perfs-test.sh --broker-list bd-master:9092,bd-slave1=9092,bd-slave3=9092 --message-size 200 --messages 500000 --topic test
2018-10-28 9:39:02 95.4188 92.2313 500271 484289 看到上面的结果肯定蒙了,看我细细讲来: 该环境下,1s内总共消费了95.4188MB消息,吞吐量为92.2313MB/s,也即736Mb/s。
在消息被认为是“已提交”之前,producer需要leader确认的produce请求的应答数。该参数用于控制消息的持久性,目前提供了3个取值:
acks = 0: 表示produce请求立即返回,不需要等待leader的任何确认。这种方案有最高的吞吐率,但是不保证消息是否真的发送成功。
acks = -1: 表示分区leader必须等待消息被成功写入到所有的ISR副本(同步副本)中才认为produce请求成功。这种方案提供最高的消息持久性保证,但是理论上吞吐率也是最差的。
acks = 1: 表示leader副本必须应答此produce请求并写入消息到本地日志,之后produce请求被认为成功。如果此时leader副本应答请求之后挂掉了,消息会丢失。这是个这种的方案,提供了不错的持久性保证和吞吐。
如果要较高的持久性要求以及无数据丢失的需求,设置acks = -1。其他情况下设置acks = 1
该参数用于指定Producer端用于缓存消息的缓冲区大小,单位为字节,默认值为:33554432合计为32M。kafka采用的是异步发送的消息架构,prducer启动时会首先创建一块内存缓冲区用于保存待发送的消息,然后由一个专属线程负责从缓冲区读取消息进行真正的发送。
producer压缩器,目前支持none(不压缩),gzip,snappy和lz4。
基于公司物联网平台,试验过目前lz4的效果最好。当然2016年8月,FaceBook开源了Ztandard。官网测试: Ztandard压缩率为2。8,snappy为2.091,LZ4 为2.101 。
producer重试的次数设置。重试时producer会重新发送之前由于瞬时原因出现失败的消息。瞬时失败的原因可能包括:元数据信息失效、副本数量不足、超时、位移越界或未知分区等。倘若设置了retries > 0,那么这些情况下producer会尝试重试。
producer都是按照batch进行发送的,因此batch大小的选择对于producer性能至关重要。producer会把发往同一分区的多条消息封装进一个batch中,当batch满了后,producer才会把消息发送出去。但是也不一定等到满了,这和另外一个参数linger.ms有关。默认值为16K,合计为16384.
producer是按照batch进行发送的,但是还要看linger.ms的值,默认是0,表示不做停留。这种情况下,可能有的batch中没有包含足够多的produce请求就被发送出去了,造成了大量的小batch,给网络IO带来的极大的压力。
producer的IO线程在单个Socket连接上能够发送未应答produce请求的最大数量。增加此值应该可以增加IO线程的吞吐量,从而整体上提升producer的性能。不过就像之前说的如果开启了重试机制,那么设置该参数大于1的话有可能造成消息的乱序。
调整partition可以直接执行如下命令:
./kafka-topics.sh --alter --topic topicName --zookeeper $ZK_HOST_NODE --partitions partitionNum
注意替换topicName、$ZK_HOST_NODE和partitionNum三个参数。
调整replica-factor需要先创建一个json描述文件replica.json,大致如下:
{
"version": 1,
"partitions": [
{
"topic": "topicName",
"partition": 0,
"replicas": [
,
]
},
{
"topic": "topicName",
"partition": 1,
"replicas": [
,
]
},
{
"topic": "topicName",
"partition": 2,
"replicas": [
,
]
}
]
}
在描述文件中说明分区和副本所在broker的Id的映射。
而后在replica.json所在的位置执行如下命令:
$KAFKA_HOME/bin/kafka-reassign-partitions.sh --zookeeper $ZK_HOST_NODE --reassignment-json-file replica.json --execute
另外,kafka-manager是个好东西,可以直接在界面上完成partiton数目的调整。可惜不能调整replica-factor。
原文:https://www.cnblogs.com/bigben0123/p/10862242.html