问题导读:
1 生产者中都有哪些有用的配置?
2 如何保证生产者消息的顺序性?
3 如何提高生产者发送消息的吞吐量?
到目前为止我们只涉及到了生产者的几个配置参数,只有bootstrap.server连接地址以及序列化相关的参数。
生产者其实也有很多可以配置的参数,详细内容可以参考官方文档:http://kafka.apache.org/documentation.html#producerconfigs 很多参数都有默认的值,大多数情况下也不需要修改。有一些参数会影响到生产者的内存、性能以及可靠性。下面我们就介绍下这些参数。
acks
acks参数控制有多少个备份分区需要给生产者提供成功回复。这个参数会影响消息是否丢失,参数的值为:
- 如果acks=0,生产者不会等待分区响应。这就意味着如果分区在持久化时发生错误或者broker压根就没有接收到消息,生产者也不会知道出现这个问题,消息就被丢失了。然而,因为生产者不会等待响应,它的速度也是最快的,所以这种配置适合需要高吞吐的场景。
- 如果acks=1,生产者需要接收leader的成功响应。如果没有写入leader(比如leader宕机或者新的leader还没有选举出来),Producer会收到错误响应,并且尝试重新发送,避免丢失数据。不过,在主节点还没有同步到备份节点时,主节点挂掉,那么数据一样会有丢失的风险。在这种情况下,就依赖于我们是采用同步还是一部,如果客户端使用get()方法,那么网络的延迟会增加。如果使用回调,那么延迟会降低,当时吞吐量则受到限制(限制于生产者发送多少还未受到回复的消息数量)。
- 如果acks=all,当所有的broker分区都成功时,才会返回成功。这种方式是最安全的,当时延迟也是最高的,因为我们需要等待消息完全同步成功。
buffer.memory
这个选项配置生产者多少内容用于缓存数据,统一再发broker。如果消息发生的速度比broker接收的速度还快,那么会导致生产者内存被快速占用,此时在调用send()方法就会报错或者阻塞,这取决参数block.on.buffer.full的配置。
compression.type
默认情况下,消息发送时是不会被压缩的。这个参数可以设置成snappy或者gzip,会根据不同参数使用不同的压缩算法发送消息。snappy压缩算法是google研发的,提供了可观的压缩比率,但是花费更低的CPU,因此适合在考虑性能时使用。Gzip压缩算法花费更高的CPU,但是压缩率会更高一些,因此推荐在网络带宽吃紧的时候使用。如果网络是你的瓶颈,那么推荐采用压缩这种方式。
reties
当生产者收到服务器的错误时,如果这个错误时暂时的,比如分区缺少leader。在这种情况下,tetries参数就控制生产者在抛出异常前,还可以尝试再发送几次。默认情况下每次重试会间隔100ms,这个值可以通过参数retry.backoff.ms控制。推荐先测试一下leader重新选举的时间,再来设置这个值,并且保证重试的时间会大于leader恢复的时间。有一些错误不是暂时性的,比如“消息过大”。一般情况下,因为生产者已经为你重试了,你也可以通过回调,再自己发送尝试。你可以不想重试发送消息,而是用不同的方式处理失败的请求,比如把失败的消息写入文件。
batch.size
当向某个相同的分区发送记录时,生产者会采用批处理的方式处理。这个参数就是控制内存中多少自己可以用来批处理,当batch满时,消息将会统一发送出去。然而这并不是说必须等到batch满时,才会发送数据。当生产者达到batch的一半时,或者甚至是只有一条消息,也会发送。如果这个参数设置的太大,将会增加消息发送的延迟。如果设置的太小,那么又会增加消息发送的频率。
linger.ms
linger.ms控制当前batch等待的时间,kafka生产者会以batch为单位发送数据,当batch满时或者时间到达linger.ms设置的时间时,也会发送。默认情况下,只要有sender线程可用,那么即便是只有一条消息,也会发送出去。如果设置linger.ms设置高于0,那么batch在发送之前就会等待一段时间。这回增加延迟,当时相应的也会带来更高的吞吐。
client.id
这个参数可以设置成任何的字符串,他只是标识消息时从那个客户端发来的。一般就是用于日志的记录跟踪以及投票时使用。
max.in.flight.requests.per.connection
这个参数控制生产者可以在不接受消息时,向broker发送多少条数据。提高这个参数会增加吞吐量,设置为1可以保证消息按照顺序发送给broker,即便是发生重试,也不会打乱次序。
timeout.ms 和 metadata.fetch.timeout.ms
这个参数控制生产者发生数据时,等待服务器响应的时长。以及请求发送分区的leader的元数据时的时长。如果超时,那么生产者将会收到一个错误(可能是异常,也可能是回调)
保证顺序
Apache Kafa只能在某个分区中保证顺序。这就意味着如果消息按照特定的顺序发送给broker,borker会按照顺序把它写入到分区,然后消费者可以按照顺序再消费它。在某些情况下,顺序是很重要的。比如在银行存入100美元,再取出来,不同的顺序区别是很大的。当然有一些情况下,对于顺序是不那么敏感的。
设置retries参数为非零并且max.in.flights.requests.per.session,如果消息在第一个batch中失败,在第二个batch中成功,那么需要对batch1和batch2同时做重试,才能保证他们的顺序。
如果对顺序要求很严格,那么可以设置retries参数为0,禁止重试。并且设置in.flights.requests.per.session=1来保证第一个batch发送成功之前,不会有第二个batch发送。这显然会降低吞吐,但是会严格的保证顺序。
|
|