Kafka安装部署及基本使用

本文详细介绍了Apache Kafka的单机安装步骤,包括下载Kafka 2.0.0版本,解压安装,配置Zookeeper,启动与停止Zookeeper及Kafka服务。此外,还讲解了如何创建和管理topic,以及使用Java客户端进行生产者和消费者的配置。最后,提到了自定义分区策略和Kafka生产者与消费者的Java代码示例。
摘要由CSDN通过智能技术生成

Kafka单机安装部署

下载kafka

https://archive.apache.org/dist/kafka/2.0.0/kafka_2.11-2.0.0.tgz

安装过程

安装过程非常简单,只需要解压就行,因为这个是编译好之后的可执行程序解压

tar -zxvf  kafka_2.11-2.0.0.tgz 
配置zookeeper

因为kafka依赖于zookeeper来做master选举一起其他数据的维护,所以需要先启动zookeeper节点 kafka内置了zookeeper的服务,所以在bin目录下提供了这些脚本

zookeeper-server-start.sh

zookeeper-server-stop.sh

在config目录下,存在一些配置文件

zookeeper.properties

server.properties

所以我们可以通过下面的脚本来启动zk服务,当然,也可以自己搭建zk的集群来实现
启动zookeeper

sh zookeeper-server-start.sh -daemon ../config/zookeeper.properties

停止zookeeper
首先,修改zookeeper-server-stop.sh脚本,原脚本可能执行停止zookeeper失败,修改脚本的PIDS

vim zookeeper-server-stop.sh

PIDS=$(jps -lm | grep -i QuorumPeerMain | grep -v grep | awk ‘{print $1}’)

再执行脚本

sh zookeeper-server-stop.sh -daemon ../config/zookeeper.properties
启动和停止kafka
  • 修改server.properties, 增加zookeeper的配置,localhost替换为具体的ip

    zookeeper.connect=localhost:2181
    
  • 启动kafka

    sh kafka-server-start.sh -daemon ../config/server.properties
    
  • 停止kafka

    首先,修改kafka-server-stop.sh脚本,原脚本可能执行停止kafka失败,修改脚本的PIDS

    vim kafka-server-stop.sh
    

    PIDS=$(jps -lm | grep -i ‘kafka.Kafka’ | awk ‘{print $1}’)

    再执行脚本

    sh kafka-server-stop.sh -daemon ../config/server.properties
    

kafka的基本操作

创建topic
sh kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 -partitions 2 --topic case-keyPerson

replication-factor 表示该topic需要在不同的broker中保存几份,这里设置成1,表示在两个broker中 保存两份

partitions 分区数

topic 消息主题

查看topic
sh kafka-topics.sh --list --zookeeper localhost:2181
查看topic属性
sh kafka-topics.sh --describe --zookeeper localhost:2181 --topic case-keyPerson
消费消息
sh kafka-console-consumer.sh --bootstrap-server 当前服务ip:9092 --topic case-keyPerson --from-beginning
发送消息
sh kafka-console-producer.sh --broker-list 当前服务ip:9092 --topic case-keyPerson
日志清除策略

修改server.properties, 设置日志清除策略

#消息保留达到12小时,就会执行删除
log.retention.hours=12

Java客户端

依赖引用

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

    <dependencies>
		<dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
            <version>2.3.7.RELEASE</version>
        </dependency>
        ...
	</dependencies>
kafka配置
#============== kafka ===================
# 指定kafka server的地址,集群配多个,中间,逗号隔开
spring.kafka.bootstrap-servers=kafka服务ip:9092
#=============== producer 生产者=======================
# 写入失败时,重试次数。当leader节点失效,一个repli节点会替代成为leader节点,此时可能出现写入失败,
# 当retris为0时,produce不会重复。retirs重发,此时repli节点完全成为leader节点,不会产生消息丢失。
spring.kafka.producer.retries=0
# 每次批量发送消息的数量,produce积累到一定数据,一次发送
spring.kafka.producer.batch-size=16384
# produce积累数据一次发送,缓存大小达到buffer.memory就发送数据
#spring.kafka.producer.buffer-memory=33554432
# 提交延时
spring.kafka.producer.properties.linger.ms=0
#procedure要求leader在考虑完成请求之前收到的确认数,用于控制发送记录在服务端的持久化,其值可以为如下:
#acks = 0 如果设置为零,则生产者将不会等待来自服务器的任何确认,该记录将立即添加到套接字缓冲区并视为已发送。在这种情况下,无法保证服务器已收到记录,并且重试配置将不会生效(因为客户端通常不会知道任何故障),为每条记录返回的偏移量始终设置为-1。
#acks = 1 这意味着leader会将记录写入其本地日志,但无需等待所有副本服务器的完全确认即可做出回应,在这种情况下,如果leader在确认记录后立即失败,但在将数据复制到所有的副本服务器之前,则记录将会丢失。
#acks = all 这意味着leader将等待完整的同步副本集以确认记录,这保证了只要至少一个同步副本服务器仍然存活,记录就不会丢失,这是最强有力的保证,这相当于acks = -1的设置。
#可以设置的值为:all, -1, 0, 1
spring.kafka.producer.acks=1

# 指定消息key和消息体的编解码方式
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer

#=============== consumer 消费者 =======================
# 指定默认消费者group id --> 由于在kafka中,同一组中的consumer不会读取到同一个消息,依靠groud.id设置组名
spring.kafka.consumer.group-id=group.dev
# earliest:从最早的offset开始消费,就是partition的起始位置开始消费
# latest:从最近的offset开始消费,就是新加入partition的消息才会被消费
spring.kafka.consumer.auto-offset-reset=earliest
# enable.auto.commit:true --> 设置自动提交offset
spring.kafka.consumer.enable-auto-commit=true
#如果'enable.auto.commit'为true,则消费者偏移自动提交给Kafka的频率(以毫秒为单位),默认值为5000。
spring.kafka.consumer.auto-commit-interval=100
# 消费端监听的topic不存在时,项目启动会报错(关掉)
spring.kafka.listener.missing-topics-fatal=false
# 设置批量消费
# spring.kafka.listener.type=batch
# 批量消费每次最多消费多少条消息
# spring.kafka.consumer.max-poll-records=50
# 指定消息key和消息体的编解码方式
spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer

java代码创建 topic
@Bean()
public NewTopic newTopic() {
	// 参数1:name 消息主题
	// 参数2:partitions 分区数量
	// 参数3:replication factor 数量
	return new NewTopic("topic", 2, (short) 1);
}

加载流程

1.KafkaAutoConfiguration自动化装配,会加载KafkaAdmin类,KafkaAdmin类使用KafkaProperties.admin构建。

@Bean
@ConditionalOnMissingBean
public KafkaAdmin kafkaAdmin() {
    KafkaAdmin kafkaAdmin = new KafkaAdmin(this.properties.buildAdminProperties());
    kafkaAdmin.setFatalIfBrokerNotAvailable(this.properties.getAdmin().isFailFast());
    return kafkaAdmin;
}

2.KafkaAdmin继承ApplicationContextAware, SmartInitializingSingleton接口

ApplicationContextAware: 通过它Spring容器会自动把上下文环境对象调用ApplicationContextAware接口中的setApplicationContext方法。

SmartInitializingSingleton: 在spring容器管理的所有单例对象(非懒加载对象)初始化完成之后调用的回调接口。其触发时机为postProcessAfterInitialization之后。

@Override
public void afterSingletonsInstantiated() {
    this.initializingContext = true;
    // 默认true,可通过KafkaProperties.admin设值
    if (this.autoCreate) {
    	initialize();
    }
}

/**
 * Call this method to check/add topics; this might be needed if the broker was not
 * available when the application context was initialized, and
 * {@link #setFatalIfBrokerNotAvailable(boolean) fatalIfBrokerNotAvailable} is false,
 * or {@link #setAutoCreate(boolean) autoCreate} was set to false.
 * @return true if successful.
 * @see #setFatalIfBrokerNotAvailable(boolean)
 * @see #setAutoCreate(boolean)
 */
public final boolean initialize() {
    // 这里从spring上下文获取NewTopic.class类型的bean,也就是我们上文使用java代码定义的NewTopic
    Collection<NewTopic> newTopics = this.applicationContext.getBeansOfType(NewTopic.class, false, false).values();
    if (newTopics.size() > 0) {
        AdminClient adminClient = null;
        try {
            // 创建admin客户端
            adminClient = AdminClient.create(this.config);
        }
        catch (Exception e) {
            if (!this.initializingContext || this.fatalIfBrokerNotAvailable) {
                throw new IllegalStateException("Could not create admin", e);
            }
            else {
                LOGGER.error(e, "Could not create admin");
            }
        }
        if (adminClient != null) {
            try {
                // 如果topic不存在,创建topic
                addTopicsIfNeeded(adminClient, newTopics);
                return true;
            }
            catch (Exception e) {
                if (!this.initializingContext || this.fatalIfBrokerNotAvailable) {
                    throw new IllegalStateException("Could not configure topics", e);
                }
                else {
                    LOGGER.error(e, "Could not configure topics");
                }
            }
            finally {
                this.initializingContext = false;
                adminClient.close(this.closeTimeout);
            }
        }
    }
    this.initializingContext = false;
    return false;
}
kafka生产者
@Component
public class CaseKafkaProducer {

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    public void send(String topic, String data) {
        kafkaTemplate.send(topic, String.valueOf(System.currentTimeMillis()), data);
    }

    /**
     * <p>
     * <code>send</code> 分发机制,默认情况下kafka采用的是hash取模的分区算法。如果key为null,则会随机分配一个分区。
     * 这个随机实在参数"metadata.max.age.ms"的事件范围内随机训责一个,对于这个时间段内,如果可疑为null,则只会发送到唯一的分区。
     * spring.kafka.producer.properties.metadata.max.age.ms=50000
     * 这个值默认情况下是10分钟更新一次
     * </p>
     *
     * @param topic
     * @param key
     * @param data
     * @return
     */
    public void send(String topic, String key, String data) {
        kafkaTemplate.send(topic, key, data);
    }
}

kafka生产者自定义分区策略

实现org.apache.kafka.clients.producer.Partitioner接口

kafka消费者
@Component
public class CaseKafkaConsumer {
	// 监听topic主题
    @KafkaListener(topics = {"topicName"})
    public void listener(ConsumerRecord record) {
        Optional msg = Optional.ofNullable(record.value());
        if (msg.isPresent()) {
            System.out.println("consumer get:" + msg.get());
        }
    }
}
kafka消费者自定义分区策略

@KafkaListener(topicPartitions={@TopicPartition(topic = “”, partitions = {“0”})})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值