由数据分析、数据挖掘和机器学习等方面的研究,大部分时间主要是使用消费kafka里面的数据,再进行数据分析和检测引擎方面的研究。
消费者
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "test");
props.put("enable.auto.commit", "true");
props.put("auto.commit.interval.ms", "1000");
props.put("auto.offset.reset", "earliest");
props.put("session.timeout.ms", "30000");
props.put("fetch.min.bytes", "1048576");
props.put("fetch.max.wait.ms", "2000");
props.put("max.partition.fetch.bytes", "2097152");
props.put("max.poll.records", "10000");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
1.enable.auto.commit:指定了消费者是否自动提交偏移量,默认值是true,为了尽量避免重复数据和数据丢失,可以把它设置为false,有自己控制合适提交偏移量,如果设置为true, 可以通过设置 auto.commit.interval.ms属性来控制提交的频率。
原理:当一个consumer退出Group时,进行重新分配partition后,同一group中的另一个consumer在读取该partition时,怎么能够知道上一个consumer该从哪个offset的message读取呢?如何保证同一个group内的consumer不重复消费消息呢?
当使用完poll从本地缓存拉取到数据之后,需要client调用commitSync方法(或者commitAsync方法)去commit 下一次该去读取 哪一个offset的message。而这个commit方法会通过走网络的commit请求将offset在coordinator中保留,这样就能够保证下一次读取(不论进行了rebalance)时,既不会重复消费消息,也不会遗漏消息
2.auto.offset.reset
默认值是latest,也就是从最新记录读取数据(消费者启动之后生成的记录),另一个值是earliest,意思是在偏移量无效的情况下,消费者从起始位置开始读取数据。
3.session.timeout.ms
该属性指定了当消费者被认为已经挂掉之前可以与服务器断开连接的时间。默认是3s,消费者在3s之内没有再次向服务器发送心跳,那么将会被认为已经死亡。
该属性与heartbeat.interval.ms紧密相关,该参数定义了消费者发送心跳的时间间隔,也就是心跳频率,一般要同时修改这两个参数,heartbeat.interval.ms参数值必须要小于session.timeout.ms,一般是session.timeout.ms的三分之一 .
4.max.partition.fetch.bytes
该属性指定了服务器从每个分区里返回给消费者的最大字节数。它的默认值是1M.在设置该属性时,另一个需要考虑的因素是消费者处理数据的时间。消费者需要频繁调用poll()方法 来避免会话过期和发生分区再均衡,如果单次调用poll()返回的数据太多,消费者需要更多的时间来处理,可能无怯及时进行下一个轮询来避免会话过期。如果出现这种情况, 可以把max.partitioin.fetch.bytes 值改小,或者延长会话过期时间。
5.fetch.min.bytes:消费者从服务器获取记录的最小字节数
6.fetch.max.wait.ms:broker的等待时间
7.max.poll.records
控制单次调用call方法能够返回的记录数量,帮助控制在轮询里需要处理的数据量。
8.receive.buffer.bytes + send.buffer.bytes socket 在读写数据时用到的TCP 缓冲区也可以设置大小。如果它们被设为-1 ,就使用操作系统的默认值。如果生产者或消费者与broker 处于不同的数据中心内,可以适当增大这些值,因为跨数据中心的网络一般都有比较高的延迟和比较低的带宽。
9.partition.assignment.strategy:分区策略
10.client.id
Consumer进程的标识。
生产者producer
1.producer 参数acks设置
在消息被认为是“已提交”之前,producer需要leader确认的produce请求的应答数。该参数用于控制消息的持久性,目前提供了3个取值:
-
acks = 0: 表示produce请求立即返回,不需要等待leader的任何确认。这种方案有最高的吞吐率,但是不保证消息是否真的发送成功。
-
acks = -1: 表示分区leader必须等待消息被成功写入到所有的ISR副本(同步副本)中才认为produce请求成功。这种方案提供最高的消息持久性保证,但是理论上吞吐率也是最差的。
-
acks = 1: 表示leader副本必须应答此produce请求并写入消息到本地日志,之后produce请求被认为成功。如果此时leader副本应答请求之后挂掉了,消息会丢失。这个方案,提供了不错的持久性保证和吞吐。
2.producer参数 buffer.memory 设置(吞吐量)
缓存消息的缓冲区大小,单位为字节,默认值为:33554432合计为32M。kafka采用的是异步发送的消息架构,prducer启动时会首先创建一块内存缓冲区用于保存待发送的消息,然后由一个专属线程负责从缓冲区读取消息进行真正的发送。
-
消息持续发送过程中,当缓冲区被填满后,producer立即进入阻塞状态直到空闲内存被释放出来,这段时间不能超过max.blocks.ms设置的值,一旦超过,producer则会抛出TimeoutException 异常,因为Producer是线程安全的,若一直报TimeoutException,需要考虑调高buffer.memory 了。
-
用户在使用多个线程共享kafka producer时,很容易把 buffer.memory 打满。
3. compression.type
producer压缩器,目前支持none(不压缩),gzip,snappy和lz4。
4.retries
producer重试的次数设置。重试时producer会重新发送之前由于瞬时原因出现失败的消息。瞬时失败的原因可能包括:元数据信息失效、副本数量不足、超时、位移越界或未知分区等。倘若设置了retries > 0,那么这些情况下producer会尝试重试。
5. batch.size
producer都是按照batch进行发送的,因此batch大小的选择对于producer性能至关重要。producer会把发往同一分区的多条消息封装进一个batch中,当batch满了后,producer才会把消息发送出去。但是也不一定等到满了,这和另外一个参数linger.ms有关。默认值为16K,合计为16384.
6.linger.ms
producer是按照batch进行发送的,但是还要看linger.ms的值,默认是0,表示不做停留。这种情况下,可能有的batch中没有包含足够多的produce请求就被发送出去了,造成了大量的小batch,给网络IO带来的极大的压力。
7.max.in.flight.requests.per.connection
producer的IO线程在单个Socket连接上能够发送未应答produce请求的最大数量。增加此值应该可以增加IO线程的吞吐量,从而整体上提升producer的性能。不过就像之前说的如果开启了重试机制,那么设置该参数大于1的话有可能造成消息的乱序。
配置文件优化
server.properties文件
1.线程数
如果服务器cpu核心为 X ,那么计算密集任务所需线程(num.network.threads) = X,IO密集任务所需线程(num.io.threads) = 2 * X
2.消息清楚策略
log.cleanup.policy=delete#启用删除策略 #直接删除,删除后的消息不可恢复。可配置以下两个策略:
#清理超过指定时间清理:
log.retention.hours=16
#超过指定大小后,删除旧的消息:
log.retention.bytes=1073741824
3.compact策略
它并不是指通过压缩算法对日志文件进行压缩,而是对重复的日志进行清理来达到目的。在日志清理过程中,会清理重复的key,最后只会保留最后一条key,可以理解为map的put方法。在清理完后,一些segment的文件大小就会变小,这时候,kafka会将那些小的文件再合并成一个大的segment文件。另外,通过日志清理功能,我们可以做到删除某个key的功能。推送value为null的key到kafka,kafka在做日志清理时就会将这条key从日志中删去。
4.内存
对kafka-server-start.sh文件配置
默认1G,生产中的经验值为4 到 6 G,最高6G,超过6G效果不明显,这时建议加服务器。
5.producer缓冲区优化
在producer.properties中配置:
buffer.memory:33554432 (32m)
#在Producer端用来存放尚未发送出去的Message的缓冲区大小。缓冲区满了之后会阻塞, max.block.ms(默认1个小时)过后将会抛出异常
6. 文件刷新
server.properties中配置
# 每当producer写入10000条消息时,刷数据到磁盘
log.flush.interval.messages=10000
# 每间隔1秒钟时间,刷数据到磁盘
log.flush.interval.ms=1000
7.消息大小配置
#producer.properties:
#也可以在创建topic时动态设置
max.request.size=5242880(5M)
#server.properties message.max.bytes=6291456(6M)
#consumer.properties:
fetch.max.bytes=7340032(7M)