生产者
缓冲区大小与Sender线程发送包大小
从生产者架构图我们可以看出,有两个地方是比较重要且影响性能的:
-
RecordAccumulator
内存缓冲区; - Sender线程的两个阈值;
-
batch.size
:只有数据积累到batch.size
之后,sender 才会发送数据,默认16kb。 -
linger.ms
:如果数据迟迟未达到batch.size
sender 等待linger.time
之后就会发送数据。 -
buffer.memory
:RecordAccumulator 缓冲区大小 默认32M。
这两个区域参数需要根据发送消息的QPS、每条消息的占用空间的大小和Sender线程发送消息的速度进行容量预估,然后通过压测工具进行验证。
缓冲区域默认是32M,如果一条消息占用空间大小是512B,那么这个区域最大存放消息的数据就是
32*1024*1024/512=65535
条数据。
Sender线程一次发送数据量的大小,默认是16kB,16*1024/512=32
,也就是说一次可以发送32条数据。那么65535条数据就需要发送2048次。
消息发送确认机制acks
生产者中还有一个比较重要的参数会影响性能acks
(确认机制):
-
1
:当消息写到 leader 成功后向生产者返回 ack,如果在 follower 同步成功之前 leader 故障,那么将会丢失数据
,默认是这个级别; -
0
:不向生产者返回ack,这种情况下生产者延迟最低,broker 一接收到还没有写入磁盘就已经返回,当 broker 故障时有可能丢失数据
; -
-1(all)
:当ISR中的所有副本都成功写入消息之后才像生产者返回ack。这种方式数据可靠,但是延迟最高;如果ISR副本同步完成后,broker 发送 ack 之前,leader 发生故障,那么会造成数据重复
。
重试机制(retries和retry.backoff.ms)
-
retries
:配置生产者重试的次数,默认值为0,即在发生异常的时候不进行任何重试动作。 -
retry.backoff.ms
:设定两次重试之间的时间间隔,避免无效的频繁重试,默认值为100。
消费者配置
fetch.min.bytes:
每次fetch请求时,server应该返回的最小字节数。如果没有足够的数据返回,请求会等待,直到足够的数据才会返回。
auto.commit.enable
如果为真,consumer所fetch的消息的offset将会自动的同步到zookeeper。这项提交的offset将在进程挂掉时,由新的consumer使用。
选择合适的分区数
在Kafka中,性能与分区数有着必然的关系,在设定分区数时一般也需要考虑性能的因素。但分区数越多吞吐量就越高吗?
分区是Kafka 中最小的并行操作单元,对生产者而言,每一个分区的数据写入是完全可以并行化的;对消费者而言,Kafka 只允许单个分区中的消息被一个消费者线程消费,一个消费组的消费并行度完全依赖于所消费的分区数。但是分区数不是越多越好,这需要进行压测,最后得出一个比较好的一个分区数。
分区太多会带来的问题:
- 分区数会占用文件描述符,而一个进程所能支配的文件描述符是有限的。
- 分区数的多少还会影响系统的可用性。由于kafka存在分区和副本机制 leader 副本对外提供服务,并且所有副本都采用自动话管理,所以当分区数量越多,那么自动化管理就会越多。
- 分区数越多也会让Kafka的正常启动和关闭的耗时变得越长。
在没有压测情况下建议将分区数设定为集群中broker的倍数。假定集群中有3个broker节点,可以设定分区数为3、6、9等,至于倍数的选定可以参考预估的吞吐量。但是还是建议进行压测,进而找到最优的分区数。
网友评论