Kafka 的安装和配置
0 安装
略,到官网下载即可。注意 Kafka 还需要 Zookeeper 支持。
Kafka 版本 :
kafka_2.13-2.4.0
Zookeeper 版本 :
Zookeeper-3.5.4-beta
jdk 版本 :
openjdk 8
1 Kafka 配置
Kafka 的主要配置文件是 /config/server.properties。
## 实例 id,同一集群中的所有实例的 id 不可相同
broker.id = 0
## kafka 服务监听的地址和端口
## 设置了 advertised.listeners 之后可以不设置客户端的 hosts 文件,原因未知
listener = PLAINTEXT://xxxxxxx:9092
advertised.listeners = PLAINTEXT://xxxxxxx:9092
##### 通用配置 #####
## 处理磁盘 io 的线程数
num.io.threads = 8
## 处理网络 io 的线程数
num.network.threads = 3
## 用来处理后台任务的线程数,例如过期消息文件的删除等
backgroud.threads = 4
## kafka 启动时回复数据和关闭时保存数据到磁盘时使用的线程数
num.recovery.threads.per.data.dir = 10
## 消息发送的缓存区大小
socket.send.buffer.bytes = 102400
## 消息接收的缓存区大小
socket.receive.buffer.bytes = 102400
## socket 请求的最大缓存值
socket.request.max.bytes = 10240000
## 再平衡延迟时间
## 再平衡的意义是当 consumer 发生上下线的时候,会重新分配 partition 的消费权
## 延迟的好处是如果 consumer 在一段时间内集中上下线,可以在延迟时间之后一次性处理
## 如果发生一次变动就处理一次,效率会较低
## 默认为 0 ms,即为不延迟
group.initial.rebalance.delay.ms = 10
##### 数据日志配置 #####
## kafka 日志数据存储目录,用逗号分割可以指定多个
# log.dirs = /tmp/kafka-logs-1,/tmp/kafka-logs-2
log.dirs = /tmp/kafka-logs
## 刷新日志到磁盘的阈值
# 根据消息数量做刷新,默认使用该策略
# log.flush.interval.messages = 10000
# 根据时间做刷新,单位 毫秒,默认不开启
log.flush.interval.ms = 1000
## 检查刷新机制的时间间隔
## 该参数的意义是每隔一定时间检查一次是否到达 flush 的设置阈值
log.flush.scheduler.interval.ms = 3000
## 记录上次固化数据到硬盘的时间点,主要用于数据恢复
## 默认值 60000
log.flush.offset.checkpoint.interval.ms = 60000
## 日志的存储时间,可以以小时单位,也可以设置为分钟或者毫秒
## 当超过这个时间,就会执行日志清除
# log.retention.minutes = 120
# log.retention.ms = 120
# 默认使用小时,值为 168
log.retention.hours = 2
## 每个 partition 的存储大小,如果超过了就会执行日志清除
## -1 代表不限制,默认 1073741824
log.retention.bytes = 1073741824
## 日志大小的检查周期,如果已经到达了大小,就触发文件删除
log.retention.check.interval.ms = 300000
## 指定日志每隔多久检查一次是否可以被删除,默认为 1 min
log.cleanup.internal.mins = 1
## 日志清除的策略,默认为 delete
## 如果要使用日志压缩,就需要让策略包含 compact
## 需要注意的是,如果开启了 compact 策略,则客户端提交的消息的 key 不允许为 null,否则提交报错
# log.cleanup.policy = delete
log.cleanup.policy = delete
## 是否开启日志压缩
## 默认开启,但是只有在日志清除策略包含 compact 的时候日志压缩才会生效
## 日志压缩的逻辑是对 key 进行整合,对相同 key 的不同 value 值只保存最后一个版本
log.cleaner.enable = true
## 开启压缩的情况才生效,日志压缩运行的线程数
log.cleaner.threads = 8
## 日志压缩去重的缓存内存,内存越大效率越好
## 单位 byte,默认 524288 byte
log.cleaner.io.buffer.size = 524288
## 日志清理的频率,越大就越高效,但是内存消耗会更大
log.cleaner.min.cleanable.ratio = 0.7
## 单个日志文件的大小,默认 1073741824
log.segment.bytes = 1073741824
## 日志被真正清除的时间
## 日志过了保存时间之后,只是被逻辑性删除,无法被索引到,但是没有真的从磁盘中被删除
## 此参数用于设置在被标注为逻辑删除后的日志被真正删除的时间
log.segment.delete.delay.ms = 60000
##### Topic 配置 #####
## 是否允许自动创建 topic
## 若为 false,则只能通过命令创建 topic
## 默认 true
auto.create.topics.enable = true
## 每个 topic 的默认分区 partition 个数,在 topic 创建的时候可以指定,如果不指定就使用该参数
## partition 数量直接影响了能够容纳的 cosumer 数量
num.partitions = 1
## topic partition 的副本数,副本越多,越不容易因为个别 broker 的问题而丢失数据
## 副本越多,可用性越高,但是每次数据写入之后同步花费的时间更多
offsets.topic.replication.factor = 1
transaction.state.log.replication.factor = 1
transaction.state.log.min.isr = 1
##### Zookeeper 配置 #####
## Zookeeper 地址,用逗号分割可以指定多个
# zookeeper.connect = localhost:2181,localhost:2182
zookeeper.connect = localhost:2101
## Zookeeper 集群的超时时间
zookeeper.connection.timeout.ms = 6000
2 创建 topic
上述配置中设置了自动创建 topic,但是也可以手工创建 :
./bin/kafka-topics.sh --create \
--zookeeper localhost:2101 \
--replication-factor 1 \
--partitions 1 \
--topic test1
查看 topic :
./bin/kafka-topics.sh --zookeeper localhost:2101 --list
3 启动 Kafka
./bin/kafka-server-start.sh -daemon ./config/server.properties &
SpringBoot Kafka 配置代码
1 pom
spring boot 版本 :
org.springframework.boot
spring-boot-starter-parent
2.2.2.RELEASE
引入 jar 包 :
org.springframework.kafka
spring-kafka
2.4.1.RELEASE
org.springframework
spring-*
2 yaml 配置
spring:
kafka:
## 生产者配置,如果本实例只是消费者,可以不配置该部分
producer:
# client id,随意配置,不可重复
client-id: boot-producer
# kafka 服务地址,pi + 端口
bootstrap-servers: aliyun-ecs:9092
# 用于序列化的工具类
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
# 消息发送失败情况下的重试次数
retries: 1
# 批量上传的 buffer size,可以是消息数量,也可以是内存量
batch-size: 10000
buffer-memory: 300000
# 等待副本同步之后才确认消息发送成功,可选的值有 0,1,-1,all 等
# 设置为 0 的意思是不等待任何副本同步完成就直接返回
# 设置为 1 的意思是只等待 leader 同步完成
# all 的意思是全部同步完才确认,但是速度会比较慢
acks: 1
## 消费者配置,如果本实例只是生产者,可以不配置该部分
consumer:
# client id,随意配置,不可重复
client-id: boot-consumer
# 消费者分组 id,同一组别的不同消费者共同消费一份数据
group-id: consumer-group-1
# kafka 服务地址,pi + 端口
bootstrap-servers: aliyun-ecs:9092
# 用于反序列化的工具类
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
# 自动更新 offset
enable-auto-commit: true
# 如果 enable-auto-commit 设置为 true,则每隔一段时间提交一次 offset
# 时间单位为毫秒,默认值 5000 (5s)
auto-commit-interval: 1000
# offset 消费指针
# earliest 代表从头开始消费,lastest 代表从新产生的部分开始消费
auto-offset-reset: earliest
3 代码
生产者配套代码:
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* kafka mq 生产者包装类
*/
@Component
public class MQProductor {
@Resource
KafkaTemplate kt;
/**
* 发送消息的方法
* @param topic 创建的 topic
* @param partition topic 分片编号,从 0 开始
* @param key 消息 key,主要用来分片和作为压缩凭据,可以重复,可以为空
* @param message 消息主体
*/
public void send(String topic,Integer partition,String key,String message) {
kt.send(topic,partition,key,message);
}
public void send(String message) {
send("test-topic",0,"",message);
}
}
消费者配套代码:
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
/**
* kafka mq 消费者包装类
*/
@Component
public class MQListener {
/**
* 监听方法,可以一次性监听多个 topic
* @param cr kafka 返回的消息包装类
*/
@KafkaListener(topics = {"test-topic" /*,"test-topic-2"*/ })
public void consume(ConsumerRecord cr) {
// value
String value = cr.value();
System.out.println(value);
// key
String key = cr.key();
System.out.println(key);
// 读取指针
long offset = cr.offset();
System.out.println(offset);
// 读取的分区编号
int partition = cr.partition();
System.out.println(partition);
// topic
String topic = cr.topic();
System.out.println(topic);
}
}