消息队列Kafka初步使用

一、概述

1.1 消息队列-Message Queue

1.1.1 消息:

消息是系统间通信载体,是分布式应用不可或缺一部分。目前系统间发送消息的方式有两种。

1.1.1.1 同步消息

即使消息:打电话、表单提交、WebService(SOAP)、Dubbo/SpringCloud

要求消息发送方和接收方必须同时在线,一般都需要和接收方建立会话。

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/S3IlDGJpqgJw.png

1.1.1.2 异步消息

发动方不接受对象是否在线,一般不需要和接收方建立会话,在接收方上线后,一般会自获取发送方发送的消息。

离线消息:发短信、发邮件、写信—消息队列

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/0ebh9waJtrFr.png

1.1.2 Queue 消息队列

FIFO先进先出

1.1.3使用场景

1.1.3.1 异步消息

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/czyVZTAcuBVZ.png

1.1.3.2 系统间解耦

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/TIh55N25MD3u.png

1.1.3.3 削峰填谷

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/nSJb2yBMeTbr.png

1.2 Kafka

1.2.1 简介

http://kafka.apache.org

Kafka® is used for building real-time data pipelines and streaming apps. It is horizontally scalable, fault-tolerant, wicked fast, and runs in production in thousands of companies.

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/rgsE@HyIvvPf.png

1.2.2 kafka结构

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/YuCYyTPTHnkT.png

1.2.3 Kafka组件说明

1.2.3.1 Broker

每个kafka server成为一个Broker,多个Broker组成kafka cluster
https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/Yd@bjcE0eXLt.png
一个机器上可以部署一个或者多个Broker,这多个Broker连接到相同的ZK就组成了Kafka集群。

1.2.3.2 Topic

Kafka是一个发布订阅消息系统,它的逻辑如下

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/XS8K2jaDsJHI.png

Topic就是消息类名,一个Topic中通常放置一类消息。每个Topic都有一个或者多个订阅者,也就是消费者Consumer。

Producer将消息推送到Topic,由订阅该Topic的Consumer从Topic中拉取消息。

1.2.3.3 Topic与Broker

一个Broker上可以创建一个或者多个Topic。同一个Topic可以在同一集群下的多个Broker。

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/YOsTegKrE0Fv.png

1.2.3.4 Partion log

kafka会为每个topic维护了多个分区(partition),每个分区会映射到一个逻辑的日志(log)文件

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/ob8fA6sqvmO5.png

每当一个message被发布到一个topic上的一个partition,broker应该会将message追加到这个逻辑log的租后一个segment上。这些segments会flush到磁盘上。Flush时可以按照时间进行,也可以按照message数来执行。

每个partition都是一个有序的、不可变的结构化的提交日志记录的序列。在每个partition中每一个日志记录都会被分配一个序号——通常称为offset,offset在partiton内是唯一的。论点逻辑文件会被化为多个文件segment(每个segment的大小一样的)

Broker集群将会保留所有已发布的message records,不管这些消息是否已被消费。保留时间依赖于一个可配的保留周期。例如:如果设置了保留策略是2day,那么每一条消息发布两天内是被保留的,在这个2day的保留时间内,消息是可以被消费的,过期后不再保留。

1.2.3.5 Partiton distribution

日志分区是分布式的存在于一个kafka集群的多个Broker。每个partiton会被复制多份存在于不同的Broker上。这样做是为了容灾。具体会复制几份,会复制到那些broker上,都是可以配置的。经过相关复制策略后,每个topic在每个broker上回驻留一到多个partiton。

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/rGdzY*V!DJ*V.png

对于同一个partiton,它所在任何一个broker,都有能扮演两种角色:leader、follower

每个partiton的Leader用于处理到该partiton的读写请求。

每个partiton的followers是用于异步的从它的leader中复制数据。

Kafka会动态维护一个与Leader保持一致的同步副本(in-sync replicas (ISR))集合,并且会将最新的同步副本(ISR )集合持久化到zookeeper。如果leader出现问题了,就会从该partition的followers中选举一个作为新的leader。

1.2.4 Kafka 角色

1.2.4.1 Producer

Producer作为消息的生产者,在生产消息后需要将消息投送到指定的目的地(某个topic的某个partition)。Producer可以根据指定选择partiton的算法或者是随机方式来选择发布消息到哪个partiton

1.2.4.2 Consumer

在Kafka中,同样有consumer group的概念,它是逻辑上将一些consumer分组。因为每个kafka consumer是一个进程。所以一个consumer group中的consumers将可能是由分布在不同机器上的不同的进程组成的。Topic中的每一条消息可以被多个consumer group消费,然而每个consumer group内只能有一个consumer来消费该消息。所以,如果想要一条消息被多个consumer消费,那么这些consumer就必须是在不同的consumer group中。所以也可以理解为consumer group才是topic在逻辑上的订阅者。

​ 每个consumer可以订阅多个topic。

​ 每个consumer会保留它读取到某个partition的offset。而consumer 是通过zookeeper来保留offset的

二、kafka安装

2.1 Kafka 基础环境

  • 安装JDK,配置JAVA_HOME环境变量
  • 安装Zookeeper集群|单机|伪集群 ,并且正常启动
  • 必须配置主机名和IP的映射关系(很重要)
  • 时钟需要同步|防火墙关闭

2.2 安装启动

集群模式

[root@HadoopNode01 ~]# mkdir /home/kafka
[root@HadoopNode01 ~]# tar -zxvf kafka_2.11-0.11.0.0.tgz -C /home/kafka/
[root@HadoopNode01 ~]# vi /home/kafka/kafka_2.11-0.11.0.0/config/server.properties

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/Aq^U2ex8cfKM.png

[root@HadoopNode01 ~]# cd /home/kafka/kafka_2.11-0.11.0.0/
[root@HadoopNode01 kafka_2.11-0.11.0.0]# ./bin/kafka-server-start.sh -daemon config/server.properties 

版本kafka_2.11-0.11.0.0 其中-以前2.11表示Scala编译版本,后面0.11.0.0表示kafka版本例如:

#创建topic
# 单节点下 可用的Broker 只有一个 所以副本数量必须是1个
# 副本数量受到了Broker数量的限制
[root@CentOSA kafka_2.11-0.11.0.0]# ./bin/kafka-topics.sh --zookeeper ZK01:2181,ZK02:2181,ZK03:2181 --create --topic topic01 --partitions 3 --replication-factor 3
//启动消费者
[root@CentOSA kafka_2.11-0.11.0.0]# ./bin/kafka-console-consumer.sh --bootstrap-server HadoopNode01:9092,HadoopNode02:9092,HadoopNode03:9092 --topic topic01

//启动生产者
[root@CentOSB kafka_2.11-0.11.0.0]# ./bin/kafka-console-producer.sh --broker-list HadoopNode01:9092,HadoopNode02:9092,HadoopNode03:9092 --topic topic01
>
#从开始消费
./bin/kafka-console-consumer.sh --bootstrap-server HadoopNode01:9092,HadoopNode02:9092,HadoopNode03:9092 --topic topic01 --from-beginning

2.3 关闭

关闭 kafka服务
[root@CentOSA kafka_2.11-0.11.0.0]# vi bin/kafka-server-stop.sh 

PIDS=$(jps | grep Kafka |  awk '{print $1}')
if [ -z "$PIDS" ]; then
  echo "No kafka server to stop"
  exit 1
else
  kill -s TERM $PIDS
fi

三、Topic管理

3.1 添加Topic

[root@CentOSA kafka_2.11-0.11.0.0]# ./bin/kafka-topics.sh --zookeeper  ZK01:2181,ZK02:2181,ZK03:2181 --create --topic topic01 --partitions 3 --replication-factor 3

3.2 查看Topic详情

[root@HadoopNode02 kafka_2.11-0.11.0.0]# ./bin/kafka-topics.sh --zookeeper  ZK01:2181,ZK02:2181,ZK03:2181 --describe --topic topic01
Topic:topic01   PartitionCount:3        ReplicationFactor:3     Configs:
        Topic: topic01  Partition: 0    Leader: 2       Replicas: 2,1,0 Isr: 2,1,0
        Topic: topic01  Partition: 1    Leader: 0       Replicas: 0,2,1 Isr: 0,2,1
        Topic: topic01  Partition: 2    Leader: 1       Replicas: 1,0,2 Isr: 1,0,2

3.3 删除Topic信息

[root@CentOSA kafka_2.11-0.11.0.0]# ./bin/kafka-topics.sh  --zookeeper  ZK01:2181,ZK02:2181,ZK03:2181 --delete --topic topic01

3.4 修改分区信息

[root@CentOSA kafka_2.11-0.11.0.0]# ./bin/kafka-topics.sh --zookeeper ZK01:2181,ZK02:2181,ZK03:2181 --alter --topic topic01 --partitions 4

3.5 显示所有Topic

[root@HadoopNode02 kafka_2.11-0.11.0.0]# ./bin/kafka-topics.sh --zookeeper ZK01:2181,ZK02:2181,ZK03:2181  --list

四、Tpoic和日志

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/96QXx626ha74.png
Topic以日志分区形式存储,分区中每一则Record都有个offset编号用于标示record的顺序.所有存储在kafka中record是允许用户重复消费的kafka通过log.retention.hours控制Record存活时间.

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/PseJH7qBnCLS.png

kafka服务端只负责存储topic日志数据,kafka消费端独自维护一套分区信息和offset偏移量,一旦消费完成后消费端会自动提交消费分区的offset信息.下次在开始消费的时候只需要从上一次offset开始即可

删除一则已经发布的消息(很少)

[root@CentOSA kafka_2.11-0.11.0.0]# ./bin/kafka-delete-records.sh --bootstrap-server HadoopNode01:9092,HadoopNode02:9092,HadoopNode03:9092 --offset-json-file /root/deleterecord.json 
-----------------------------
{
   "partitions":                        
 [
	{
   "topic": "topic01", "partition": 1,"offset": 3}
 ]                      
} 

删除topic01中分区1 的offset 2以前的所有的数据

五、消费者

https://gitee.com/PengFei-io/pic_bed/raw/master/20200516/GlOqlHf6@@Rd.png

组内均分分区组间广播

六、JavaAPI

6.1 依赖

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>0.11.0.0</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.5</version>
</dependency>

6.2 删除Topic

 @Test
    public void del() {
   
        Properties props = new Properties();

        props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "HadoopNode01:9092,HadoopNode02:9092,HadoopNode03:9092");
        //KafkaAdminClient创建AdminClient对象
        AdminClient adminClient = KafkaAdminClient.create(props);

        Collection<String> topics = Arrays.asList("topic01");
        adminClient.deleteTopics(topics);

        adminClient.close();
    }

6.3 创建Topic

 @Test
    public void create() {
   

        Properties props = new Properties();
        props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, "HadoopNode01:9092,HadoopNode02:9092,HadoopNode03:9092");
        AdminClient adminClient = KafkaAdminClient.create(props);

        Collection<NewTopic> topics = Arrays.asList(
                new NewTopic("topic01", 3, (short) 3));
        adminClient.createTopics(topics);

        adminClient.close();
    }

6.4 发布一则消息

@Test
    public void publish() {
   
        Properties props = new Properties();
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "HadoopNode01:9092,HadoopNode02:9092,HadoopNode03:9092");
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
        props.put(ProducerConfig.PARTITIONER_CLASS_CONFIG, DefaultPartitioner.class);
        KafkaProducer<String, String> pd = new KafkaProducer<String, String>(props);

        //封装record
        for (int i = 0; i < 10; i++) {
   
            ProducerRecord<String, String> record
                    = new ProducerRecord<String, String>("topic01", "00" + i + "0", "user0100 true 15000");
            //发送消息
            pd.send(record);
        }
        pd.flush();
        pd.close();
    }

6.5 订阅消息

 @Test
    public void subcribe() {
   


        Properties props = new Properties();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "HadoopNode01:9092,HadoopNode02:9092,HadoopNode03:9092");
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "g1");

        System.out.println<
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值