影响单次poll返回最大数据量的几个因素

timeout

单次poll最大等待时间,consumer.poll(1000)意味着在缓存中的数据被消费完之后,consumer会到broker中拉取数据,最多等待1000毫秒。很明显,timeout越大,单次poll返回的数据就越多。但前提是有足够多的数据可供消费,如果在1000毫秒内,consumer已经拿完所有能拿的数据,就会立即返回。

max.poll.records

单次poll最大返回数据条数,默认值2,147,483,647。这应该不需要解释。

receive.buffer.bytes

用于TCP读取数据的缓存(SO_RCVBUF)大小,默认值64k。之前做过小测试,发现消费10万条大小1k的数据,花费5秒左右,设置max.poll.records=1,理论上来说性能应该大大下降才对,但实际测试结果也在5秒左右。后来发现消费端有64k缓存,换句话说每次TCP请求会拿64条数据,因此虽然poll每次只拿一条数据,但也是从缓存中拿,拿64次才会真正发送一次TCP请求。而相对于1k大小数据的消费,TCP请求的开销可以忽略,因此消费时间差不多。当测试数据大小为1个字节时,TCP请求的开销就不能忽略了,而测试结果也证实,max.poll.records=1会使消费性能下降2/3。

max.partition.fetch.bytes

单次poll对于每个partition最大返回数据量,默认值1M。如果消费的topic有3个partition,那么单次poll最多返回3M数据。但实际上发现单次poll一般都只返回1M的数据,而不是3M。检查数据的分布,也都分散在3个partition中。原因是consumer会启动3个fetcher分别到每个partition抓取数据,而考虑到性能问题,consumer会在fetch一个partition一定时间后才会fetch下一个partition,所以单次poll很可能只是在拿一个partition中的数据,所以返回1M数据。把测试时间延长之后发现,偶尔会有一次poll拿到2M数据,符合刚才的分析。