目录
1Kafka持久化机制
1.1 如何使用磁盘达到较高的吞吐量?
1.2 写磁盘的过程
2 Producer 拦截器
3 Kafka Partitionor
4 Kafka调优参考
4.1 吞吐量
4.2 延迟
4.3 可用性
5 Leader的选举
1Kafka持久化机制
Kafka数据存储目录由log.dirs参数配置。 Kafka的消息数据是基于磁盘进行数据存储的。
每个partition都会对应一个文件夹。Partition中可以包含一个或者多个segment, 消息的失效是以segment为单位的。 默认情况下, 每个片段包含1GB或者1周的数据, 以较小的那个为准。 当前正在写入数据的分区称为活跃分区, 活跃分区是不会被删除的。
Kafka的消息可以进行压缩, 在客户端CPU充足的情况下, 可以有效的增加吞吐量。 即如果通过网络传输文件, 只需要在内核内存空间里有一个内存缓冲区。
消息保留的时间可以配置:
- log.retention.bytes: 空间限制
- log.retention.hours, log.retention.minutes, log.retention.ms: 时间限制
1.1 如何使用磁盘达到较高的吞吐量?
- 顺序读写: 磁盘的顺序读写远比随机读写要快;
- RAID阵列;
- 分布式读写;
1.2 写磁盘的过程
一般的操作系统在写磁盘时, 不会直接往磁盘写, 而是先写到内存中的page cache, 然后再一定时间之后, 才把数据复制到磁盘上。 如下:
kafka可以通过log.flush.*这些参数进行冲刷磁盘相关的配置。
2 Producer 拦截器
可以向producer注册拦截器, 执行一些横切逻辑。 可以同时注册多个拦截器, 它们之间以职责链的模式来写作。
拦截器的接口的接口为ProducerInterceptor, 其中方法定义为:
- configure(configs): 初始化时调用;
- onSend(ProducerRecord): 方法的出入参时ProducerRecord, 运行在用户主线程中, 在确定分区和消息被序列化之前调用;
- onAcknowledgement(Recordmetadata, Exeption): 消息处理结果的回调, 运行在IO线程中, 所以不要在这个方法中执行过重的逻辑, 以免影响消息的发送。
- close();
需要由用户来保证多线程的安全性。
3 Kafka Partitionor
可以通过实现Partitionor来实现自己的分区规则。
其中的一个使用场景是,保证消息的顺序, 当partition的数量变多时, 通过Partition让相同key的消息还是发送在原来的partition上。
4 Kafka调优参考
4.1 吞吐量
通过增大消息发送和消费的批次可以提高吞吐量。 在客户端机器CPU充足的情况下可以开启压缩, 也可以提高吞吐量。
相关配置:
- Producer:
- batch.size 设置成一个比较大的值。
- linger.ms 100或者更大的值
- compression.type lz4是压缩率最大的算法
- acks=1
- retries=0
- buffer.memory 适当增加缓冲区的大小, 增加可以同时处理的batch的数量
- Consumer:
- fetch.min.bytes 增加单个request的最小字节数
4.2 延迟
吞吐量是和延迟相互矛盾的一个参数,对于需要低延迟的情况, 可以适量调低吞吐量的参数来调整。
4.3 可用性
可以通过增加partition的副本数量来提高kafka的可用性。
- Broker
- replication.factor >= 3
5 Leader的选举
Partition的leader的选举, 如下图:
Broker中有一个节点存在着一个controller, 当要选举一个partition的leader时, 由controller根据某种策略决定哪一个ISR 节点成为新的broker。ISR, 是指和leader节点保持一致的节点, 由两个配置参数界定:
- replica.lag.time.max.ms
- replica.lag.max.messages
决定的策略: 是抢占性的吗?
(acks为all时, 实际上是同步了所有的ISR就返回)