kafka 深入浅出

kafka 零拷贝

在这里插入图片描述

consumer group coondinator机制

coondinator如何选择的? broker里面的其中一台服务器。
consumer group:
group. id: my_conumser -> my consumer hash -> 求出来就是—个数字
数字/50 =>获取到 0-49的这样的一个数。比如数就是8,
然后就在找到 __consumer_offets的partition 8 的leader partition在
哪台服务器上面。那台就是coondinator服务器。|
__consumer_offets 默认有50个分区

kafka 集群评估

搞定10亿请求,需要5台物理机,11 (SAS) * 7T

内存评估

我们发现kafka读写数据的流程都是基于os cache,换句话说假设咱们的os cashe无限大
那么整个kafka是不是相当于就是基于内存去操作,如果是基于内存去操作,性能肯定很好。
内存是有限的。

  1. 尽可能多的内存资源要给os cache
  2. Kafka的代码用 核心的代码用的是scala写的,客户端的代码java写的。
    都是基于jvm。所以我们还要给一部分的内存给jvm。
    Kafka的设计, 没有把很多数据结构都放在j v m 里面。所以我们的这个j v m 不需耍太大的内存。
    根据经验,给个10G就可以了。
    NameNode: I
    jvm里面还放了元数据(几十G) , JVM一定要给得很大。比如给个100G。

假设我们这个10亿请求的这个项目 ,一共会有100个topic。
100 topic * 5 partition * 2 = 1000 partition
一个partition其实就是物理机上面的一个目录,这个目录下面会有很多个.log的文件。
.log就是存储数据文件.默认情况下一个.log文件的大小是1G。
我们如果要保证1000个partition的最新的.log文件的数据如果都在内存里面,这个时候
性能就是最好。1000 * 1G = 1000G内存.
我们只需要把当前最新的这个log保证里面的25%的最新的数据在内存里面。
250M * 1000 = 0.25 G* 1000 =250G的内存。
250内存/ 5 = 50G内存
50G+10G = 60G 内存
64G的内存,另外的4G,操作系统本生是不是也需要内存。
其实Kafka的jvm也可以不用给到10G这么多。
评估出来64G是可以的。
当然如果能给到128G的内存的服务器,那就最好。
我刚刚评估的时候用的都是一个topic是5个partition,但是如果是数据量比较大的topic,可能会有10个partition。
总结.
搞定10亿请求,需要5台物理机,11 (SAS) * 7T ,需要64G的内存(128G更好),需要16个cpu core (32个更好)

评估我们需要什么样网卡?

一般要么是千兆的网卡 (IG/S),还有的就是万兆的网长(10G/S)
高峰期的时候每秒会有5.5万的请求涌入,5.5/5 =大约是每台服务器会有1万个请求涌入。
我们之前说的,
10000 * 50kb = 488M 也就是每条服务器,每秒要接受488M的数据。数据还要有副木,副本之间的同步
也是走的网络的请求。488 * 2 = 976m/s
说明一下:
很多公司的数据,一个请求里面是没有50kb这么大的,我们公司是因为主机在生产端封装了数据
然后把多条数据合并在一起了,所以我们的一个请求才会有这么大。
说明一下:
一般情况下,网卡的带宽是达不到极限的,如果是千兆的网卡,我们能用的一般就是700M左右。
但是如果最好的情况,我们还是使用万兆的网卡。
如果使用的是万兆的,那就是很轻松。

Exception

1)LeaderNotAvailableException:
这个就是如果某台机器挂了,此时leader副本不可.用,会导致你写入失败,、
要等待其他follower副本切换为leader副本之后,才能继续写入,此时可以重试发送即可
如果说你平时重启kafka的broker进程,肯定会导致leader切换,一定会导致你写入报错,
是LeaderNotAvailableException
2) NotControllerException: 这个也是同理,如果说Controller所在Broker挂了,
那么此时会有问题,需耍等待Controller重新选举,此时也是一样就是重试即可
3) NetworkException: 网络异常 timeout
a.配置.retries参数,他会自动重试的
b.但是如果重试几次之后还是不行,
就会提供Exception给我们来处理了,我们获取到异常以后,再对这个消息进行单独处理,
我们会有备用的链路。

如何提升吞吐量

参数一:
buffer.memory:设置发送消息的缓冲区,默认值是33554432,就是32MB
参数二:
compression, type:默认是none,不压缩,但是也可以使用Iz4JK缩,效率还是不错的,
压缩之后可以减小数据量,提升吞吐量:,但是会加大producer端的cpu开销
参数三:
batch.size:设置.batch的大小,如果batch太小,会导致频繁网络请求,吞吐量下降;
如果batch太大,会导致一条消息需要等待很久才能被发送出去,而且会让内存缓冲区有很大压力,
过多数据缓冲在内存里, 默认值是: 16384 , 就是 6 k b , 也就是一个batch 满了 16 kb 就发送出去,
一般在实际生产环境,这个batch的值可以增大一些来提升乔吐量:

如果我们消息比较少
配合使用的参数linger.ms,这个值默认是0,意思就是消息必须立即被发送,但是这是不对的,
一般设置一个100亳秒之类的,这样的话就是说,这个消息被发送出去后进入一个batch,
如果100毫秒内,这个batch满了 16kb,自然就会发送出去

猜你喜欢

转载自blog.csdn.net/m0_46449152/article/details/114998935