Kafka

1、简介

1.1、消息队列

消息队列一般用于消息的临时存取,遵循先入先出原则。常用的消息中间件:Kafka(大数据领域,性能高)、ActivateMQ、RabbitMQ、RocketMQ等。

应用场景:

  • 异步处理
  • 系统解耦
  • 流量削峰
  • 日志处理

生产者消费者模型
在这里插入图片描述
消息队列模式

  • 点对点模式
    -在这里插入图片描述每个消息只有一个接收者,发送者和接收者没有依赖性,接收者在成功接收消息后需向队列应答成功。

  • 发布/订阅模式
    在这里插入图片描述
    每个消息有多个订阅者,发布者和订阅者在时间上有依赖性。某主题的订阅者,必须先创建订阅者才能消费消息。同时,订阅者需要提前订阅该角色主题并保持在线。

1.2、Kafka

Kafka是一个分布式流平台。分布式流平台应包括:发布订阅数据流、冗余持久化数据流、处理数据流。各个消息队列对比。
在这里插入图片描述
工具:

  1. kafka可视化工具:Offset Explorer 2.0或Kafka Tool
  2. 监控Kafka集群工具:Kafka-eagle

2、下载安装

下载地址:https://kafka.apache.org/downloads

所有节点配置环境变量

vim /etc/profile

添加配置

export KAFKA_HOME=/export/soft/kafka_2.13-2.5.0
export PATH=$PATH:${KAFKA_HOME}

最后

source /etc/profile

版本根据Zookeeper的版本进行匹配,在kafka的lib目录有Zookeeper的jar包,通过jar查看对应的Zookeeper版本。

解压后修改config文件夹下的配置文件server.properties

broker.id=0
log.dirs=/export/soft/kafka_2.13-2.5.0/data

用scp -r命令分发文件夹到其他节点

scp -r  kafka_2.13-2.5.0/ hadoop101:$PWD
scp -r  kafka_2.13-2.5.0/ hadoop102:$PWD

分别将broker.id改为1和2

后台启动命令(所有节点)

nohup  /export/soft/kafka_2.13-2.5.0/bin/kafka-server-start.sh /export/soft/kafka_2.13-2.5.0/config/server.properties &

停止命令

/export/soft/kafka_2.13-2.5.0/bin/kafka-server-stop.sh /export/soft/kafka_2.13-2.5.0/config/server.properties &

3、生产、消费消息测试

创建topic test

/export/soft/kafka_2.13-2.5.0/bin/kafka-topics.sh --create --bootstrap-server hadoop101:9092 --topic test

查看topic

/export/soft/kafka_2.13-2.5.0/bin/kafka-topics.sh  --bootstrap-server hadoop101:9092 --list

创建生产者

/export/soft/kafka_2.13-2.5.0/bin/kafka-console-producer.sh --broker-list hadoop101:9092 --topic test

创建消费者

/export/soft/kafka_2.13-2.5.0/bin/kafka-console-consumer.sh --bootstrap-server  hadoop101:9092 --topic test --from-beginning

可视化工具

Kafka tool或者Offset Explorer 2.0,两者差不多,可通过可视化界面查看Kafka集群信息和消息队列中的数据
在这里插入图片描述

4、Java操作Kafka

创建生产者

    @Test
    public void testKafkaProducer(){
        Properties properties = new Properties();
        properties.put("bootstrap.servers","192.168.132.100:9092");
        properties.put("ack","all");
        properties.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
        properties.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");

        KafkaProducer<String, String> producer = new KafkaProducer<>(properties);
        ProducerRecord<String, String> record = new ProducerRecord<>("test", "testKafka2", "334455");
        producer.send(record,new Callback() {
            @Override
            public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                if (e==null) {
                    System.out.println(recordMetadata.timestamp());
                }else {
                    e.printStackTrace();
                    System.out.println("发送失败");
                }
            }
        });
        producer.close();
    }

创建消费者

 @Test
    public void testKafkaConsumer(){
        Properties properties = new Properties();
        properties.put("bootstrap.servers","192.168.132.100:9092");
        properties.put("group.id","test");
        //自动提交offset
        properties.put("enable.auto.commit","true");
        //自动提交offset的时间间隔
        properties.put("auto.commit.interval.ms","1000");
      properties.put("key.deserializer","org.apache.kafka.common.serialization.StringDeserializer");
        properties.put("value.deserializer","org.apache.kafka.common.serialization.StringDeserializer");

        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(properties);
        consumer.subscribe(Arrays.asList("test"));
        while (true){
            ConsumerRecords<String, String> records = consumer.poll(Duration.ofSeconds(5));
            for (ConsumerRecord<String, String> record : records) {
                System.out.println(record);
            }

        }

    }

5、架构组成

5.1、基础架构

在这里插入图片描述

5.2、broker

一个Kafka集群通常由多个broker组成,方便实现负载均衡和冗余。broker 是无状态的,由ZK管理集群状态,每个broker每秒可处理十万次读写。

5.3、消费者组consumer group

在这里插入图片描述
consumer group是kafka提供的可扩展且具有容错性的消费者机制。一个消费者组可包含多个消费者,组内消费者一起消费主题的所有分区数据。一个topic如果只有一个分区,那么这个分区只能被某个消费者消费。有多少分区就可以被同一组的多少个消费者消费。消费组中一个消费者可以消费多个分区,但一个分区不能被同一个消费组中的多个消费者消费。

5.4、分区partition

kafka的消息组织形式分为三级结构,topic->分区->消息

查看分区数

./kafka-topics.sh --zookeeper 127.0.0.1:2181 --describe --topic test

修改分区数

./kafka-topics.sh --zookeeper 127.0.0.1:2181 -alter --partitions 3 --topic test

可在config文件夹中修改server.properties中的num.partitions(默认分区数)和default.replication.factor(默认副本数)

可在可视化工具新建topic时设置分区数量和副本数量,分区会均匀分布在broker上达到负载均衡的效果。
在这里插入图片描述
分区架构
在这里插入图片描述
副本架构
在这里插入图片描述
一个主题对应多个分区,副本可以确保单个节点故障时,数据依然可用。

对比

HBaseKafka
Region Serverbroker
Regionpartition
tabletopic
5.5、topic

在这里插入图片描述
主题是一个逻辑的概念,是唯一的必须标识符,一般主题包含某一类信息,消息不能被更改。

5.6、偏移量offset

offset记录下一条要发送给消费者的序号。默认存在ZK中。每个分区有一个offset用来标记消费到哪一条了。

6、幂等性

在这里插入图片描述
当kafka不具备幂等性,在ACK返回失败时会重复存储数据。

通过引入producer id和sequence number防止消息重复存储。当seq没有增加的情况下,不会存储消息。
在这里插入图片描述

7、分区和副本

7.1、生产者分区策略
  1. 轮询分区策略:key为null使用,数据会乱序
  2. 随机分区策略:基本不用,数据会乱序
  3. 按key分区策略:对key取hash对分区数取余,可能数据倾斜,注意key值,数据一定程度上有序
  4. 自定义分区策略
7.2、消费者rebalance机制

触发条件:consumer个数变化、订阅的topic个数变化、订阅的分区数变化。

rebalance时所有同一组中的consumer停止,直到rebalance完成。尽量不要触发rebalance

7.2、消费者消费策略
  1. range范围分配策略(默认)

    确保每个消费者消费尽量均衡,n=分区数量/消费者数量,m=分区数量%消费者数量,前m个消费者消费n+1个,剩余消费者消费n个

  2. RoundRobin轮询策略

    按照字典顺序排序,通过轮询方式逐个将分区分配给每个消费者。

  3. stricky粘性分配策略

    在发生rebalance时,保留原消费者和分区的对应关系,将多出来的分区均匀分配给其他好用的consumer。

7.3、副本机制

当某个broker分区的数据丢失或故障,依然可保障数据可用。

ACK参数:当生产者生产消息时,写入到副本的要求严格程度。

​ ACK=0:不等broker确认直接发送下一条数据,性能最高,但可能数据丢失。

​ ACK=1:等leader副本确认后再发送下一条数据,性能中等,但可能数据丢失。(leader和follower是针对分区 而言的,只有leader能读写数据)

​ ACK=-1/all:等所有节点的副本都同步完再发送下一条数据,性能最差,数据不会丢。

8、Kafka原理

8.1、分区的leader和follower

每个topic都有多个分区和多个副本。每个分区有一个leader、0个或多个follower。在创建topic时,每个分区的leader会均匀分布在broker上。leader负责所有的读写操作,所有的follower拉取leader对应分区的数据并保存在日志数据文件中。在leader故障时,follower会被选举为leader。

分区的leader不一定和分区在同一个节点上,因为多个副本不一定选举谁为leader

8.2、AR、ISR、OSR

follower按照不同状态分为三类

  • 分区的所有副本称为AR(Assigned Replicas 已分配的副本)
  • 所有与leader副本保持一定程度同步的副本(含leader副本)组成ISR (In-SyncReplicas-在同步中的副本)
  • follower副本同步滞后过多的副本组成OSR(Out-Of-SyncReplicas)

AR=ISR+OSR

8.3、leader的选举

controller:在Kafka启动时,会在所有broker中选择一个controller,leader、follower是针对分区而言的,而 controller是针对broker而言的。

创建topic、添加分区、管理副本、leader选举等管理工作都由controller处理。controller相当于集群中的master。

controller选举:

  • 在Kafka集群启动时,每个broker都会去尝试注册成controller(ZK上的临时节点)
  • 只有一个成功,其他节点注册成该节点的监视器
  • 满足高可用,其他节点监视到controller崩溃,会重新注册为controller
  • 在这里插入图片描述
    controller选举leader:**(不通过ZK进行选举)

leader选举由controller决定,controller将leader的改变通过RPC方式进行通知,controller读取ISR,只要有一个副本好使,就选其中一个做leader,如果所有副本宕机后,新leader为-1。

leader负载均衡:在leader分配不均匀时,–partition可指定需要重新分配leader的partition编号

8.4、工作流程
1、数据写入流程

在这里插入图片描述
生产者先从zk找到leader,broker进程上的leader将消息顺序写入本地log中,follower从leader上拉取消息,写入本地log,并向leader发送ACK,leader接收到所有的ISR中Replica的ACK后,并向生产者返回ACK。

2、数据消费流程

两种消费流程:推(push)、拉(pull)。

offset自动提交即使该条数据未处理成功也会提交从而offset+1,原offset数据未被成功消费导致消息丢失。

当offset提交到ZK未成功,会导致重复消费问题。可将通过offset存到mysql利用事务机制防止重复消费。

拉模式:由消费者自己记录消费状态,每个消费者互相独立、顺序拉取每个分区消息。消费者可以按照任意的顺序消费信息。

推模式:消息队列记录所有消费的状态,某一条消息如果被标记为已消费,则消费者不能再次消费。

拉取数据流程:
在这里插入图片描述
每个消费者都可根据分配策略,获得要消费的分区。获取到消费者对应的offset,找到该分区的leader并拉取数据,消费者提交offset。

8.5、数据存储形式

在这里插入图片描述
一个topic由多个分区组成,一个分区由多个segment组成,一个segment由多个文件组成,segment由多个文件组成(数据文件log、稀疏索引index、时间索引timeindex)。

读取数据时,先根据全局的offset找到segment段,再将全局的offset转成段内的局部offset,根据局部offset从稀疏索引(index)找到数据位置,进行顺序读取。

数据定期清理,一次删除一个segment段的日志文件。

8.6、数据清理

日志删除是以segment段为单位进行定期清理的。

日志保留策略:1、基于时间(默认7天) 2、基于日志大小 3、基于日志起始偏移量

  • 24
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值