什么是Apache Kafka?
Apache Kafka是一个发布-订阅消息系统。
由LinkedIn发起,于2011年初开源。
LinkedIn开发Kafka的初衷:
需要一个能够处理大公司所有实时数据的统一平台
该平台需要具备以下特性:
1.高吞吐量。
2.支持实时消息处理。
3.能够积压处理大量的周期性离线数据。
4.低延时。
5.零容忍机器故障。
Kafka架构
1.组件介绍
1.1 生产者写数据到broker。
1.2 消费者从broker读取数据。
所有的这些都是分布式的。
2.数据
2.1 数据存储在topic中。
2.2 topic通过复制被分成许多个partition(分区)。
对生产者的优化建议
1.使用正确的消息确认选项
消息一旦发送到了broker,你想等多久?可通过下面这个选项来设置。
‘request.required.acks’是生产者的属性,其可能的值有:
0 - 生产者不需要等broker的确认,以持久性的代价获得最低的延时。
1 - 当主复制已经接收到了数据就发送一个确认给生产者。
-1- 当所有的复制都同步收到数据后发送一个确认给生产者。
2.通过异步的生产者来批处理消息
2.1发布消息,通过回调获取确认的发送状态。
2.2 设置”producer.type=1”变生产者为异步。
2.3 为了提高吞吐量使用独立的线程来发送大批量的消息到broker。
2.4 queue.buffer.max.ms用于设置批处理的时长。
2.5 batch.num.messages用于设置在一个批次中要发送多少条消息。
3.压缩
压缩可以降低数据在磁盘上的存储空间以加快对数据的读写。
但同时从磁盘上读数据需要解压,解压却需要消耗一定的cpu周期。
所以需要在IO负载和CPU负载之间做一个权衡。
目前kafka支持Gzip,Snappy等压缩方式。
“compression.codec”的属性值有”none”,”gzip”和”snappy”。
4.大消息
假如有大文件放在共享存储上,可考虑使用Kafka发送文件的所在位置,这在大多数情况下,要比直接使用kafka发送文件本身要快得多。
5.对于不同的操作设置适当的超时
5.1 没有必要一直等待操作的响应。
5.2 不同的超时设置可以控制在操作返回失败前需要等多久。
5.3 一些重要的超时设置有:
request.timeout.ms-这个值是用于设置broker为了尝试满足request.required.acks需要并在返回错误到客户端前需要等的时间。
更多的这些设置可参考https://kafka.apache.org/08/configuration.html(不仅包含超时设置,还包括其它的设置如重试和入队列等)。
对Broker的优化建议
1.预备更多的分区
1.1 消费者的数量应该同分区的数量一样多,所以为了更多的并发处理就需要有更多的分区。
1.2 但更多的分区会增加延时。
1.3 一个物理磁盘存储就一个分区,以保证写IO不成为瓶颈。
2.要时刻注意分区的负载情况,必要的时候要重新分区到新的broker
2.1 要保证没有分区是超负荷的,虽然有些分区处于闲置状态。
2.2 使用”kafka-reassign-partition.sh”工具来
2.2.1 - - generate:给定一个主题列表和目标broker,该模式可以非常方便的产生一个重分区的计划。
2.2.2 - - execute:在这个模式中,工具将会基于用户提供的重分配计划来取消原本的重分区计划(使用 - - reassignment-json-file选项),这个计划可能是管理员人手定制的重分区计划也可能是由 - generate选项提供的计划。
2.2.3 - -verify:在这个模式中,工具将会检查在generate模式中列出的所有分区的重分区状态。
3.一些更好性能的配置
3.1 num.io.threads-服务器用于处理请求的io线程数量。这个数量至少需要与你所拥有的磁盘数量一样多。
3.2 num.parttions-每个主题默认的分区数量。
3.3 log.flush.interval.messages-在我们强制同步日志前需要写入一个日志分区的消息数量。增加这个值虽然可以提高不少的性能,但会有风险丢失一定的消息。
对消费者的优化建议
1.一个主题的消费者的最大数量应该与分区的数目相同。
2.你需要有足够的分区来处理所有需要追上生产者的消费者。
3.同一个消费者组内的消费者之间来摊分分区。
增加更多的消费者到组内能提高性能,但增加更多的消费者组却对性能没有帮助。
4.’replica.high.watermark.checkpoint.interval.ms’的值会影响吞吐量。
5.当从一个分区中读数据时,你可以标记最后所读的数据位置。这样的话,如果你想回头读取错过的消息,你就需要有一个检查点来向前移动而不需要读之前的数据。
6.如果你为每个事件都设置了检查点的水印,你将不会丢失消息,但对性能影响很大。
7.相反,如果你每隔几百条消息设置一个检查的偏移量,那么你就有一个对吞吐量影响更小的安全余地。
8.设计和优化你的消息者并适当的向前’pipeline’。
9.选择超时和其它比较重要的配置选项如自动提交等。