集群搭建:
修改 broker.id 为不同的值0 ,1 ,2 。。。
host.name 设置IP 供连接使用
zookeeper.connect 设置 zk 地址
注意:zk地址设置是可以为 172.17.44.176:2181,172.17.44.178:2181,172.17.44.180:2181,172.17.44.184:2181,172.17.44.192:2181/kafka
这里会在zk 上创建目录的时候 将kafka 创建的几个目录 放在根目录下/kafka 下面,另外创建consumer的时候的zk连接地址也需要增加 /kafka
log.dirs -- kafka存放消息文件的路径,默认/tmp/kafka-logs
以及 下面broker设置的内容
启动kafka 会在zookeeper上创建3个目录 1--- brokers 2-- consumers 3----controllers_epoch 4---controllers 等
创建topic 的副本数 不能超过 集群中broker的个数,指定副本数例如:
bin/kafka-create-topic.sh --zookeeper storm1:2181 --replica 3 --partition 1 --topic qqqc5
topic: qqqc5 partition: 0 leader: 1 replicas: 1,0 isr: 1,0
partiton: partion id,由于此处只有一个partition,因此partition id 为0
leader:当前负责读写的lead broker id
relicas:当前partition的所有replication broker list
isr:relicas的子集,只包含出于活动状态的broker
broker 设置:
##检测log文件的时间间隔
log.cleanup.interval.mins=1
##log文件被保留的时长,如果超过此时长,将会被清除,无论log中的消息是否被消费过.
log.retention.hours=168
##是否自动创建topic
##如果broker中没有topic的信息,当producer/consumer操作topic时,是否自动创建.
##如果为false,则只能通过API或者command创建topic
auto.create.topics.enable=true
##partitions的"replicas"个数,不得大于集群中broker的个数
default.replication.factor=1 当设置大于broker个数时 自动创建topic就会报错导致发送不出去消息
##partitions可以被sharding到多个broker上,以提高并发能力和"可用性"
num.partitions=2
producer :
//集群中添加brokerlist格式
props.put("metadata.broker.list", "10.12.218.183:9092,10.12.218.184:9092");
high level api:
consumer 配置 --
props.put("auto.offset.reset", "smallest"); //消费者 group 每次取offset 中未处理的老信息
props.put("auto.commit.enable", "true"); //自动提交到 zk 注意offset信息并不是每消费一次消息就向zk提交一次,而是现在本地保存(内存),并定期提交
可以设置为false 自己手动调用consumer中的commit 方法(其实是讲message中存在的offset信息提交到zk上进行存储)
props.put("auto.commit.interval.ms", "1000"); //自动提交的时间间隔,默认为1分钟 这里是1秒
props.put("request.required.acks", "0");
##producer接收消息ack的时机.默认为0.
##0: producer不会等待broker发送ack
##1: 当leader接收到消息之后发送ack
##2: 当所有的follower都同步消息成功后发送ack.
request.required.acks=0
问题:当consumer消费失败后,会导致消息丢失;改进:每次consumer消费后,给broker ack,若broker在超时时间未收到ack,则重发此消息。
问题:1.当消费成功,但未ack时,会导致消费2次 2. now the broker must keep multiple states about every single message 3.当broker是多台机器时,则状态之间需要同步
props.put("compression.codec", "snappy"); //提供批量压缩,broker不对此批消息做任何操作,且以压缩的方式,一起被发送到consumer gzip ,snappy
疑问:
在处理数据的时候 KafkaStream --- 获取 iterator() 遍历的时候
调用
MessageAndMetadata<byte[], byte[]> msgMeta = it.next();
msgMeta.key() 这里会卡死在这里--- 原因未知
low level api:
手动拉取自己设置offset的消息
SimpleConsumer simpleConsumer = new SimpleConsumer( KafkaProperties.kafkaServerURL, KafkaProperties.kafkaServerPort, KafkaProperties.connectionTimeOut, KafkaProperties.kafkaProducerBufferSize, KafkaProperties.clientId); System.out.println("Testing single fetch"); String topicl = KafkaProperties.topic2 ; // String topicl = "qcall"; int partitopn = 0 ; long offset = 0L ; while(offset >= 0){ FetchRequest req = new FetchRequestBuilder() .clientId("12dxczxc") .addFetch(topicl, partitopn, offset, 64*1024).build(); FetchResponse fetchResponse = simpleConsumer.fetch(req); offset = printMessages((ByteBufferMessageSet) fetchResponse.messageSet(topicl, partitopn)); }
查询topic的最大offset值
TopicAndPartition topicAndPartition = new TopicAndPartition(topic, partition); Map<TopicAndPartition, PartitionOffsetRequestInfo> requestInfoMap = new HashMap<TopicAndPartition, PartitionOffsetRequestInfo>(); // requestInfoMap.put(topicAndPartition, new PartitionOffsetRequestInfo( // kafka.api.OffsetRequest.LatestTime(), 100)); // long ttt = -2 ; long ttt = kafka.api.OffsetRequest.LatestTime(); // System.out.println(ttt); requestInfoMap.put(topicAndPartition, new PartitionOffsetRequestInfo(ttt, 100)); OffsetRequest request = new OffsetRequest(requestInfoMap, kafka.api.OffsetRequest.CurrentVersion(), clientName); OffsetResponse response = consumer.getOffsetsBefore(request); long[] validOffsets = response.offsets(topic, partition); for (long validOffset : validOffsets) { System.out.println(validOffset + " : "); } if(validOffsets.length <= 0){ throw new Exception(" topic:" + topic + ",partition:" + partition + " offset wei" + validOffsets.length); } long largestOffset = validOffsets[0]; long smallestOffset = validOffsets[validOffsets.length - 1]; System.out.println(smallestOffset + " : " + largestOffset); return largestOffset;