kafka的入门学习

本文详细介绍了Kafka的基础知识,包括消息队列的概念、分类及其使用场景,重点讲解了Kafka的特点、设计目标及核心概念。进一步,文章阐述了Kafka的分布式安装步骤、Topic的操作以及Kafka的API使用,包括生产者和消费者的API操作,以及记录进入分区的策略。此外,还介绍了Kafka与Flume的整合案例。最后,文章深入探讨了Kafka的架构,包括其基本架构、分区策略以及Controller的选举过程,并分析了Kafka的高性能原因和影响因子。
摘要由CSDN通过智能技术生成

今日大纲

  • Kafka简介
  • Kafka分布式集群安装
  • Kafka-topic操作
  • Kafka-api
  • Kafka和Flume整合案例
  • Kafka架构之道
  • Kafka Leader Election
  • Kafka高性能之道

1. Kafka简介

1.1. 消息队列

1.1.1. 为甚要有消息队列

1.1.2. 消息队列

  • 消息 Message
    网络中的两台计算机或者两个通讯设备之间传递的数据。例如说:文本、音乐、视频等内容。
  • 队列 Queue
    一种特殊的线性表(数据元素首尾相接),特殊之处在于只允许在首部删除元素和在尾部追加元素。入队、出队。
  • 消息队列 MQ
    消息+队列,保存消息的队列。消息的传输过程中的容器;主要提供生产、消费接口供外部调用做数据的存储和获取。

1.1.3. 消息队列的分类

​ MQ主要分为两类:点对点(p2p)、发布订阅(Pub/Sub)

  • Peer-to-Peer
    一般基于Pull或者Polling接收数据
    发送到队列中的消息被一个而且仅仅一个接收者所接受,即使有多个接收者在同一个队列中侦听同一消息
    即支持异步“即发即收”的消息传递方式,也支持同步请求/应答传送方式

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AC5OkIcq-1584667570107)(E:/%E5%A4%A7%E6%95%B0%E6%8D%AE/spark/kafka1/%E6%96%87%E6%A1%A3/assets/1568684012083.png)]

  • 发布订阅
    发布到同一个主题的消息,可被多个订阅者所接收
    发布/订阅即可基于Push消费数据,也可基于Pull或者Polling消费数据
    解耦能力比P2P模型更强

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rba5lfGV-1584667570117)(E:/%E5%A4%A7%E6%95%B0%E6%8D%AE/spark/kafka1/%E6%96%87%E6%A1%A3/assets/1568684181173.png)]

1.1.4. p2p和发布订阅MQ的比较

  • 共同点:
    消息生产者生产消息发送到queue中,然后消息消费者从queue中读取并且消费消息。
  • 不同点:
    p2p模型包括:消息队列(Queue)、发送者(Sender)、接收者(Receiver)
    一个生产者生产的消息只有一个消费者(Consumer)(即一旦被消费,消息就不在消息队列中)。比如说打电话。
    pub/Sub包含:消息队列(Queue)、主题(Topic)、发布者(Publisher)、订阅者(Subscriber)
    每个消息可以有多个消费者,彼此互不影响。比如我发布一个微博:关注我的人都能够看到。

1.1.5. 消息系统的使用场景

  • 解耦 各系统之间通过消息系统这个统一的接口交换数据,无须了解彼此的存在
  • 冗余 部分消息系统具有消息持久化能力,可规避消息处理前丢失的风险
  • 扩展 消息系统是统一的数据接口,各系统可独立扩展
  • 峰值处理能力 消息系统可顶住峰值流量,业务系统可根据处理能力从消息系统中获取并处理对应量的请求
  • 可恢复性 系统中部分键失效并不会影响整个系统,它恢复会仍然可从消息系统中获取并处理数据
  • 异步通信 在不需要立即处理请求的场景下,可以将请求放入消息系统,合适的时候再处理

1.1.6. 常见的消息系统

  • RabbitMQ Erlang编写,支持多协议AMQP,XMPP,SMTP,STOMP。支持负载均衡、数据持久化。同时支持Peer-to-Peer和发布/订阅模式。
  • Redis 基于Key-Value对的NoSQL数据库,同时支持MQ功能,可做轻量级队列服务使用。就入队操作而言,Redis对短消息(小于10kb)的性能比RabbitMQ好,长消息性能比RabbitMQ差。
  • ZeroMQ 轻量级,不需要单独的消息服务器或中间件,应用程序本身扮演该角色,Peer-to-Peer。它实质上是一个库,需要开发人员自己组合多种技术,使用复杂度高。
  • ActiveMQ JMS实现,Peer-to-Peer,支持持久化、XA(分布式)事务
  • Kafka/Jafka 高性能跨语言的分布式发布/订阅消息系统,数据持久化,全分布式,同时支持在线和离线处理
  • MetaQ/RocketMQ 纯Java实现,发布/订阅消息系统,支持本地事务和XA分布式事务

1.2. Kafka简介

1.2.1. 简介

Kafka是分布式的发布—订阅消息系统。它最初由LinkedIn(领英)公司发布,使用Scala语言编写,与2010年12月份开源,成为Apache的顶级项目。Kafka是一个高吞吐量的、持久性的、分布式发布订阅消息系统。它主要用于处理活跃live的数据(登录、浏览、点击、分享、喜欢等用户行为产生的数据)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0GmDrs18-1584667570120)(assets/kafka-apis.png)]

三大特点:

  • 高吞吐量
    可以满足每秒百万级别消息的生产和消费——生产消费。
  • 持久性
    有一套完善的消息存储机制,确保数据的高效安全的持久化——中间存储。
  • 分布式
    基于分布式的扩展和容错机制;Kafka的数据都会复制到几台服务器上。当某一台故障失效时,生产者和消费者转而使用其它的机器——整体
  • 健壮性。

1.2.2. 设计目标

  • 高吞吐率 在廉价的商用机器上单机可支持每秒100万条消息的读写
  • 消息持久化 所有消息均被持久化到磁盘,无消息丢失,支持消息重放
  • 完全分布式 Producer,Broker,Consumer均支持水平扩展
  • 同时适应在线流处理和离线批处理

1.2.3. kafka核心的概念

一个MQ需要哪些部分?生产、消费、消息类别、存储等等。
对于kafka而言,kafka服务就像是一个大的水池。不断的生产、存储、消费着各种类别的消息。那么kafka由何组成呢?

Kafka服务:

  • Topic:主题,Kafka处理的消息的不同分类。
  • Broker:消息服务器代理,Kafka集群中的一个kafka服务节点称为一个broker,主要存储消息数据。存在硬盘中。每个topic都是有分区的。
  • Partition:Topic物理上的分组,一个topic在broker中被分为1个或者多个partition,分区在创建topic的时候指定。
  • Message:消息,是通信的基本单位,每个消息都属于一个partition

Kafka服务相关

  • Producer:消息和数据的生产者,向Kafka的一个topic发布消息。
  • Consumer:消息和数据的消费者,定于topic并处理其发布的消息。
  • Zookeeper:协调kafka的正常运行。

2. kafka的分布式安装

2.1. 版本下载

安装包:http://archive.apache.org/dist/kafka/1.1.1/kafka_2.12-1.1.1.tgz

源码包:http://archive.apache.org/dist/kafka/1.1.1/kafka-1.1.1-src.tgz

2.2. 安装过程

  1. 解压

​ [bigdata@bigdata01 app]$ tar -zxvf ~/soft/kafka_2.11-1.1.1.tgz -C app/

  1. 重命名

​ [bigdata@bigdata01 app]$ mv kafka_2.11-1.1.1/ kafka

  1. 添加环境变量

​ [bigdata@bigdata01 kafka]$ vim ~/.bash_profile

export KAFKA_HOME=/home/bigdata/app/kafka
export PATH=$PATH:$KAFKA_HOME/bin

​ [bigdata@bigdata01 kafka]$ source ~/.bash_profile

  1. 配置

​ 修改$KAFKA_HOME/config/server.properties

broker.id=11 ## 当前kafka实例的id,必须为整数,一个集群中不可重复
log.dirs=/home/bigdata/data/kafka ## 生产到kafka中的数据存储的目录,目录需要手动创建
zookeeper.connect=bigdata01:2181,bigdata02:2181,bigdata03:2181/kafka ## kafka数据在zk中的存储目录
  1. 同步到其它机器
scp -r kafka/ hadoop@hadoop02:/home/hadoop/app/
scp -r kafka/ bigdata@bigdata03:/home/hadoop/app/
  1. 修改配置文件中的broker.id
broker.id=12 ##bigdata02
broker.id=13 ##bigdata03
  1. 创建数据目录
mkdir -p /home/bigdata/data/kafka
  1. 启动kafka服务
~/app/kafka/bin/kafka-server-start.sh -daemon ~/app/kafka/config/server.properties 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3rxE49Jf-1584667570122)(assets/1564974407794.png)]

  1. kafka服务测试

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-enHaYrvT-1584667570123)(E:/%E5%A4%A7%E6%95%B0%E6%8D%AE/spark/kafka1/%E6%96%87%E6%A1%A3/assets/1564974489574.png)]

    ​ 只要我们配置的kafka的服务都在zookeeper中进行了注册,便说明kafka已经安装启动成功

2.3. kafka在zookeeper中的目录说明

/kafka
    /cluster		
    	/id  {"version":"1","id":"Pks8sWZUT6GBJHqyVGQ5OA"}  ---》代表的是一个kafka集群包含集群的版本,和集群的id
    /controller  {"version":1,"brokerid":11,"timestamp":"1564976668049"} -->controller是kafka中非常重要的一个角色,意为控制器,控制partition的leader选举,topic的crud操作。brokerid意为由其id对应的broker承担controller的角色。
    /controller_epoch 2 代表的是controller的纪元,换句话说是代表controller的更迭,每当controller的brokerid更换一次,controller_epoch就+1.
    /brokers
       /ids	 [11, 12, 13] --->存放当前kafka的broker实例列表
       /topics	[hadoop, __consumer_offsets] ---->当前kafka中的topic列表
       /seqid	系统的序列id
    /consumers --->老版本用于存储kafka消费者的信息,主要保存对应的offset,新版本中基本不用,此时用户的消费信息,保存在一个系统的topic中:__consumer_offsets
    /config	--->存放配置信息

3. Kafka的基本操作

3.1. kafka的topic的操作

​ topic是kafka非常重要的核心概念,是用来存储各种类型的数据的,所以最基本的就需要学会如何在kafka中创建、修改、删除的topic,以及如何向topic生产消费数据。

​ 关于topic的操作脚本:kafka-topics.sh

  1. 创建topic
[bigdata@bigdata01 kafka]$ bin/kafka-topics.sh --create \
--topic hadoop \	## 指定要创建的topic的名称
--zookeeper 
hadoop01:2181,hadoop02:2181,hadoop03:2181/kafka \ ##指定kafka关联的zk地址
--partitions 3 \		##指定该topic的分区个数
--replication-factor 3	##指定副本因子

 bin/kafka-topics.sh --create --topic hadoop --zookeeper hadoop01:2181/kafka --partitions 3 --replication-factor 3

注意:指定副本因子的时候,不能大于broker实例个数,否则报错:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SWRQALVN-1584667570125)(assets/1564976012893.png)]

zookeeper目录变化

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pgu7sQFi-1584667570127)(assets/1564976107745.png)]

kafka数据目录的变化

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BCUkzhgu-1584667570130)(assets/1564976163903.png)]

  1. 查看topic的列表
[bigdata@bigdata01 kafka]$ bin/kafka-topics.sh --list  \
--zookeeper bigdata01:2181,bigdata02:2181,bigdata03:2181/kafka
hadoop
  1. 查看每一个topic的信息
[bigdata@bigdata01 kafka]$ bin/kafka-topics.sh --describe --topic hadoop \
--zookeeper bigdata01:2181,bigdata02:2181,bigdata03:2181/kafka

Topic:hadoop	PartitionCount:3	ReplicationFactor:3		Configs:
Topic: hadoop	Partition: 0	Leader: 12	Replicas: 12,13,11	Isr: 12,13,11
Topic: hadoop	Partition: 1	Leader: 13	Replicas: 13,11,12	Isr: 13,11,12
Topic: hadoop	Partition: 2	Leader: 11	Replicas: 11,12,13	Isr: 11,12,13

Partition:	当前topic对应的分区编号
Replicas :  副本因子,当前kafka对应的partition所在的broker实例的broker.id的列表
Leader	 :  该partition的所有副本中的leader领导者,处理所有kafka该partition读写请求
ISR		 :  该partition的存活的副本对应的broker实例的broker.id的列表
  1. 修改一个topic
[bigdata@bigdata01 kafka]$ bin/kafka-topics.sh --alter --topic hadoop --partitions 4 --zookeeper bigdata01:2181/kafka
WARNING: If partitions are increased for a topic that has a key, the partition logic or ordering of the messages will be affected
Adding partitions succeeded!

但是注意:partition个数,只能增加,不能减少:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ptthEQf6-1584667570132)(assets/1564976954334.png)]

  1. 删除一个topic

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ltfsUVww-1584667570133)(assets/1564977032114.png)]

  1. 生产数据
[bigdata@bigdata01 kafka]$ bin/kafka-console-producer.sh \
--topic hadoop \	-->指定数据被生产的topic
--broker-list bigdata01:9092,bigdata02:9092,bigdata03:9092 --->指定kafka的broker列表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sWE5hAU8-1584667570137)(assets/1564977283073.png)]

  1. 消费数据
[bigdata@bigdata03 kafka]$ bin/kafka-console-consumer.sh \
--topic hadoop \
--bootstrap-server bigdata01:9092,bigdata02:9092,bigdata03:9092

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L8weFDuH-1584667570137)(assets/1564977398804.png)]

没数据,原因在于消费者后于生产者启动,在消费者启动之前生产者消费的数据变不能直接获取。

如果想要获取消费者启动之前生产者生产的数据,可以添加一个参数–from-beginning。

如图所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mrG4eMdn-1584667570138)(assets/1564977543576.png)]

3.2. Kafka的数据消费的总结

​ kafka消费者在消费数据的时候,都是分组别的。不同组的消费不受影响,相同组内的消费,需要注意,如果partition有3个,消费者有3个,那么便是每一个消费者消费其中一个partition对应的数据;如果有2个消费者,此时一个消费者消费其中一个partition数据,另一个消费者消费2个partition的数据。如果有超过3个的消费者,同一时间只能最多有3个消费者能消费得到数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XO49m37e-1584667570139)(assets/consumer-groups.png)]

 bin/kafka-console-consumer.sh --topic spark \
 --bootstrap-server bigdata01:9092,bigdata02:9092,bigdata03:9092 \
 --group haha \		---》消费者对应的消费者组
 --offset earliest \		--->从什么位置(消息的偏移量)开始消费
 --partition 2		---->消费哪一个分区中的数据	

offset:是kafka的topic中的partition中的每一条消息的标识,如何区分该条消息在kafka对应的partition的位置,就是用该偏移量。offset的数据类型是Long,8个字节长度。offset在分区内是有序的,分区间是不一定有序。如果想要kafka中的数据全局有序,就只能让partition个数为1。

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1Hi3lmql-1584667570140)(assets/log_anatomy.png)]

​ 在组内,kafka的topic的partition个数,代表了kafka的topic的并行度,同一时间最多可以有多个线程来消费topic的数据,所以如果要想提高kafka的topic的消费能力,应该增大partition的个数。

3.3. kafka的编程的api

3.3.1. 创建kafka的项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MoRjIpnD-1584667570142)(assets/1564987565272.png)]

指定maven坐标

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MvmWIFw3-1584667570148)(assets/1564987594037.png)]

指定存放目录

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eRnbq0yq-1584667570149)(assets/1564987640236.png)]

导入maven依赖

  <!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-clients -->
<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>1.1.1</version>
</dependency>
<!-- 下面的依赖,包含了上面的kafka-clients,所以只需要引入下面即可 -->
<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka_2.11</artifactId>
    <version>1.1.1</version>
</dependency>

3.3.2. kafka生产者的api操作

​ 入口类:Producer

  • 入门案例
public class MyKafkaProducer {
   
    public static void main(String[] args) throws IOException {
   
        /*
            K: --->代表的是向topic中发送的每一条消息的key的类型,key可以为null
            V: --->代表的是向topic中发送的每一条消息的value的类型
         */
        Properties properties = new Properties();
//        properties.put("bootstrap.servers", "bigdata01:9092,bigdata02:9092,bigdata03:9092");
        properties.load(MyKafkaProducer.class.getClassLoader().getResourceAsStream("producer.properties"));
        Producer<Integer, String> producer = new KafkaProducer<Integer, String>(properties);

        //发送数据
        ProducerRecord<Integer, String> record = new ProducerRecord("spark", "11111");
        producer.send(record);
        producer.close();
    }
}

配置:

bootstrap.servers=bigdata01:9092,bigdata02:9092,bigdata03:9092
key.serializer=org.apache.kafka.common.serialization.IntegerSerializer
value.serializer=org.apache.kafka.common.serialization.StringSerializer
  • 创建producer时需要指定的配置信息
bootstrap.servers=bigdata01:9092,bigdata02:9092,bigdata03:9092 ## kafka的服务器
key.serializer=org.apache.kafka.common.serialization.IntegerSerializer ##Key的序列化器
value.serializer=org.apache.kafka.common.serialization.StringSerializer ##value的序列化器
acks=[0|-1|1|all] ##消息确认机制
	0:	不做确认,直管发送消息即可
	-1|all: 不仅leader需要将数据写入本地磁盘,并确认,还需要同步的等待其它followers进行确认
	1:只需要leader进行消息确认即可,后期follower可以从leader进行同步
batch.size=1024 #每个分区内的用户缓存未发送record记录的空间大小
## 如果缓存区中的数据,没有沾满,也就是任然有未用的空间,那么也会将请求发送出去,为了较少请求次数,我们可以配置linger.ms大于0,
linger.ms=10 ## 不管缓冲区是否被占满,延迟10ms发送request
buffer.memory=10240 #控制的是一个producer中的所有的缓存空间
retries=0 #发送消息失败之后的重试次数
  • 修改配置查看生产数据情况

配置文件

bootstrap.servers=bigdata01:9092,bigdata02:9092,bigdata03:9092

# specify the compression codec for all data generated: none, gzip, snappy, lz4
compression.type=none

# name of the partitioner class for partitioning events; default partition spreads data randomly
# 输入进入分区的方式
#partitioner.class=

# the maximum amount of time the client will wait for the response of a request
# 请求超时时间
#request.timeout.ms=

# how long `KafkaProducer.send` and `KafkaProducer.partitionsFor` will block for
# 使用send方法最大消息阻塞时间
#max.block.ms=

# the producer will wait for up to the given delay to allow other records to be sent so that the sends can be batched together
linger.ms=5000

# the maximum size of a request in bytes
## 最大的请求大小
#max.request.size=

# the default batch size in bytes when batching multiple records sent to a partition
batch.size=1024

buffer.memory=10240
key.serializer=org.apache.kafka.common.serialization.IntegerSerializer
value.serializer=org.apache.kafka.common.serialization.StringSerializer

代码

public class MyKafkaProducer {
   
    public static void main(String[] args) throws Exception {
   
        /*
            K: --->代表的是向topic中发送的每一条消息的key的类型,key可以为null
            V: --->代表的是向topic中发送的每一条消息的value的类型
         */
        Properties properties = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值