Kafka(一)入门

一.概述

1.简单了解

Kafka : Kafka是 一个开源的分布式事件流平台 (Event Streaming Platform,被数千家公司用于高性能数据管道、流分析、数据集成和关键任务应用

目 前 企 业 中 比 较 常 见 的 消 息 队 列 产 品 主 要 有 Kafka、ActiveMQ、 RabbitMQ、RocketMQ等,在大数据场景主要采用Kafka作为消息队列

传统消息队列的应用场景

传统的消息队列的主要应用场景包括:缓存/消峰、解耦和异步通信

缓冲/消峰:有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况,下图,生产者发送消息的数据时100条/秒,二消费者处理消息的能力只有30条/秒,那么Kafka可以起到暂时缓冲消息的作用

在这里插入图片描述

解耦:允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束

比如Spark和Spring想和数据库打交道,就可以根据一个消息队列Q1完成
在这里插入图片描述

2.两种模式

(1)点对点模式

一个生产者,一个消费者,一个主题(存储消息的容器,是个逻辑概念,实际消息存在文件中),消费者主动拉取数据,消息收到后通知队列清除消息

(2)发布/订阅模式(常用)

多个生产者,多个消费者,可以有多个topic主题

消费者消费数据之后,Kafka集群不删除数据

每个消费者(消费者组整体看做一个消费者)相互独立,可以消费相同主题相同分区的数据,互不影响。特别注意,消费者组里消费者只能消费不同的分区

3.Kafka基础架构

broker:就是一台服务器

topic:kafka数据写入操作的基本单元

topic分区:提高topic可用性、可靠性

leader:每个分区的主(生产者、消费者都针对leader)

follower:每个分区的副本(副本的作用是保证可靠性)

group:消费者组,里面有单个的消费者

consumer:单个的消费者
在这里插入图片描述

1.为了提高吞吐量,一个topic(topic是Kafka数据写入操作的基本单元)被分成多个分区,producer发布数据时,必须指定将该消息发布到哪个topic。consumer订阅消息时,也必须指定订阅哪个topic的信息

2.消费者组,为了提高效率,每一个消费者组的消费者可以消费一个分区的数据,一对一的关系,同一个消费者组的消费者不可以消费同一个分区

3.为了保证可靠性,每个分区的数据有备份,备份称为follower,主数据是leader,无论生产还是消费,处理的对象都是leader,zookeeper可以帮助我们记录谁是leader,新版本的kafka已经不需要zookeeper了,但目前使用zookeeper还是比较多的

二.Kafka快速入门

1.安装Kafka

下载安装包
在这里插入图片描述
tar zxvf 解压,重命名

在这里插入图片描述

bin目录里面是一些命令
config是配置文件
libs是一些依赖jar包

重要配置

在这里插入图片描述
broker.id kafka在集群中身份的唯一标识,不可以重复
在这里插入图片描述

log.dirs kafka文件存放的位置
在这里插入图片描述
第三个修改的地方

zookeeper.connect=hadoop102:2181,hadoop103:2181,hadoop104:2181/ka
fka

分发到其他服务器节点

修改另外两个节点的broker.id为1和2

sudo vim /etc/profile.d/my_env.sh

配置kafka环境变量

#KAFKA_HOME
export KAFKA_HOME=/opt/module/kafka
export PATH=$PATH:$KAFKA_HOME/bin
source /etc/profile

分发

sudo /home/gzhu/bin/xsync /etc/profile.d/my_env.sh

source /etc/profile

另外两台主机

source /etc/profile

启动zookeeper集群

在kafka目录的bin下编写kafka一键启动脚本

vim kf.sh

# !/bin/bash
case $1 in
"start")
       for i in hadoop102 hadoop103 hadoop104
       do
          echo " --------启动 $i Kafka-------"
          ssh $i  "/opt/module/kafka/bin/kafka-server-start.sh -daemon /opt/module/kafka/config/server.properties"
      done
;;
"stop")
    for i in hadoop102 hadoop103 hadoop104
    do
         echo " --------停止 $i Kafka-------"
         ssh $i "/opt/module/kafka/bin/kafka-server-stop.sh "
    done
;;
esac

添加执行权限

chmod +x kf.sh

2.命令操作Kafka

启动kafka
在这里插入图片描述

Topic命令

kafka-topics.sh 命令,后面跟一些参数

注意:前面的符号是- -

参数说明
–bootstrap-server <String: server toconnect to>连接kafka的主机和端口号
–topic name操作的topic名称
–create创建主题
–delete删除主题
–alter修改主题
–list查看所有主题
–describe查看主题详细信息
–partitions设置分区数
–replication-factor num设置分区副本
–config更新系统默认的配置

bin目录下:

./kafka-topics.sh --bootstrap-server hadoop102:9092 --topic first --create --partitions 1 --replication-factor 3

-bootstrap-server hadoop102:9092 连接集群
–topic first 指定主题名字
–create 创建主题
–partitions 1 分区为1
–replication-factor 3 主题为3

./kafka-topics.sh --bootstrap-server hadoop102:9092 --topic first --describe

查看主题的详细信息

在这里插入图片描述

./kafka-topics.sh --bootstrap-server hadoop102:9092 --topic first --alter --partitions 3 

–partitions 3 意思是修改分区数为3,注意分区只能增加不能修改

分区副本虽有命令,但不能使用命令行的操作进行修改分区副本,暂且放一放

生产者发送数据

kafka-console-producer.sh 要指定集群连接和发送到哪个topic

[gzhu@hadoop102 bin]$ ./kafka-console-producer.sh --bootstrap-server hadoop102:9092 --topic first

消费者消费数据

kafka-console-consumer.sh 要指定集群连接和消费哪个topic

 ./kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic first 

在这里插入图片描述
在这里插入图片描述

注意,消费者默认只会消费消费者启动后,生产者发送的数据,如果要消费历史数据,那么消费者应该加一个--from beginning 参数

3.异步发送

kafka异步发送指的外部数据到RecordAccumulator(一个存储消息的内存缓冲区)的发送,即外部数据发送到了RecordAccumulator就算成功 [ 具体理论可参考 kafka(二)]

导入依赖

<dependencies>
    <dependency>
        <groupId>org.apache.kafka</groupId>
        <artifactId>kafka-clients</artifactId>
        <version>3.0.0</version>
    </dependency>
</dependencies>

以下测试是开启了消费者的情况下

普通异步发送 发送即忘模式

public class CustomProducer {
    public static void main(String[] args) {
        // 1.配置属性
        Properties properties = new Properties();
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092");
        // 指定对应的key和value序列化
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());


        // 2.创建生产者
        KafkaProducer<String, String> producer = new KafkaProducer<>(properties);
        // 3.发送数据
        for (int i = 0; i < 3; i++) {
            producer.send(new ProducerRecord<>("topicx","data" + i));
        }
        // 4.关闭资源
        producer.close();
    }
}

可以看到,两个不同的消费者都消费到了主题topicx分区1的数据,也验证了每个消费者(消费者组整体看做一个消费者)相互独立,可以消费相同主题相同分区的数据,互不影响
在这里插入图片描述

回调异步发送

可以通过回调函数获取分区等信息,并能做异常处理,只有回调函数执行结束生产者才会结束,否则一致阻塞

// 3.发送数据
producer.send(new ProducerRecord<>("topicx","Producer to topicx -- callback"), new Callback() {
    @Override
    public void onCompletion(RecordMetadata recordMetadata, Exception e) {
        if(e == null){
            System.out.println("发送到的主题:" + recordMetadata.topic());
            System.out.println("发送到的分区:"+recordMetadata.partition());
        }
    }
});

可以返回给生产者一些topic或者分区的信息
在这里插入图片描述

4.同步发送

kafka同步发送指的外部数据到kafka集群,kafka集群收到后正确反馈后才可以发送下一批数据
在这里插入图片描述

只需要在send后面加一个get方法就实现了同步发送,0是发送到哪个分区,""是发送的key,"Hello"是发送的数据,实际上,同步发送返回的是一个Future,通过get方法来获取返回结果,如果没有结果,将会一直阻塞

// 3.发送数据
producer.send(new ProducerRecord<>("topicx",0,"","Hello")).get();
5.订阅主题

务必配置消费者的id,不同的id视为不同的消费者,相同的id视为是一个消费者组

public class CustomConsumer {
    public static void main(String[] args) {
        // 1.配置
        Properties properties = new Properties();
        properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092");

        // 2.反序列化
        properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,StringDeserializer.class);

        // 3.配置消费者id
        properties.put(ConsumerConfig.GROUP_ID_CONFIG,"100");

        // 4.创建消费者
        KafkaConsumer<String,String> consumer = new KafkaConsumer<>(properties);

        // 5.订阅主题
        ArrayList<String> topics = new ArrayList<>();
        topics.add("topicx");
        consumer.subscribe(topics);

        // 6.消费
        while(true){
            ConsumerRecords<String,String> records = consumer.poll(Duration.ofSeconds(1));
            for (ConsumerRecord<String, String> record : records) {
                System.out.println(record.topic() +" " + record.partition() + " "+ record.value());
            }
        }

    }
}
6.订阅某主题的分区
public class CustomConsumerPartition {
    public static void main(String[] args) {
        // 1.配置
        Properties properties = new Properties();
        properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"hadoop102:9092");

        // 2.反序列化
        properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,StringDeserializer.class);

        // 3.配置消费者id
        properties.put(ConsumerConfig.GROUP_ID_CONFIG,"kun100");

        // 4.创建消费者
        KafkaConsumer<String,String> consumer = new KafkaConsumer<>(properties);

        // 5.订阅主题topicx的0号分区
        ArrayList<TopicPartition> topicPartitions = new ArrayList<>();
        topicPartitions.add(new TopicPartition("topicx",0));
        consumer.assign(topicPartitions);

        // 6.消费
        while(true){
            ConsumerRecords<String,String> records = consumer.poll(Duration.ofSeconds(1));
            for (ConsumerRecord<String, String> record : records) {
                System.out.println(record);
            }
        }

    }
}
7.大数据环境下的kafka工具类
public class MyKafkaUtil {

    private static String brokers = "hadoop102:9092,hadoop103:9092,hadoop104:9092";
	// kafka生产者
    public static FlinkKafkaProducer<String> getKafkaProducer(String topic){
        return new FlinkKafkaProducer<String>(brokers,topic,
                new SimpleStringSchema());
    }
	// kafka生产者,主题可以变化,怎么使用在下面
    public static <T> FlinkKafkaProducer<T> getKafkaProducer(KafkaSerializationSchema<T> kafkaSerializationSchema){

        Properties properties = new Properties();
        properties.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,brokers);
        return new FlinkKafkaProducer<T>("default_topic", // 默认主题,必须有,但是我们不用
                kafkaSerializationSchema, // 一个kafkaSerializationSchema
                properties, // 配置信息
                FlinkKafkaProducer.Semantic.NONE);
    }
	// kafka消费者
    public static FlinkKafkaConsumer<String> getKafkaConsumer(String topic,String groupId){

        Properties properties = new Properties();
        properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,brokers);
        properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,StringDeserializer.class);
        properties.put(ConsumerConfig.GROUP_ID_CONFIG,groupId);
        // 没有offset,从新提交的数据开始消费 默认5s自动提交一次offset
        properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,"latest");

       return new FlinkKafkaConsumer<>(topic, new SimpleStringSchema(), properties);
    }
}

着重说一下主题自由变化的生产者,我们需要传入一个KafkaSerializationSchema,泛型可以自己定,这里我们是JSONObject

 kafka.addSink(MyKafkaUtil.getKafkaProducer(new KafkaSerializationSchema<JSONObject>() {
            @Override
            public ProducerRecord<byte[], byte[]> serialize(JSONObject jsonObject, @Nullable Long aLong) {
                return new ProducerRecord<byte[], byte[]>(topic,value);
            }
        }));

三.Kafka-Eagle可视化监控

1.环境准备

集群中要有MySQL,Kafka-Eagle 的安装依赖于MySQL,MySQL 主要用来存储可视化展示的数据

在kafka集群未启动的情况下

vim bin/kafka-server-start.sh

if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then
export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G"
fi

修改为

if [ "x$KAFKA_HEAP_OPTS" = "x" ]; then
   export KAFKA_HEAP_OPTS="-server -Xms2G -Xmx2G
-XX:PermSize=128m -XX:+UseG1GC -XX:MaxGCPauseMillis=200
-XX:ParallelGCThreads=8 -XX:ConcGCThreads=5
-XX:InitiatingHeapOccupancyPercent=70"
   export JMX_PORT="9999"
#export KAFKA_HEAP_OPTS="-Xmx1G -Xms1G"
fi

启动kafka集群

2.安装Kafka-eagle

解压
在这里插入图片描述
该文件下还有一个压缩包,再次解压
在这里插入图片描述

在这里插入图片描述

改名字

mv efak-web-2.0.8 efak

进入该目录下的conf目录

vim system-config.properties


在这里插入图片描述
改为,监控一个集群,信息在zookeeper
在这里插入图片描述
配置自己的mysql

mysql不要忘了创建ke数据库
在这里插入图片描述

添加环境变量

sudo vim /etc/profile.d/my_env.sh
# kafkaEFAK
export KE_HOME=/opt/module/efak
export PATH=$PATH:$KE_HOME/bin
source /etc/profile

启动
在这里插入图片描述
在这里插入图片描述
访问

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jumanji_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值