Kafka详解与总结(一)

1. Kafka概述

1.1. 消息队列

1)点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)

点对点模型通常是一个基于拉取或者轮询的消息传送模型,这种模型从队列中请求信息,而不是将消息推送到客户端。这个模型的特点是发送到队列的消息被一个且只有一个接收者接收处理,即使有多个消息监听者也是如此。

2)发布/订阅模式(一对多,数据生产后,推送给所有订阅者)

发布订阅模型则是一个基于推送的消息传送模型。发布订阅模型可以有多种不同的订阅者,临时订阅者只在主动监听主题时才接收消息,而持久订阅者则监听主题的所有消息,即使当前订阅者不可用,处于离线状态。

1.1. 为什么需要消息队列

1)解耦:

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

2)冗余:

消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的"插入-获取-删除"范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。

3)扩展性:

因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。

4)灵活性 & 峰值处理能力:

在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。

5)可恢复性:

系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。

6)顺序保证:

在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。(Kafka保证一个Partition内的消息的有序性)

7)缓冲:

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

8)异步通信:

很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。

1.2. 什么是Kafka

在流式计算中,Kafka一般用来缓存数据,Storm通过消费Kafka的数据进行计算。

1)Apache Kafka是一个开源消息系统,由Scala写成。是由Apache软件基金会开发的一个开源消息系统项目。

2)Kafka最初是由LinkedIn公司开发,并于2011年初开源。2012年10月从Apache Incubator毕业。该项目的目标是为处理实时数据提供一个统一、高通量、低等待的平台。

3)Kafka是一个分布式消息队列。Kafka对消息保存时根据Topic进行归类,发送消息者称为Producer,消息接受者称为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)称为broker

4)无论是kafka集群,还是consumer都依赖于zookeeper集群保存一些meta信息,来保证系统可用性。

 

1)Producer :消息生产者,就是向kafka broker发消息的客户端;

2)Consumer :消息消费者,向kafka broker取消息的客户端;

3)Topic :可以理解为一个队列;

4) Consumer Group (CG):这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播(发给任意一个consumer)的手段。一个topic可以有多个CG。topic的消息会复制(不是真的复制,是概念上的)到所有的CG,但每个partion只会把消息发给该CG中的一个consumer。如果需要实现广播,只要每个consumer有一个独立的CG就可以了。要实现单播只要所有的consumer在同一个CG。用CG还可以将consumer进行自由的分组而不需要多次发送消息到不同的topic;

5)Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic;

6)Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序;

7)Offset:kafka的存储文件都是按照offset.kafka来命名,用offset做名字的好处是方便查找。例如你想找位于2049的位置,只要找到2048.kafka的文件即可。当然the first offset就是00000000000.kafka。

1. Kafka单节点运行方式

Setp 1:下载代码

下载 kafka_2.12-2.1.0 版本并且解压。

https://www.apache.org/dyn/closer.cgi?path=/kafka/2.1.0/kafka_2.12-2.1.0.tgz

> tar -xzf kafka_2.11-1.0.0.tgz

> cd kafka_2.11-1.0.0

Setp 2:启动服务

Kafka 使用 ZooKeeper 如果你还没有ZooKeeper服务器,你需要先启动一个ZooKeeper服务器。 您可以通过与kafka打包在一起的便捷脚本来快速简单地创建一个单节点ZooKeeper实例。如果你有使用docker的经验,你可以使用docker-compose快速搭建一个zk集群。

> bin/zookeeper-server-start.sh config/zookeeper.properties

现在启动Kafka服务器:

> bin/kafka-server-start.sh config/server.properties 

后台启动:

> bin/kafka-server-start.sh config/server.properties 1>/dev/null  2>&1  &

其中1>/dev/null  2>&1 是将命令产生的输入和错误都输入到空设备,也就是不输出的意思。

/dev/null代表空设备。

Setp 3:创建一个topic

创建一个名为“test”的topic,它有一个分区和一个副本:

> bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test

运行list(列表)命令来查看这个topic:

> bin/kafka-topics.sh --list --zookeeper localhost:2181 test

除了手工创建topic外,你也可以配置你的broker,当发布一个不存在的topic时自动创建topic。

Setp 4:发送消息

Kafka自带一个命令行客户端,它从文件或标准输入中获取输入,并将其作为message(消息)发送到Kafka集群。默认情况下,每行将作为单独的message发送。

运行 producer,然后在控制台输入一些消息以发送到服务器。

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

hello world

Hello study.163.com

Setp 5:启动消费者

Kafka还有一个命令行使用者,它会将消息转储到标准输出。

> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning

hello world

hello study.163.com

如果在不同的终端中运行上述命令,能够在生产者终端中键入消息并看到它们出现在消费者终端中。

所有命令行工具都有选项; 运行不带参数的命令将显示使用信息。

 =========================================================================================

Kafka集群部署方式

Setp 6:设置多 broker 集群

到目前,我们只是单一的运行一个broker对于Kafka,一个broker仅仅只是一个集群的大小,接下来我们来broker。

首先为每个broker创建一个配置文件:

> cp config/server.properties config/server-1.properties

> cp config/server.properties config/server-2.properties

现在编辑这些新建的文件,设置以下属性:

config/server-1.properties:

    broker.id=1

    listeners=PLAINTEXT://:9093

    log.dir=/tmp/kafka-logs-1

config/server-2.properties:

    broker.id=2

    listeners=PLAINTEXT://:9094

    log.dir=/tmp/kafka-logs-2

broker.id属性是集群中每个节点的名称,这一名称是唯一且永久的。

我们已经建立Zookeeper和一个单节点了,现在我们只需要启动两个新的节点:

> bin/kafka-server-start.sh config/server-1.properties &

...

> bin/kafka-server-start.sh config/server-2.properties &

...

现在创建一个副本为3的新topic:

> bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic my-replicated-topic

运行命令“describe topics” 查看集群中的topic信息

> bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic

Topic:my-replicated-topic   PartitionCount:1    ReplicationFactor:3 Configs:

    Topic: my-replicated-topic  Partition: 0    Leader: 1   Replicas: 1,2,0 Isr: 1,2,0

以下是对输出信息的解释:第一行给出了所有分区的摘要,下面的每行都给出了一个分区的信息。因为我们只有一个分区,所以只有一行。

l “leader”是负责给定分区所有读写操作的节点。每个节点都是随机选择的部分分区的领导者。

l “replicas”是复制分区日志的节点列表,不管这些节点是leader还是仅仅活着。

l “isr”是一组“同步”replicas,是replicas列表的子集,它活着并被指到leader。

请注意,在示例中,节点1是该主题中唯一分区的领导者。

我们运行这个命令,看看一开始我们创建的那个test节点:

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

Topic:test  PartitionCount:1    ReplicationFactor:1 Configs:

    Topic: test Partition: 0    Leader: 0   Replicas: 0 Isr: 0

这并不奇怪,刚才创建的主题没有Replicas,并且在服务器“0”上,我们创建它的时候,集群中只有一个服务器,所以是“0”。

发布一些信息在新的topic上:

> bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-replicated-topic

...

my test message 1

my test message 2

消费这些消息:

> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic

...

my test message 1

my test message 2

测试集群的容错,kill掉leader,Broker1作为当前的leader,也就是kill掉Broker1。

> ps aux | grep server-1.properties

7564 ttys002    0:15.91 /System/Library/Frameworks/JavaVM.framework/Versions/1.8/Home/bin/java...

> kill -9 7564

备份节点之一成为新的leader,而broker1已经不在同步备份集合里了。

> bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic

Topic:my-replicated-topic   PartitionCount:1    ReplicationFactor:3 Configs:

    Topic: my-replicated-topic  Partition: 0    Leader: 2   Replicas: 1,2,0 Isr: 2,0

即使最初接受写入的领导者已经失败,这些消息仍可供消费:

> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic

...

my test message 1

my test message 2

Setp 7:使用 Kafka Connect 导入/导出数据

Kafka Connect是Kafka的一个工具,它可以将数据导入和导出到Kafka。它是一种可扩展工具,通过运行connectors(连接器) 使用自定义逻辑来实现与外部系统的交互。接下来我们将学习如何使用简单的connectors来运行Kafka Connect,这些connectors 将文件中的数据导入到Kafka topic中,并从中导出数据到一个文件。

首先,我们将创建一些种子数据来进行测试:

> echo -e "allen" > test.txt

> echo -e "tony" >> test.txt

接下来,我们将启动两个standalone(独立)运行的连接器,第一个是源连接器,它从输入文件读取行并生成Kafka主题,第二个是宿连接器从Kafka主题读取消息并将每个消息生成为输出文件中的一行。

> bin/connect-standalone.sh config/connect-standalone.properties config/connect-file-source.properties config/connect-file-sink.properties

一旦Kafka Connect进程启动,源连接器应该开始从test.txt主题读取行并生成它们connect-test,并且接收器连接器应该开始从主题读取消息connect-test 并将它们写入文件test.sink.txt。我们可以通过检查输出文件的内容来验证数据是否已通过整个管道传递:

> more test.sink.txt

allen

tony

数据存储在Kafka主题中connect-test,因此我们还可以运行控制台使用者来查看主题中的数据:

> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic connect-test --from-beginning

{"schema":{"type":"string","optional":false},"payload":"allen"}

{"schema":{"type":"string","optional":false},"payload":"tony"}

...

连接器一直在处理数据,所以我们可以将数据添加到文件中,并看到它在pipeline 中移动:

> echo mike >> test.txt

猜你喜欢

转载自www.cnblogs.com/htkj/p/10941435.html