Kafka系列-2、kafka基础

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

大数据系列文章目录

kafka的中文网站

消息队列的基本介绍

什么是消息队列?

消息队列,英文名:Message Queue,经常缩写为MQ。从字面上来理解,消息队列是一种用来存储消息的队列。来看一下下面的代码
在这里插入图片描述
上述代码,创建了一个队列,先往队列中添加了一个消息,然后又从队列中取出了一个消息。这说明了队列是可以用来存取消息的。

总结: 消息队列指的就是将数据放置到一个队列中, 从队列一端进入, 然后从另一端流出的过程

消息队列的应用场景

消息队列在实际应用中包括如下四个场景:

1) 应用耦合:

多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败;

2) 异步处理:

多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间;

3) 限流削峰:

广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况;

4) 消息驱动的系统:

系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,消费者(可能有多个)负责对消息进行处理

下面详细介绍上述四个场景以及消息队列如何在上述四个场景中使用

异步处理

具体场景:用户为了使用某个应用,进行注册,系统需要发送注册邮件并验证短信。对这两个操作的处理方式有两种:串行及并行。

  1. 串行方式: 新注册信息生成后 , 先发送注册邮件, 再发送验证短信注意: 在这种方式下,需要最终发送验证短信后再返回给客户端
    在这里插入图片描述
  2. 并行处理:新注册信息写入后,由发短信和发邮件并行处理
    在这里插入图片描述
    注意: 在这种方式下,发短信和发邮件 需处理完成后再返回给客户端。

假设以上三个子系统处理的时间均为50ms,且不考虑网络延迟,则总的处理时间: 串行:50+50+50=150ms
并行:50+50 = 100ms
如果引入消息队列, 在来看整体的执行效率:
在这里插入图片描述
在写入消息队列后立即返回成功给客户端,则总的响应时间依赖于写入消息队列的时间,而写入消息队列的时间 本身是可以很快的,基本可以忽略不计,因此总的处理时间相比串行提高了2倍,相比并行提高了一倍;

应用耦合

具体场景:
用户使用QQ相册上传一张图片,人脸识别系统会对该图片进行人脸识别,一般的做法是,服务器接收到图片后,图片上传系统立即调用人脸识别系统,调用完成后再返回成功,如下图所示:如果引入消息队列, 在来看整体的执行效率
在这里插入图片描述
该方法有如下缺点:

  1. 人脸识别系统被调失败,导致图片上传失败;

  2. 延迟高,需要人脸识别系统处理完成后,再返回给客户端,即使用户并不需要立即知道结果;

  3. 图片上传系统与人脸识别系统之间互相调用,需要做耦合;
    若使用消息队列:
    在这里插入图片描述
    此时图片上传系统并不需要关心人脸识别系统是否对这些图片信息的处理、以及何时对这些图片信息进行处理。事实上,由于用户并不需要立即知道人脸识别结果,人脸识别系统可以选择不同的调度策略,按照闲时、忙时、正常时 间,对队列中的图片信息进行处理。

限流削峰
具体场景:
购物网站开展秒杀活动,一般由于瞬时访问量过大,服务器接收过大,会导致流量暴增,相关系统无法处理请求甚 至崩溃。而加入消息队列后,系统可以从消息队列中取数据,相当于消息队列做了一次缓冲。
在这里插入图片描述
该方法有如下优点:
请求先入消息队列,而不是由业务处理系统直接处理,做了一次缓冲,极大地减少了业务处理系统的压力;
队列长度可以做限制,事实上,秒杀时,后入队列的用户无法秒杀到商品,这些请求可以直接被抛弃,返回活动已结束或商品已售完信息;

消息驱动系统
具体场景:
用户新上传了一批照片, 人脸识别系统需要对这个用户的所有照片进行聚类,聚类完成后由对账系统重新生成用户的人脸索引(加快查询)。这三个子系统间由消息队列连接起来,前一个阶段的处理结果放入队列中,后一个阶段从队 列中获取消息继续处理。
在这里插入图片描述
该方法有如下优点:
避免了直接调用下一个系统导致当前系统失败;
每个子系统对于消息的处理方式可以更为灵活,可以选择收到消息时就处理,可以选择定时处理,也可以划分时间段按不同处理速度处理;

消息队列的两种模式

点对点模式
点对点模式下包括三个角色
消息队列
发送者 (生产者)
接收者(消费者)

在这里插入图片描述
消息发送者生产消息发送到queue中,然后消息接收者从queue中取出并且消费消息。消息被消费以后,queue中 不再有存储,所以消息接收者不可能消费到已经被消费的消息。

点对点模式特点:

每个消息只有一个接收者(Consumer)(即一旦被消费,消息就不再在消息队列中);

发送者和接收者间没有依赖性,发送者发送消息之后,不管有没有接收者在运行,都不会影响到发送者下次发送消息;

接收者在成功接收消息之后需向队列应答成功,以便消息队列删除当前接收的消息;

发布/订阅模式

发布/订阅模式下包括三个角色:
角色主题(Topic)
发布者(Publisher)
订阅者(Subscriber)

在这里插入图片描述
发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。

发布/订阅模式特点:

每个消息可以有多个订阅者;

发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息。

为了消费消息,订阅者需要提前订阅该角色主题,并保持在线运行;

常见的消息队列的产品

1) RabbitMQ
RabbitMQ 2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。
2) activeMQ
ActiveMQ是由Apache出品,ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现。它非常快速
,支持多种语言的客户端和协议,而且可以非常容易的嵌入到企业的应用环境中,并有许多高级功能,目前市场的活跃 度比较低, 在java领域正在被RabbitMQ替代
3) RocketMQ
RocketMQ出自 阿里公司的开源产品,用 Java 语言实现,在设计时参考了 Kafka,并做出了自己的一些改进,消息可靠性上比 Kafka 更好。RocketMQ在阿里集团被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理等
4) kafka
Apache Kafka是一个分布式消息发布订阅系统。它最初由LinkedIn公司基于独特的设计实现为一个分布式的提交日志系统( a distributed commit log),之后成为Apache项目的一部分。Kafka系统快速、可扩展并且可持久化。它的分区特性,可复制和可容错都是其不错的特性。

各种消息队列产品的对比图:
在这里插入图片描述

kafka的基本介绍

官网:http://kafka.apache.org/
kafka是最初由linkedin公司开发的,使用scala语言编写,kafka是一个分布式,分区的,多副本的,多订阅者的日 志系统(分布式MQ系统),可以用于搜索日志,监控日志,访问日志等
Kafka is a distributed,partitioned,replicated commit logservice。它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的完整实现。kafka对消息保存时根据Topic进行归类,发送消息者成为Producer,消息 接受者成为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。无论是kafka集群,还是producer和consumer都依赖于zookeeper来保证系统可用性集群保存一些meta信息

kakfa的特点:

可靠性: 分布式, 分区 , 复制 和容错等

可扩展性: kakfa消息传递系统轻松缩放, 无需停机

耐用性: kafka使用分布式提交日志, 这个意味着消息会尽可能快速的保存在磁盘上, 因此它是持久的

性能: kafka对于发布和订阅消息都具有高吞吐量, 即使存储了许多TB的消息, 他也爆出稳定的性能- kafka非常快: 保证零停机和零数据丢失

kafka的主要应用场景:

  1. 指标分析: kafka通常用于操作监控数据, 这设计聚合来自分布式应用程序和统计信息, 以产生操作的数据集中反馈

  2. 日志聚合解决方法: kafka可用于跨组织从多个服务器收集日志, 并使他们一标准的合适提供给多个服务器

  3. 流式处理: 流式的处理框架(spark, storm , flink) 从主题中读取数据, 对其进行处理, 并将处理后的结果数据写入新的主题, 供用户和应用程序使用, kafka的强耐久性在流处理的上下文中也非常的有用

apache kafka是一个分布式发布-订阅消息系统和一个强大的队列,可以处理大量的数据,并使能够将消息从一个端点传递到另一个端点,kafka适合离线和在线消息消费。kafka消息保留在磁盘上,并在集群内复制以防止数据丢失。 kafka构建在zookeeper同步服务之上。它与apache和spark非常好的集成,应用于实时流式数据分析。

版本说明:

我本次使用的Kafka版本为2.4.1,是2020年3月12日发布的版本。

可以注意到Kafka的版本号为:kafka_2.12-2.4.1,因为kafka主要是使用scala语言开发的,2.12为scala的版本号。http://kafka.apache.org/downloads可以查看到每个版本的发布时间。

kafka的架构说明

在这里插入图片描述
Kafka Cluster:由多个服务器组成。每个服务器单独的名字broker(掮客)。
kafka broker:kafka集群中包含的服务器Kafka Producer:消息生产者、发布消息到 kafka 集群的终端或服务。
Kafka consumer:消息消费者、负责消费数据。
Kafka Topic: 主题,一类消息的名称。存储数据时将一类数据存放在某个topci下,消费数据也是消费一类数据。订单系统:创建一个topic,叫做order。
用户系统:创建一个topic,叫做user。
商品系统:创建一个topic,叫做product。 注意:Kafka的元数据都是存放在zookeeper中。

kafka集群的搭建操作

kafka的环境搭建,后续专门写一篇文章。

kafka的相关shell命令操作

1、创建topic
创建一个topic(主题)。Kafka中所有的消息都是保存在主题中,要生产消息到Kafka,首先必须要有一个确定的主题。

# 创建名为test的主题
bin/kafka-topics.sh --create --bootstrap-server node1:9092 --topic test
# 查看目前Kafka中的主题
bin/kafka-topics.sh --list --bootstrap-server node1:9092

2、生产消息到kafka

使用Kafka内置的测试程序,生产一些消息到Kafka的test主题中。

bin/kafka-console-producer.sh --broker-list node1:9092 --topic test

3、从kafka中消费消息
使用下面的命令来消费 test 主题中的消息。

bin/kafka-console-consumer.sh --bootstrap-server node1:9092 --topic test

4、查看主題的命令
查看kafka当中存在的主题

bin/kafka-topics.sh --list --zookeeper node1:2181,node2:2181,node3:2181

5、运行describe的命令
运行describe查看topic的相关详细信息

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

在这里插入图片描述6、增加topic分区数
任意kafka服务器执行以下命令可以增加topic分区数

bin/kafka-topics.sh --zookeeper zkhost:port --alter --topic topicName --partitions 8

7、删除topic
目前删除topic在默认情况下只是打上一个删除的标记,在重新启动kafka后才删除。如果需要立即删除,则需要在server.properties中配置:
delete.topic.enable=true
然后执行以下命令进行删除topic

bin/kafka-topics.sh --zookeeper zkhost:port --delete --topic topicName

8、使用kafka Tools操作Kafka
安装Kafka Tools后启动Kafka, 并连接kafka集群
在这里插入图片描述
安装Kafka Tools后启动Kafka, 并连接kafka集群
在这里插入图片描述
在这里插入图片描述创建topic
在这里插入图片描述
在这里插入图片描述
查看分区中的数据
在这里插入图片描述

kafka的基准测试

基于1个分区1个副本的基准测试

第一步: 创建topic

bin/kafka-topics.sh --zookeeper node1:2181 --create --topic benchmark --partitions 1 --replication-factor 1

第二步: 生产消息基准测试

在生产环境中,推荐使用生产5000W消息,这样会性能数据会更准确些。为了方便测试,课程上演示测试500W的消息作为基准测试

bin/kafka-producer-perf-test.sh --topic benchmark --num-records 5000000 --throughput -1 --record-size 1000 --producer-props
bootstrap.servers=node1:9092,node2:9092,node3:9092 acks=1

在这里插入图片描述
测试结果:
在这里插入图片描述
第三步: 消费者基准测试

bin/kafka-consumer-perf-test.sh --broker-list node1:9092,node2:9092,node3:9092 --topic benchmark -- fetch-size 1048576 --messages 5000000

参数说明: 测试结果:
在这里插入图片描述基于3个分区1个副本的基准测试

第一步: 创建topic

bin/kafka-topics.sh --zookeeper node1:2181 --create --topic benchmark --partitions 3 --replication-factor 1

第二步: 生产消息基准测试
在生产环境中,推荐使用生产5000W消息,这样会性能数据会更准确些。为了方便测试,课程上演示测试500W的消息作为基准测试

bin/kafka-producer-perf-test.sh --topic benchmark --num-records 5000000 --throughput -1 --record-size 1000 --producer-props
bootstrap.servers=node1:9092,node2:9092,node3:9092 acks=1

在这里插入图片描述
第三步: 消费者基准测试

bin/kafka-consumer-perf-test.sh --broker-list node1:9092,node2:9092,node3:9092 --topic benchmark --
fetch-size 1048576 --messages 5000000

测试结果:
在这里插入图片描述
还是一样,因为虚拟机的原因,多个分区反而消费的效率也有所下降

基于1个分区3个副本的基准测试

第一步: 创建topic

bin/kafka-topics.sh --zookeeper node1:2181 --create --topic benchmark --partitions 1 --replication-factor 3

第二步: 生产消息基准测试

在生产环境中,推荐使用生产5000W消息,这样会性能数据会更准确些。为了方便测试,课程上演示测试500W的消息作为基准测试

bin/kafka-producer-perf-test.sh --topic benchmark --num-records 5000000 --throughput -1 --record-size 1000 --producer-props
bootstrap.servers=node1:9092,node2:9092,node3:9092 acks=1

在这里插入图片描述
第三步: 消费者基准测试

bin/kafka-consumer-perf-test.sh --broker-list node1:9092,node2:9092,node3:9092 --topic benchmark --fetch-size 1048576 --messages 5000000

测试结果:
在这里插入图片描述

kafka的java api操作

同步消息到kafka中:生产者代码

第一步:需求
接下来,我们将编写Java程序,将1-100的数字消息写入到Kafka中

第二步: 准备工作

1、创建maven项目 导入相关的依赖

<repositories><!-- 代码库 -->
	<repository>
		<id>central</id>
		<url>http://maven.aliyun.com/nexus/content/groups/public//</url>
		<releases>
			<enabled>true</enabled>
		</releases>
		<snapshots>
			<enabled>true</enabled>
			<updatePolicy>always</updatePolicy>
			<checksumPolicy>fail</checksumPolicy>
		</snapshots>
	</repository>
</repositories>
<dependencies>
	<!-- kafka客户端工具 -->
	<dependency>
		<groupId>org.apache.kafka</groupId>
		<artifactId>kafka-clients</artifactId>
		<version>2.4.1</version>
	</dependency>
	<!-- 工具类 -->
	<dependency>
		<groupId>org.apache.commons</groupId>
		<artifactId>commons-io</artifactId>
		<version>1.3.2</version>
	</dependency>
	<!-- SLF桥接LOG4J日志 -->
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-log4j12</artifactId>
		<version>1.7.6</version>
	</dependency>
	<!-- SLOG4J日志 -->
	<dependency>
		<groupId>log4j</groupId>
		<artifactId>log4j</artifactId>
		<version>1.2.16</version>
	</dependency>
</dependencies>
<build>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<version>3.7.0</version>
			<configuration>
				<source>1.8</source>
				<target>1.8</target>
			</configuration>
		</plugin>
	</plugins>
</build>

2、导入log4j.properties

将log4j.properties配置文件放入到resources文件夹中

log4j.rootLogger=INFO,stdout 
log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p - %m%n

3、创建包和类
创建包cn.kafka,并创建KafkaProducerTest类

第三步: 代码开发

可以参考以下方式来编写第一个Kafka示例程序
参考以下文档:
http://kafka.apache.org/24/javadoc/index.html?org/apache/kafka/clients/producer/KafkaProducer.html
以下为参考代码

在这里插入图片描述
在这里插入图片描述
从kafka中topic中消费消息:消费者代码

第一步: 需求
从 test topic中,将消息都消费,并将记录的offset、key、value打印出来

第二步: 准备工作

在cn.kafka包下创建KafkaConsumerTest类

第三步: 代码开发

参考官网API文档: http://kafka.apache.org/24/javadoc/index.html?org/apache/kafka/clients/consumer/KafkaConsumer.html
在这里插入图片描述
在这里插入图片描述
异步使用带有回调函数方法生成数据:

第一步: 需求

如果我们想获取生产者消息是否成功,或者成功生产消息到Kafka中后,执行一些其他动作。此时,可以很方便地使用带有回调函数来发送消息。

第二步: 样例代码

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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

技术武器库

一句真诚的谢谢,胜过千言万语

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

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

打赏作者

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

抵扣说明:

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

余额充值