文章目录

  • kafka使用和操作
  • 1.环境搭建
  • 2.基本操作
  • 2.1.服务器基本操作
  • 2.2.topic相关操作
  • 2.3.生产者相关命令
  • 2.4.消费者相关命令
  • 3. 生产者
  • 3.1发送消息 异步发送 没有回调函数
  • 3.2 发送消息 异步发送 带回调函数
  • 3.3 发送消息 同步发送
  • 3.4 生产者 分区策略
  • 3.4.1自定义分区器
  • 3.5 生产者常用的配置
  • 3.1.7 生产者 ack 应答模式
  • 3.1.7.1 应答模式总结
  • 3.1.7.2 代码配置应答模式
  • 4.kafka broker
  • 4.1 基本工作原理
  • 4.1.1.节点的注册
  • 4.1.2. kafka leader选举流程
  • 4.1.3 topic 信息
  • 4.2节点的服役和退役
  • 4.2.1 下线kafka节点
  • 4.2.2 上线新的kafka 节点
  • 4.2.3 kafka 选举流程和 ar , isr
  • 4.2.4 故障转移的过程
  • 4.2.5 leader再平衡策略
  • 4.2.6 kafka日志存储
  • 5.消费者
  • 5.1 消费者的基础概念
  • 5.1.1 消费者的原理
  • 5.1.2 消费者的配置
  • 5.2 消费者代码实现
  • 5.2.1 普通的消费者代码
  • 5.2.2 消费者指定消费某个分区
  • 5.2.3 消费者消费策略


kafka使用和操作

1.环境搭建

2.基本操作

2.1.服务器基本操作

# 启动kafka
/usr/local/kafka_2.12-3.0.0/bin/kafka-server-start.sh -daemon /usr/local/kafka_2.12-3.0.0/config/server.properties

# 停止kafka
/usr/local/kafka_2.12-3.0.0/bin/kafka-server-stop.sh

2.2.topic相关操作

# 查看 topic 列表
/usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --list

# 创建一个名称为 test 的 topic, partitions 指定分区数量, replication-factor 副本数量
/usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --create --partitions 3 --replication-factor 3 --topic test

# 查看某个主题的详细信息
/usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --describe --topic test

# 修改分区数量 只能增加不能减少
/usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --alter --topic test --partitions 4

# 删除主题
/usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --delete --topic test

2.3.生产者相关命令

# 通过控制台发送消息 到 test 这个 topic
/usr/local/kafka_2.12-3.0.0/bin/kafka-console-producer.sh --bootstrap-server node-1:9092 --topic test

2.4.消费者相关命令

# 从控制台消息消息
/usr/local/kafka_2.12-3.0.0/bin/kafka-console-consumer.sh --bootstrap-server node-1:9092  --topic test

3. 生产者

3.1发送消息 异步发送 没有回调函数

public class TestProducer {

    private static String kafkaAddr = "node-1:9092";
    private static String topic = "test";

    public static void main(String[] args) {
        Properties properties = new Properties();
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaAddr);
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");

        KafkaProducer<String, String> producer = new KafkaProducer<String, String>(properties);
        for (int i = 0; i < 10; i++) {
            producer.send(new ProducerRecord<String, String>(topic, "a"+i));
        }
        producer.close();

    }
}

3.2 发送消息 异步发送 带回调函数

producer.send(new ProducerRecord<String, String>(topic, "a" + i), new Callback() {
                public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                    String topic = recordMetadata.topic();
                    int partition = recordMetadata.partition();
                    long offset = recordMetadata.offset();
                    System.out.println("topic="+topic+"partition="+partition+"offset="+offset);
                }
            });

3.3 发送消息 同步发送

RecordMetadata recordMetadata = producer.send(new ProducerRecord<String, String>(topic, "a" + i)).get();

3.4 生产者 分区策略

// 发往指定的分区1 , 如果生产者指定发往那个分区, kafka就直接发往对应的分区了
// 分区对应类: org.apache.kafka.clients.producer.UniformStickyPartitioner
producer.send(new ProducerRecord<String, String>(topic, 1,"","a" + i), new Callback() {
                public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                    String topic = recordMetadata.topic();
                    int partition = recordMetadata.partition();
                    long offset = recordMetadata.offset();
                    System.out.println("topic="+topic+"partition="+partition+"offset="+offset);
                }
            });

// 使用 key  分区=key.gethashCode() % topic.partitionCount;
// 分区对应类: org.apache.kafka.clients.producer.internals.DefaultPartitioner
producer.send(new ProducerRecord<String, String>(topic, ""+i,"val" + i), new Callback() {
                public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                    String topic = recordMetadata.topic();
                    int partition = recordMetadata.partition();
                    long offset = recordMetadata.offset();
                    System.out.println("topic="+topic+"partition="+partition+"offset="+offset);
                }
            });

// 如果生产者没有使用分区, kafka会使用黏性 分区, 会随机选择一个分区, 并尽可能一直使用这个分区, 当该分区的 batch已满或者 linger.ms 时间到了会重新选择一个分区与上次不同
// 分区对应类: org.apache.kafka.clients.producer.RoundRobinPartitioner
3.4.1自定义分区器
/**
 * 自定义分区器, 判断value 是 user开头的发送到 0分区 其他发送到1分区
 */
public class MyPartitioner implements Partitioner {
    
    public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
        String val = value.toString();
        int partition =0;
        if(val.startsWith("user")){
            partition = 0;
        }else{
            partition =1;
        }
        return partition;
    }

    public void close() {
    }

    public void configure(Map<String, ?> configs) {
    }
}

// 使用分区, 在创建 kafka配置的时候指定相关的分区
properties.put(ProducerConfig.PARTITIONER_CLASS_CONFIG,"com.syl.demo.producer.MyPartitioner");

3.5 生产者常用的配置

// 1. 创建 kafka 生产者的配置对象
Properties properties = new Properties();

// 2. 给 kafka 配置对象添加配置信息:bootstrap.servers 
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092");

// key,value 序列化(必须):key.serializer,value.serializer 
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");

properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");

// RecordAccumulator:缓冲区大小,默认 32M:buffer.memory 
properties.put(ProducerConfig.BUFFER_MEMORY_CONFIG,33554432);

// batch.size: 批 次 大 小 , 默 认 16K 
properties.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384);

// linger.ms:等待时间,默认 0
properties.put(ProducerConfig.LINGER_MS_CONFIG, 1);

// compression.type:压缩,默认 none,可配置值 gzip、snappy、lz4 和 zstd 
properties.put(ProducerConfig.COMPRESSION_TYPE_CONFIG,"snappy");
3.1.7 生产者 ack 应答模式
  • 0
    生产者发送数据到kafka 不需要等待数据落盘就应答了消费者, 存在消息丢失的可能性;
  • 1
    生产者发送数据到kafka Leader 收到数据后应答, 存在消息丢失 消费者发送数据后 Leader 挂了, 新的 Leader不会知道这条数据
  • -1
    生产者发送过来的数据,Leader和SR队列里面的所有节点收齐数据后应答。
•数据完全可靠条件 = ACK级别设置为-1 + 分区副本大于等于2 + ISR里应答的最小副本数量大于等于2
3.1.7.1 应答模式总结
应答模式总结

acks=0,生产者发送过来数据就不管了,可靠性差,效率高; 
acks=1,生产者发送过来数据Leader应答,可靠性中等,效率中等;
acks=-1,生产者发送过来数据Leader和ISR队列里面所有Follwer应答,可靠性高,效率低;在生产环境中,acks=0很少使用;acks=1,一般用于传输普通日志,允许丢个别数据;acks=-1,一般用于传输和钱相关的数据, 对可靠性要求比较高的场景。
3.1.7.2 代码配置应答模式
// 设 置 acks 
properties.put(ProducerConfig.ACKS_CONFIG, "all");
// 重试次数retries,默认是 int 最大值,2147483647 
properties.put(ProducerConfig.RETRIES_CONFIG, 3);

4.kafka broker

4.1 基本工作原理

4.1.1.节点的注册

kafka 是依赖zookeeper 的, 当每一个 kafka 启动的时候, 会向zookeeper 注册节点信息注册到 zk的 /kafka/broker/ids 这个节点下就能够看到整个kafka集群的机器数量

4.1.2. kafka leader选举流程

kfka每台机器都会有 一个controller 模块, 启动后会向 zk的 /kafka/controller 注册那台机器先注册上那一台就是 控制整个集群选举的机器, 当某一台注册上后 它会监控 /kafka/broker/ids 这个节点的变化, 如果某台服务下线了, 监控机器会重新选举该节点的leader

4.1.3 topic 信息

当创建 topic 会向zk 的 /kafka/brokers/topics/topic_name, 节点注册相应的topic topic_name 下面对应的有这个 topic的分片信息(partitions), 每个分片都会有 谁是 leader isr队列信息

# 当我们创建一个 test topic 3个分区 3个副本 
/usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --create --partitions 3 --replication-factor 3 --topic test

# zookeeper 显示, 下面zk显示 三个分片信息, 显示的是 broker.id kafka配置文件的主机id
/kafka/brokers/topics/test/partitions/1/state
{
  "controller_epoch" : 9,
  "leader" : 1,
  "version" : 1,
  "leader_epoch" : 0,
  "isr" : [ 1, 3, 2 ]
}

/kafka/brokers/topics/test/partitions/2/state
{
  "controller_epoch" : 9,
  "leader" : 2,
  "version" : 1,
  "leader_epoch" : 0,
  "isr" : [ 2, 1, 3 ]
}
/kafka/brokers/topics/test/partitions/0/state
{
  "controller_epoch" : 9,
  "leader" : 3,
  "version" : 1,
  "leader_epoch" : 0,
  "isr" : [ 3, 2, 1 ]
}

4.2节点的服役和退役

4.2.1 下线kafka节点
# 创建一个2个副本的 主题
/usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --create --partitions 2 --replication-factor 2 --topic test

# 登录服务器操作
cd /root
vim topics-to-move.json
  {
    "topics": [
      {"topic": "test"}
    ],
    "version": 1
  }
	
# 生成一个负载均衡计划, 删除掉 broker id 为3的服务器
[root@node-1 ~]# /usr/local/kafka_2.12-3.0.0/bin/kafka-reassign-partitions.sh --bootstrap-server node-1:9092 --topics-to-move-json-file /root/topics-to-move.json --broker-list "1,2" --generate
# 当前的计划, 我们可以看到 有2个分区 0分区(副本在 1,3 服务器) 1分区(副本在 2,1 服务器)
Current partition replica assignment
{
	"version": 1,
	"partitions": [{
		"topic": "test",
		"partition": 0,
		"replicas": [1, 3],
		"log_dirs": ["any", "any"]
	}, {
		"topic": "test",
		"partition": 1,
		"replicas": [2, 1],
		"log_dirs": ["any", "any"]
	}]
}

# 修改后的计划, 按照我们命令上传了 生成的新计划里面没有3号服务器了 
Proposed partition reassignment configuration
{
	"version": 1,
	"partitions": [{
		"topic": "test",
		"partition": 0,
		"replicas": [1, 2],
		"log_dirs": ["any", "any"]
	}, {
		"topic": "test",
		"partition": 1,
		"replicas": [2, 1],
		"log_dirs": ["any", "any"]
	}]
}

# 创建执行计划, 拷贝 修改后的计划 json 并执行
vim increase-replication-factor.json
  {
    "version": 1,
    "partitions": [{
      "topic": "test",
      "partition": 0,
      "replicas": [1, 2],
      "log_dirs": ["any", "any"]
    }, {
      "topic": "test",
      "partition": 1,
      "replicas": [2, 1],
      "log_dirs": ["any", "any"]
    }]
  }
  
# 执行企划
/usr/local/kafka_2.12-3.0.0/bin/kafka-reassign-partitions.sh --bootstrap-server node-1:9092 --reassignment-json-file /root/increase-replication-factor.json --execute

# 验证计划
/usr/local/kafka_2.12-3.0.0/bin/kafka-reassign-partitions.sh --bootstrap-server node-1:9092 --reassignment-json-file /root/increase-replication-factor.json --verify

# 再次查看节点发现 3号机器已经没有了
[root@node-1 ~]# /usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --describe --topic test
Topic: test	TopicId: sIpAfy1qQziyfMqrhOBYBA	PartitionCount: 2	ReplicationFactor: 2	Configs: segment.bytes=1073741824
	Topic: test	Partition: 0	Leader: 1	Replicas: 1,2	Isr: 1,2
	Topic: test	Partition: 1	Leader: 2	Replicas: 2,1	Isr: 2,1
4.2.2 上线新的kafka 节点
vim topics-to-move.json
  {
    "topics": [
      {"topic": "test"}
    ],
    "version": 1
  }
  
# 生成计划
[root@node-1 ~]# /usr/local/kafka_2.12-3.0.0/bin/kafka-reassign-partitions.sh --bootstrap-server node-1:9092 --topics-to-move-json-file /root/topics-to-move.json --broker-list "1,2,3" --generate
Current partition replica assignment
{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[1,2],"log_dirs":["any","any"]},{"topic":"test","partition":1,"replicas":[2,1],"log_dirs":["any","any"]}]}

Proposed partition reassignment configuration
{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[2,3],"log_dirs":["any","any"]},{"topic":"test","partition":1,"replicas":[3,1],"log_dirs":["any","any"]}]}

# 执行计划
vim  increase-replication-factor.json
{"version":1,"partitions":[{"topic":"test","partition":0,"replicas":[2,3],"log_dirs":["any","any"]},{"topic":"test","partition":1,"replicas":[3,1],"log_dirs":["any","any"]}]}

/usr/local/kafka_2.12-3.0.0/bin/kafka-reassign-partitions.sh --bootstrap-server node-1:9092 --reassignment-json-file /root/increase-replication-factor.json --execute

# 查看topic 的分区副本信息, 已经按照我们的计划更新了
[root@node-1 ~]# /usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --describe --topic test
Topic: test	TopicId: sIpAfy1qQziyfMqrhOBYBA	PartitionCount: 2	ReplicationFactor: 2	Configs: segment.bytes=1073741824
	Topic: test	Partition: 0	Leader: 2	Replicas: 2,3	Isr: 2,3
	Topic: test	Partition: 1	Leader: 3	Replicas: 3,1	Isr: 1,3
4.2.3 kafka 选举流程和 ar , isr
  • ar 副本数量 和副本所存在的顺序
  • isr 该分区 副本存活的 服务器(如果follower 长时间没发送请求数据给 leader 就会被剔除 isr队列 默认30秒 replica.lag.time.max.ms参数控制)
# 创建 topic 3个分区 3个副本
[root@node-1 ~]# /usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --create --partitions 3 --replication-factor 3 --topic test
Created topic test.

# 查看topic详情下面显示 Isr 为存活的kafka存活的服务器, 
# Replicas 为 ar, 也就是副本存在哪些服务器.
# Leader 分片所在服务器的 Leader
[root@node-1 ~]# /usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --describe --topic test
Topic: test	TopicId: Ze9LaGjSTdS5cdAzI1LUKw	PartitionCount: 3	ReplicationFactor: 3	Configs: segment.bytes=1073741824
	Topic: test	Partition: 0	Leader: 3	Replicas: 3,2,1	Isr: 3,2,1
	Topic: test	Partition: 1	Leader: 1	Replicas: 1,3,2	Isr: 1,3,2
	Topic: test	Partition: 2	Leader: 2	Replicas: 2,1,3	Isr: 2,1,3
	
# 停止掉 3号服务器, 我们发现 isr 服务器少了, 是因为他是 存活的服务器列表, 由 ar=Replicas 2号服务器接替了 3号的位置
[root@node-1 ~]# /usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --describe --topic test
Topic: test	TopicId: Ze9LaGjSTdS5cdAzI1LUKw	PartitionCount: 3	ReplicationFactor: 3	Configs: segment.bytes=1073741824
	Topic: test	Partition: 0	Leader: 2	Replicas: 3,2,1	Isr: 2,1
	Topic: test	Partition: 1	Leader: 1	Replicas: 1,3,2	Isr: 1,2
	Topic: test	Partition: 2	Leader: 2	Replicas: 2,1,3	Isr: 2,1
	
# 停掉2号服务器, 我们发现停掉 2号服务器后 所有的分片信息都集中到了 1号服务器里面
[root@node-1 ~]# /usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --describe --topic test
Topic: test	TopicId: Ze9LaGjSTdS5cdAzI1LUKw	PartitionCount: 3	ReplicationFactor: 3	Configs: segment.bytes=1073741824
	Topic: test	Partition: 0	Leader: 1	Replicas: 3,2,1	Isr: 1
	Topic: test	Partition: 1	Leader: 1	Replicas: 1,3,2	Isr: 1
	Topic: test	Partition: 2	Leader: 1	Replicas: 2,1,3	Isr: 1
	
# 我们再启动 3号服务器
[root@node-1 ~]# /usr/local/kafka_2.12-3.0.0/bin/kafka-topics.sh --bootstrap-server node-1:9092 --describe --topic test
Topic: test	TopicId: Ze9LaGjSTdS5cdAzI1LUKw	PartitionCount: 3	ReplicationFactor: 3	Configs: segment.bytes=1073741824
	Topic: test	Partition: 0	Leader: 1	Replicas: 3,2,1	Isr: 1,3
	Topic: test	Partition: 1	Leader: 1	Replicas: 1,3,2	Isr: 1,3
	Topic: test	Partition: 2	Leader: 1	Replicas: 2,1,3	Isr: 1,3

总结: leader 选举策略,如果某个 broker 挂了 新的 leader需要具备, 在Isr队列存活 并且在 ar中排在最前面的副本(最前面的副本同步的数据最多)

4.2.4 故障转移的过程
  • LEO(Log end offset) 每个副本最新的offset
  • HW (所有副本最小的 LEO)
集群中有 1,2,3 台 broker
当某台 broker 故障停机了, 它首先先从 Isr 队列删除掉;
当这台服务器故障结束好了, 它会吧 自己上次 记录 HW之后的数据全部删除掉(会认为是没有验证的数据)
这台服务器就同步数据, 当同步到 基本水位线 HW 的时候 才重新加入 Iso队列
当集群中 leader 宕机了, 先按照选举流程选举 新的 leader 
所有的副本节点从leader同步数据如果高于leader的数据需要删除, 追求数据的一致性
4.2.5 leader再平衡策略

当我们集群中某个节点挂了, 后面有自己启动了, 这样节点比较多了, 就会将所有主题的 leader集中到一个或者某几台服务器上, 这样没有达到负载均衡的效果, kafka有自动平衡策略, 比较耗费集群性能

参数名称

描述

auto.leader.rebalance.enable

默认是 true。 自动Leader Partition 平衡。生产环境中,leader 重选举的代价比较大,可能会带来性能影响,建议设置为 false 关闭。

leader.imbalance.per.broker.percentage

默认是 10%。每个 broker 允许的不平衡的 leader的比率。如果每个 broker 超过了这个值,控制器会触发 leader 的平衡。

leader.imbalance.check.interval.seconds

默认值 300 秒。检查 leader 负载是否平衡的间隔时间。

4.2.6 kafka日志存储
# topic 是一个逻辑分区, 下面有 分区  分区下面有 Segement 默认每个Segement 存储1G文件,可以通过segment.bytes 修改配置
# 偏移量索引文件 存在 log文件存储 4Kb的数据在索引文件中添加一条日志, 采用稀疏索引存储的
00000000000000000000.index
# 存储正在的日志数据
00000000000000000000.log
# 时间戳索引
00000000000000000000.timeindex

5.消费者

5.1 消费者的基础概念

在kafka每个消费者都是独立的必须要有一个 groupId, 这个groupId 可以吧多个消费者串起来, 一个分区只能被同一个groupId的一个消费者消费消息,反过来说 一个消费者集群有10台机器, 这个分区有10个分区 刚好 每个消费者对应一个分区去消费, 如果分区有5个有10个消费者 剩下的5个消费者就闲着了

5.1.1 消费者的原理

多个消费者组成一个组那么它么怎么消费消息呢, 首先在每个 broker 对消费有一个模块为 coordinator 用来辅助消费者消费数据

如有一个 topic 名称为 user 有 3个分区, 2个副本
消费者组为 g1_user, 这个组中的消费者有4个
首先每个消费者 组名称.getHashCode() % 50 = (coordinator = brokerId)

每个消费者都去请求同一个 coordinator, coordinator会随机选择其中一个消费者 作为消费者中的老大;
选择好消费者 老大后 coordinator 会将所有的消费者发给消费者老大, 消费者老大定制一个消费计划 再次发送给 coordinator;
coordinator 获得消费计划后 分发给组中所有的消费者, 由每个消费者去找 broker 拉取消息, 这样消息就实现了一个消费的过程

在 消费者与coordinator 消费数据的时候 会有一个每3秒的心跳检测机制 一旦超过session.timeout.ms=45s 该消费者就会被移除触发再次平衡 或者 消费者处理消息超过 max.poll.interval.ms5分钟 也会再次触发再平衡策略;

5.1.2 消费者的配置

参数名称

描述

group.id

标记消费者所属的消费者组。

enable.auto.commit

默认值为 true,消费者会自动周期性地向服务器提交偏移量。

auto.commit.interval.ms

如果设置了 enable.auto.commit 的值为 true, 则该值定义了消费者偏移量向Kafka 提交的频率,默认 5s。

auto.offset.reset

当 Kafka 中没有初始偏移量或当前偏移量在服务器中不存在(如,数据被删除了),该如何处理? earliest:自动重置偏移量到最早的偏移量。 latest:默认,自动重置偏移量为最新的偏移量。 none:如果消费组原来的(previous)偏移量不存在,则向消费者抛异常。 anything:向消费者抛异常。

offsets.topic.num.partitions

consumer_offsets 的分区数,默认是 50 个分区。

heartbeat.interval.ms

Kafka 消费者和 coordinator 之间的心跳时间,默认 3s。该条目的值必须小于 session.timeout.ms , 也不应该高于session.timeout.ms 的 1/3。

session.timeout.ms

Kafka 消费者和 coordinator 之间连接超时时间,默认 45s。超过该值,该消费者被移除,消费者组执行再平衡。

max.poll.interval.ms

消费者处理消息的最大时长,默认是 5 分钟。超过该值,该消费者被移除,消费者组执行再平衡。

fetch.min.bytes

默认 1 个字节。消费者获取服务器端一批消息最小的字节数。

fetch.max.wait.ms

默认 500ms。如果没有从服务器端获取到一批数据的最小字节数。该时间到,仍然会返回数据。

fetch.max.bytes

默认Default: 52428800(50 m)。消费者获取服务器端一批消息最大的字节数。如果服务器端一批次的数据大于该值(50m)仍然可以拉取回来这批数据,因此,这不是一个绝对最大值。一批次的大小受 message.max.bytes ( brokerconfig)or max.message.bytes (topic config)影响。

max.poll.records

一次 poll 拉取数据返回消息的最大条数,默认是 500 条。

partition.assignment.strategy

消 费 者 分 区 分 配 策 略 , 默 认 策 略 是 Range +CooperativeSticky。Kafka 可以同时使用多个分区分配策略。可以选择的策略包括: Range 、 RoundRobin 、 Sticky 、

5.2 消费者代码实现

5.2.1 普通的消费者代码

public static void main(String[] args) {
        Properties proper = new Properties();
        // 2.给消费者配置对象添加参数
        proper.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "hadoop102:9092,node-2:9092,node-3:9092");

        // 配置序列化 必须
        proper.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        proper.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());

        // 配置消费者组(组名任意起名) 必须
        proper.put(ConsumerConfig.GROUP_ID_CONFIG, "g1");

        KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(proper);

        consumer.subscribe(Arrays.asList("test"));

        while (true){
            ConsumerRecords<String, String> poll = consumer.poll(Duration.ofSeconds(1));
            for (ConsumerRecord<String, String> stringStringConsumerRecord : poll) {
                System.out.println(stringStringConsumerRecord);
            }
        }
    }

5.2.2 消费者指定消费某个分区

// 删除下面这行代码
// consumer.subscribe(Arrays.asList(topic));
// 消费某个主题的某个分区数据
ArrayList<TopicPartition>	topicPartitions	=	new ArrayList<>();
topicPartitions.add(new TopicPartition("first", 0));
consumer.assign(topicPartitions);

5.2.3 消费者消费策略

// 修改分区分配策略
proper.put(ConsumerConfig.PARTITION_ASSIGNMENT_STRATEGY_CONFIG,"org.apache.kafka.clients.consumer.RoundRobinAssignor");