目录

1、消息队列

1.1、传统消息队列的应用场景

2.1.1、异步处理

1.1.2、系统解耦

1.1.3、流量削峰

1.1.4、日志处理

1.2、生产者-消费者模型

1.3、消息队列的两种模式

1.3.1、点对点模式

1.3.2、发布/订阅模式

2、Kafka简介

2.1、Kafka定义

2.2、Kafka的应用场景

2.3、Kafka的诞生背景

2.4、Kafka版本

3、环境搭建

3.1、搭建Kafka集群

3.2、Kafka目录结构分析

3.3、Kafka一键启动/关闭脚本

3.4、Windows环境下启动Kafka

4、基础操作

4.1、Kafka的生产者/消费者/工具

4.2、创建topic

4.3、生产消息到Kafka

4.4、从Kafka消费消息

4.5、使用Kafka Tools操作Kafka

4.5.1、连接Kafka集群

4.5.2、创建topic

5、Kafka基准测试

5.1、Kafka的基准测试工具

5.2、基准测试

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


1、消息队列

消息队列(Message Queue,MQ):从字面上来理解,是一种用来存储消息的队列。简单理解,消息队列就是将需要传输的数据存放在队列中。

  • 消息队列是用于存放消息的组件;
  • 程序员可以将消息放入到队列中,也可以从消息队列中获取消息;
  • 很多时候消息队列并不是一个永久性的存储,是作为临时存储存在的(设定一个期限:设置消息在MQ中保存10天);
  • 消息队列中间件:消息队列的组件。

消息队列中间件:就是用来存储消息的软件(组件)。举个例子,为了分析网站的用户行为,我们需要记录用户的访问日志,这些一条条的日志,可以看成是一条条的消息,我们可以将它们保存到消息队列中,将来有一些应用程序需要处理这些日志,就可以随时将这些消息取出来处理。

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

1.1、传统消息队列的应用场景

传统的消息队列的主要应用场景包括:缓冲/消峰、解耦和异步通信、日志处理等等。

2.1.1、异步处理

异步处理:允许用户把一个消息放入队列,但并不立即处理它,然后在需要的时候再去处理它们。

可以将一些比较耗时的操作放在其它系统中,通过消息队列将需要进行处理的消息进行存储,其它系统可以消费消息队列中的数据。

例如:电商网站中,新的用户注册时,需要将用户的信息保存到数据库中,同时还要额外发送注册的邮件通知,以及短信注册码给用户,但因为发送邮件、发送注册短信需要连接外部的服务器,需要额外等待一段时间,此时,就可以使用消息队列来进行异步处理,从而实现快速响应。

android 查看消息队列 消息队列存储在哪里_android 查看消息队列

1.1.2、系统解耦

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

原先一个微服务是通过接口(HTTP)调用另一个微服务,这时候耦合很严重,只要接口发生变化就会导致系统不可用。使用消息队列可以将系统进行解耦合,现在第一个微服务可以将消息放入到消息队列中,另一个微服务可以从消息队列中取出来进行处理。从而进行系统解耦。

android 查看消息队列 消息队列存储在哪里_kafka_02

1.1.3、流量削峰

缓冲/:有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。

因为消息队列是低延迟、高可靠、高吞吐的,因此可以应对大量并发。

android 查看消息队列 消息队列存储在哪里_消息队列_03

1.1.4、日志处理

可以使用消息队列作为临时存储,或者一种通信管理。

大型电商网站(淘宝、京东、国美、苏宁...)、App(抖音、美团、滴滴...)等需要分析用户行为,要根据用户的访问行为来发现用户的喜好以及活跃情况,需要在页面上收集大量的用户访问信息。

android 查看消息队列 消息队列存储在哪里_kafka_04

1.2、生产者-消费者模型

Java服务器端开发的交互模型是这样的:

android 查看消息队列 消息队列存储在哪里_数据_05

使用Java JDBC来访问操作MySQL数据库的交互模型是这样的:

android 查看消息队列 消息队列存储在哪里_android 查看消息队列_06

它也是一种请求响应模型,只不过它不再是基于HTTP协议,而是基于MySQL数据库的通信协议。

而如果我们基于消息队列来编程,此时的交互模式称为:生产者-消费者模型:

android 查看消息队列 消息队列存储在哪里_数据_07

1.3、消息队列的两种模式

1.3.1、点对点模式

消费者主动拉取数据并消费数据,向消息队列发回确认收到,然后消息队列收到确认后清除消息。

android 查看消息队列 消息队列存储在哪里_kafka_08

消息发送者生产消息发送到消息队列中,然后消息接受者从消息队列中取出并且消费消息,消息被消费以后,消息队列中不再有存储,所以消息接受者不可能消费到已经被消费的消息。

点对点模式的特点;

  • 每个消息只有一个接收者(Consumer)(即一旦被消费,消息就不在消息队列中);
  • 发送者和接收者间没有依赖性,发送者发送消息之后,不管有没有接收者在运行,都不会影响到发送者下次发送消息;
  • 接收者在成功接收消息之后需向队列应答成功,一遍消息队列删除当前接收的消息。

1.3.2、发布/订阅模式

android 查看消息队列 消息队列存储在哪里_数据_09

发布/订阅模式的特点:

  • 每个消息可以有多个消费者;
  • 发布者和订阅制之间有时间上的依赖性,针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息;
  • 为了消费消息,订阅者需要提前订阅该角色主题,并保持在线运行;
  • 可以有多个topic主题(浏览、点赞、收藏、评论等);
  • 消费者消费数据之后,不删除数据;
  • 每个消费者相互独立,都可以消费到数据。

2、Kafka简介

2.1、Kafka定义

Kafka是由Apache软件基金会开发的一个开源流平台,由Scala和Java编写。Kafka的Apache官网是这样介绍Kafka的:

Apache Kafka是一个分布式流平台,一个分布式的流平台应该包含3点关键的能力:

  • 发布和订阅数据流,类似于消息队列或者是企业消息传递系统;
  • 以容错的持久化方式存储数据流;
  • 处理数据流。

Kafka传统定义:Kafka是一个分布式的基于发布/订阅模式的消息队列,主要应用于大数据实时处理领域。

发布/订阅:消息的发布者不会将消息直接发送给特定的订阅者,而是将发布的消息分为不同的类别,订阅者只接收感兴趣的消息。

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

我们重点关注三个部分的关键词:

  • Publish and subscribe:发布与订阅;
  • Store:存储;
  • Process:处理。

Kafka的结构:

  •  为方便扩展,并提高吞吐量,一个topic分为多个partition;
  • 配合分区的设计,提出消费者组的概念,组内每个消费者并行消费;
  • 为提高可用性,为每个partition增加若干副本,类似NameNode HA;
  • ZK中记录谁是leader,Kafka2.8.0以后也可以配置不采用ZK。

android 查看消息队列 消息队列存储在哪里_kafka_10

2.2、Kafka的应用场景

我们通常将Apache Kafka用在两类程序:

  • 建立实时数据管道,以可靠地在系统或应用程序之间获取数据;
  • 构建实时流应用程序,以转换或响应数据流。

android 查看消息队列 消息队列存储在哪里_android 查看消息队列_11

上图,我们可以看到:

  • Producers:可以有很多的应用程序,将消息数据放入到Kafka集群中;
  • Consumers:可以有很多的应用程序,将消息数据从Kafka集群中拉取出来;
  • Connectors:Kafka的连接器可以将数据库中的数据导入到Kafka,也可以将Kafka的数据导出到数据库中;
  • Stream Processors:流处理器可以从Kafka中拉取数据,也可以将数据写入到Kafka中。

2.3、Kafka的诞生背景

Kafka 的诞生,是为了解决linkedin的数据管道问题,起初linkedin采用了ActiveMQ来进行数据交换,大约是在2010年前后,那时的ActiveMQ还远远无法满足linkedin对数据传递系统的要求,经常由于各种缺陷而导致消息阻塞或者服务无法正常访问,为了能够解决这个问题,linkedin决定研发自己的消息传递系统,当时linkedin的首席架构师jay kreps便开始组织团队进行消息传递系统的研发。

2.4、Kafka版本

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

3、环境搭建

3.1、搭建Kafka集群

  • Kafka集群是必须要有Zookeeper的;
  • 每一个Kafka的节点都需要修改broker.id(每个节点的标识,不能重复);
  • log.dirs数据存储目录需要配置。
1、将Kafka的安装包上传到虚拟机,并解压
cd /export/software/
tar -xvzf kafka_2.12-2.4.1.tgz -C ../server/
cd /export/server/kafka_2.12-2.4.1

2、修改 server.properties
cd /export/server/kafka_2.12-2.4.1/config
vim server.properties
    # 指定broker的id
    broker.id = 0
    # 指定kafka数据的位置
    log.dirs = /export/server/kafka_2.12-2.4.1/data

3、将安装好的Kafka复制到另外两台服务器
scp -r kafka_2.12-2.4.1/ node2.itcast.cn:$PWD
scp -r kafka_2.12-2.4.1/ node3.itcast.cn:$PWD
- 修改另外两个结点的broker.id分别为1和2

4、配置KAFKA_HOME环境变量
vim /etc/profile
    export KAFKA_HOME=/export/server/kafka_2.12-2.4.1
    export PATH=$PATH:${KAFKA_HOME}
- 分发到各个结点:
scp /etc/profile node2.itcast.cn:$PWD
scp /etc/profile node3.itcast.cn:$PWD
- 每个结点加载环境变量
source /etc/profile

5、启动服务器
# 启动Zookeeper
nohup bin/zookeeper-server-start.sh config/zookeeper.properties &
# 启动Kafka
cd /export/server/kafka_2.12-2.4.1
nohup bin/kafka-server-start.sh config/server.properties &
# 测试Kafka集群是否启动成功
bin/kafka-topics.sh --bootstrap-server node1.itcast.cn:9092 --list

3.2、Kafka目录结构分析

目录名称

说明

bin

Kafka的所有执行脚本都在这里。例如:启动Kafka服务器,创建Topic、生产者、消费者程序等

config

Kafka的所有配置文件

libs

运行Kafka所需要的所有JAR包

logs

Kafka的所有日志文件,如果Kafka出现一些问题,需要到该目录中去查看异常信息

site-docs

Kafka的网站帮助文件

3.3、Kafka一键启动/关闭脚本

为了方便将来进行一键启动、关闭Kafka,我们可以编写一个shell脚本来操作。将来只要执行一次该脚本就可以快速启动/关闭Kafka.

1、在节点1中创建/export/onekey目录
    cd /export/onekey
2、准备slave配置文件,用于保存要启动哪几个节点上的Kafka
    node1.itcast.cn
    node2.itcast.cn
    node3.itcast.cn
3、编写start-kafka.sh脚本
    vim start-kafka.sh
        cat /export/onekey/slave | while read line
        do
        {
        echo $line
        ssh    $line    "source    /etc/profile;export    JMX_PORT=9988;nohup${KAFKA_HOME}/bin/kafka-server-start.sh ${KAFKA_HOME}/config/server.properties >/dev/nul*2>&1 & " &
        }&
        wait
        done
4、编写stop-kafka.sh脚本
    vim stop-kafka.sh
        cat /export/onekey/slave | while read line
        do
        {
        echo $line
        ssh $line "source /etc/profile;jps |grep Kafka |cut -d' ' -f1 |xargs kill -s 9"
        }&
        wait
        done
5、启动服务器
# 启动zookeeper
nuhup bin/zookeeper-server-start.sh config/zookeeper.properties &
# 启动kafka
cd /export/server/kafka_2.12-2.4.1
nohup bin/kafka-server-start.sh config/server.properties &
# 测试Kafka集群是否启动成功
bin/kafka-topics.sh --bootstrap-server node1.itcast.cn:9092 --list

3.4、Windows环境下启动Kafka

需遵循以下几步, 依次打开新的命令行启动, 也不要关闭之前的命令行窗口
cmd 至 D:\kafka_2.12-3.1.0。

- 启动 Zookeeper 服务, 默认端口 2181
bin\windows\zookeeper-server-start.bat config\zookeeper.properties

- 启动 Kafka 服务,默认端口 9092
bin\windows\kafka-server-start.bat config\server.properties

4、基础操作

4.1、Kafka的生产者/消费者/工具

安装Kafka集群,可以测试以下:

  • 创建一个topic主题(消息都是存放在topic中,类似mysql建表的过程);
  • 基于kafka的内置测试生产者脚本来读取标准输入(键盘输入)的数据,并放入到topic中;
  • 基于kafka的内置测试消费者脚本来消费topic中的数据。

推荐开发的时候使用Kafka Tool,它可以:

  • 浏览Kafka集群节点,topic数量,分区数量;
  • 创建topic/删除topic;
  • 浏览Zookeeper中的数据;

android 查看消息队列 消息队列存储在哪里_消息队列_12

4.2、创建topic

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

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

- windows下创建主题
# 创建名为test的主题
D:\kafka_2.13-3.1.0\bin\windows>kafka-topics.bat --create --bootstrap-server localhost:9092 1 --partitions 1 --topic test

4.3、生产消息到Kafka

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

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

- windows下创建生产者
D:\kafka_2.13-3.1.0\bin\windows>kafka-console-producer.bat --broker-list localhost:9092 --topic test

4.4、从Kafka消费消息

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

bin/kafka-console-consumer.sh --bootstrap-server node1.itcast.cn:9092 --topic test --from-beginning

-windows下创建消费者
D:\kafka_2.13-3.1.0\bin\windows>kafka-console-consumer --bootstrap-server localhost:9092 --topic test

4.5、使用Kafka Tools操作Kafka

4.5.1、连接Kafka集群

安装Kafka后启动Kafka。

android 查看消息队列 消息队列存储在哪里_android 查看消息队列_13

4.5.2、创建topic

android 查看消息队列 消息队列存储在哪里_消息队列_14

5、Kafka基准测试

5.1、Kafka的基准测试工具

Kafka中提供了内置的性能测试工具:

  • 生产者:测试出来每秒传输的数据量(多少条数据、多少M的数据);
  • 消费者:测试消费每秒拉取的数据量。

对比生产者和消费者,消费者的速度更快。

5.2、基准测试

基准测试(benchmark testing)是一种测量和评估软件性能指标的活动。我们可以通过基准测试,了解到软件、硬件的性能水平。主要测试负载的执行时间、传输速度、吞吐量、资源占用率等。

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

测试步骤:

  • 启动Kafka集群;
  • 创建一个1个分区1个副本的topic: benchmark;
  • 同时运行生产者、消费者基准测试程序;
  • 观察结果。

1、创建topic

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

2、生产消息基准测试

在生产环境中,推荐使用生产5000W消息,这样性能数据会更准确些。

bin/kafka-producer-pref-test.sh --topic benchmark --num-records 5000000 --throughput -1 
--record-size 1000 --producer-props 
bootstrap.servers=node1.itcast.cn:9092,node2.itcast.cn:9092,node3.itcast.cn:9092 acks=1
bin/kafka-producer-pref-test.sh
--topic topic的名字
--num-records 总共指定生产数据量
--throughput 指定吞吐量——限流(-1不指定)
--record-size record数据大小(字节)
--producer-props bootstrap.server=192.168.1.20:9092,192.168.1.20:9092,192.168.1.22:9092 
acks=1 指定Kafka集群地址,ACK模式

在虚拟机上,因为都是共享笔记本上的CPU、内存、网络,所以分区越多,反而效率越低。但是如果是真实的服务器,分区多效率是会有明显提升的。

3、消费消息基准测试

bin/kafka-consumer-pref-test.sh --broker-list 
node1.itcast.cn:9092,node2.itcast.cn:9092,node3.itcast.cn:9092 --topic benchmark 
--fetch-size 1048576 --messages 5000000
bin/kafka-consumer-pref-test.sh
--broker-list 指定kafka集群地址
--topic 指定topic的名称
--fetch-size 每次拉取的数据大小
--message 总共要消费的消息个数