Kafka——零基础入门消息系统

                                       Kafka——零基础入门消息系统

 

背景:因工作需要,零基础入门kafka,总结下自学过程,共包括以下几点:

  • 1. 为什么学习kafka?【理论篇】
  • 2. 什么是kafka?【理论篇】
  • 3. Mac如何安装并使用kafka?【工程篇】
  • 4. Python如何安装使用kafka?【代码篇】

相关资源:

 

1. 为什么学习kafka?【理论篇】

关于大数据,工作中主要有两个挑战:

  • 如何收集大量的数据
  • 如何分析收集的数据

        为了克服这2个挑战,消息服务是必须要学习的。那什么是消息服务(或叫消息系统)呢?

        消息服务(系统)是将数据从一个应用程序传输到另一个应用程序的一个服务(系统)。因此应用程序可以专注于数据,但不担心如何共享它。 分布式消息传递基于可靠消息队列的概念。 消息在客户端应用程序和消息传递系统之间异步排队。特别地,Java消息服务(Java Message Service,JMS)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。

        JMS规范目前支持两种消息模型:详细戳 消息队列模式(点对点&发布订阅)

  • 点对点
  • 发布 - 订阅(pub-sub)

1.1 点对点:Queue,不可重复消费

        在点对点系统中,消息被保留在队列中。 一个或多个消费者可以消耗队列中的消息,但是特定消息只能由最多一个消费者消费。 一旦消费者读取队列中的消息,它就从该队列中消失。 该系统的典型示例是订单处理系统,其中每个订单将由一个订单处理器处理,但多个订单处理器也可以同时工作。

 

1.2.1  发布/订阅:Topic,可以重复消费

        在发布 - 订阅系统中,消息被保留在主题中。 与点对点系统不同,消费者可以订阅一个或多个主题并使用该主题中的所有消息。 在发布 - 订阅系统中,消息生产者称为发布者,消息使用者称为订阅者。 一个现实生活的例子是一站式Apache Kafka集群指标监控与运维管控平台

1.2.2  发布/订阅组:Topic,可以重复消费
        在发布 - 订阅系统中,当发布者消息量很大时,显然单个订阅者的处理能力是不足的。实际上现实场景中是多个订阅者节点组成一个订阅组负载均衡消费topic消息即分组订阅,这样订阅者很容易实现消费能力线性扩展。可以看成是一个topic下有多个Queue,每个Queue是点对点的方式,Queue之间是发布订阅方式。

        目前大多数的消息系统都是遵循pub-sub模式 ,比如Apache的ActiveMQ,Apache的Kafka,RabbitMQ、memcacheQ等。传统企业型消息队列ActiveMQ遵循了JMS规范,实现了点对点和发布订阅模型,但其他流行的消息队列RabbitMQKafka并没有遵循JMS规范。

        本文主要介绍Kafka,它专为分布式高吞吐量系统而设计, 往往工作得很好,所以常作为更传统的消息代理的替代品。与其他消息传递系统相比,Kafka具有更好的吞吐量,内置分区,复制和固有的容错能力,这使得它非常适合大规模消息处理应用程序。

 

2. 什么是kafka?【理论篇】

这部分主要简化kafka的相关名词概念、功能、消息模型等。

2.1 相关名词

(1)消息记录【record】

        由一个key,一个value和一个时间戳构成。消息最终存储在主题下的分区中, 记录在生产者中称为生产者记录(ProducerRecord), 在消费者中称为消费者记录(ConsumerRecord),Kafka集群保持所有的消息,直到它们过期, 无论消息是否被消费了,在一个可配置的时间段内,Kafka集群保留所有发布的消息,不管这些消息有没有被消费。比如,如果消息的保存策略被设置为2天,那么在一个消息被发布的两天时间内,它都是可以被消费的。之后它将被丢弃以释放空间。Kafka的性能是和数据量无关的常量级的,所以保留太多的数据并不是问题。

(2)消息【message】

        kafka里面的我们处理的数据叫做消息。

(3)生产者【producer】

        生产者用于发布(send)消息,是发送给一个或多个Kafka主题的消息的发布者。 生产者向Kafka经纪人发送数据。 每当生产者将消息发布给代理时,代理只需将消息附加到最后一个段文件。实际上,该消息将被附加到分区。 生产者还可以向他们选择的分区发送消息。

(4)消费者【consumer】

        消费者用于订阅(subscribe)消息Consumers从经纪人处读取数据。 消费者订阅一个或多个主题,并通过从代理中提取数据来使用已发布的消息。

(5)消费者组【consumer group】

        相同的group.id的消费者将视为同一个消费者组, 每个消费者都需要设置一个组id, 每条消息只能被 consumer group 中的一个 Consumer 消费,但可以被多个 consumer group 消费。

(6)主题【topic】

        消息的一种逻辑分组,用于对消息进行分类,每一类消息称为一个主题,相同主题的消息放在一个队列中。

        换句话说,属于特定类别的消息流称为主题。 数据存储在主题中。主题被拆分成分区。 对于每个主题,Kafka保存一个分区的迷你妈妈。 每个这样的分区包含不可变有序序列的消息。 分区被实现为具有相等大小的一组分段文件。

(7)分区【partition】

       消息的一种物理分组, 一个主题被拆成多个分区,每一个分区就是一个顺序的、不可变的消息队列,并且可以持续添加,分区中的每个消息都被分配了一个唯一的id,称之为偏移量(offset),在每个分区中偏移量都是唯一的。每个分区对应一个逻辑log,有多个segment组成。

(8)偏移量【offset,或者叫做 Partition offset(分区偏移)

        分区中的每个消息都一个一个唯一id,称之为偏移量,它代表已经消费的位置。每个分区消息具有称为 offset 的唯一序列标识。可以自动或者手动提交偏移量(即自动或者手动控制一条消息是否已经被成功消费)。

(9)代理【broker】

        一台kafka服务器称之为一个broker。Kafka集群通常由多个代理组成以保持负载平衡。 Kafka代理是无状态的,所以他们使用ZooKeeper来维护它们的集群状态。 一个Kafka代理实例可以每秒处理数十万次读取和写入,每个Broker可以处理TB的消息,而没有性能影响。Kafka经纪人领导选举可以由ZooKeeper完成。

(10)经纪人【Brokers】

        代理是负责维护发布数据的简单系统。 每个代理可以每个主题具有零个或多个分区。 假设,如果在一个主题和N个代理中有N个分区,每个代理将有一个分区。
        假设在一个主题中有N个分区并且多于N个代理(n + m),则第一个N代理将具有一个分区,并且下一个M代理将不具有用于该特定主题的任何分区。
        假设在一个主题中有N个分区并且小于N个代理(n-m),每个代理将在它们之间具有一个或多个分区共享。 由于代理之间的负载分布不相等,不推荐使用此方案。
 

(11)副本【replica,或者叫做 Replicas of partition(分区备份)

       副本只是一个分区(partition)的备份。 副本从不读取或写入数据。 它们用于防止数据丢失。

(12)领导者【leader】

        Leader 是负责给定分区的所有读取和写入的节点。 每个分区都有一个服务器充当Leader, producer 和 consumer 只跟 leader 交互。

(13)追随者【follower】

        跟随领导者指令的节点被称为Follower。 如果领导失败,一个追随者将自动成为新的领导者。 跟随者作为正常消费者,拉取消息并更新其自己的数据存储。replica 中的一个角色,从 leader 中复制数据。

(14)Zookeeper【不熟悉,看下Zookeeper 教程

         Kafka代理是无状态的,所以他们使用ZooKeeper来维护它们的集群状态。ZooKeeper用于管理和协调Kafka代理。ZooKeeper服务主要用于通知生产者和消费者Kafka系统中存在任何新代理或Kafka系统中代理失败。 根据Zookeeper接收到关于代理的存在或失败的通知,然后产品和消费者采取决定并开始与某些其他代理协调他们的任务。

(15)Kafka Cluster(Kafka集群)

         Kafka有多个代理被称为Kafka集群。 可以扩展Kafka集群,无需停机。 这些集群用于管理消息数据的持久性和复制。

 

2.2 kafka功能

(1)发布订阅

         生产者(producer)生产消息(数据流), 将消息发送到到kafka指定的主题队列(topic)中,也可以发送到topic中的指定分区(partition)中,消费者(consumer)从kafka的指定队列中获取消息,然后来处理消息。

(2)流处理【Stream Process】

         将输入topic转换数据流到输出topic。

(3)连接器【Connector)】

        将数据从应用程序(源系统)中导入到kafka,或者从kafka导出数据到应用程序(宿主系统sink system), 例如:将文件中的数据导入到kafka,从kafka中将数据导出到文件中

 

2.3 kafka的消息模型

  • 队列模型:同名的消费者组员瓜分消息,换句话说,一组消费者从服务器读取消息,一条消息只由其中一个消费者来处理
  • 发布订阅模型:广播消息给多个消费者组(不同名),换句话说,消息被广播给所有消费者,接收到消息的消费者都可以处理此消息

本质:生产者(producer)将消息记录(record)发送到kafka中的主题中(topic), 一个主题可以有多个分区(partition), 消息最终存储在分区中,消费者(consumer)最终从主题的分区中获取消息。 

区分:kafka 的消费者和消费者组,kafka为两种模型提供了单一的消费者抽象模型:消费者组。

  • 假如 所有消费者都在一个组中,那么就是 队列模型
  • 假如 所有消费者都在不同的组中,那么就是 发布 订阅模型

 

2.4 Kafka的工作流程

2.4.1 发布 - 订阅模型的工作流程

1. 生产者定期向主题发送消息。
2. Kafka代理存储为该特定主题配置的分区中的所有消息。 它确保消息在分区之间平等共享。 如果生产者发送两个消息并且有两个分区,Kafka将在第一分区中存储一个消息,在第二分区中存储第二消息。
3. 消费者订阅特定主题。
4. 一旦消费者订阅主题,Kafka将向消费者提供主题的当前偏移,并且还将偏移保存在Zookeeper系综中。
5. 消费者将定期请求Kafka(如100 Ms)新消息。
6. 一旦Kafka收到来自生产者的消息,它将这些消息转发给消费者。
7. 消费者将收到消息并进行处理。
8. 一旦消息被处理,消费者将向Kafka代理发送确认。
9. 一旦Kafka收到确认,它将偏移更改为新值,并在Zookeeper中更新它。 由于偏移在Zookeeper中维护,消费者可以正确地读取下一封邮件,即使在服务器暴力期间。

以上流程将重复,直到消费者停止请求。
消费者可以随时回退/跳到所需的主题偏移量,并阅读所有后续消息。

2.4.2 队列消息/用户组的工作流程

        在队列消息传递系统而不是单个消费者中,具有相同组ID 的一组消费者将订阅主题。 简单来说,订阅具有相同 Group ID 的主题的消费者被认为是单个组,并且消息在它们之间共享。

1. 生产者以固定间隔向某个主题发送消息。
2. Kafka存储在为该特定主题配置的分区中的所有消息,类似于前面的方案。
3. 单个消费者订阅特定主题,假设 Topic-01 为 Group ID 为 Group-1 。
4. Kafka以与发布 - 订阅消息相同的方式与消费者交互,直到新消费者以相同的组ID 订阅相同主题 Topic-01  1 。
5. 一旦新消费者到达,Kafka将其操作切换到共享模式,并在两个消费者之间共享数据。 此共享将继续,直到用户数达到为该特定主题配置的分区数。
6. 一旦消费者的数量超过分区的数量,新消费者将不会接收任何进一步的消息,直到现有消费者取消订阅任何一个消费者。 出现这种情况是因为Kafka中的每个消费者将被分配至少一个分区,并且一旦所有分区被分配给现有消费者,新消费者将必须等待。

此功能也称为使用者组。 同样,Kafka将以非常简单和高效的方式提供两个系统中最好的。

 

3、Mac如何安装并使用kafka?【工程篇】

         实践是检验真理的唯一标准。mac 如何安装kafka,参考博客Kafka入门教程 Golang实现Kafka消息发送、接收,详细过程【含图片,有问题请留言】如下:

3.1 安装kafka

brew install kafka

装kafka是需要依赖于zookeeper的,所以安装kafka的时候也会包含zookeeper。

kafka的安装目录:/usr/local/Cellar/kafka 
kafka的配置文件目录:/usr/local/etc/kafka 
kafka服务的配置文件:/usr/local/etc/kafka/server.properties 
zookeeper配置文件: /usr/local/etc/kafka/zookeeper.properties


3.2 修改server.properties配置【需修改】、zookeeper.properties配置【不需修改】

# server.properties中的重要配置
 
broker.id=0
listeners=PLAINTEXT://:9092
advertised.listeners=PLAINTEXT://127.0.0.1:9092
log.dirs=/usr/local/var/lib/kafka-logs
# zookeeper.properties中的重要配置
 
dataDir=/usr/local/var/lib/zookeeper
clientPort=2181
maxClientCnxns=0 

 

3.3 启动Zookeeper

# 新起一个终端1启动zookeeper, 注意版本号, 可能不一样
cd /usr/local/Cellar/kafka/2.4.1
./bin/zookeeper-server-start /usr/local/etc/kafka/zookeeper.properties

 

3.4 启动kafka

# 新起一个终端2启动zookeeper,注意启动kafka之前先启动zookeeper,注意Kafka版本号
cd /usr/local/Cellar/kafka/2.4.1
./bin/kafka-server-start /usr/local/etc/kafka/server.properties

 

3.5 创建topic

# 新起一个终端3来创建主题topic
cd /usr/local/Cellar/kafka/2.4.1 
./bin/kafka-topics --create --zookeeper localhost:2181 --partitions 1 --topic test

 

3.6 查看topic

# 创建成功可以通过 list 列举所有的主题
./bin/kafka-topics --list --zookeeper localhost:2181
 
# 查看某个主题的信息
./bin/kafka-topics --describe --zookeeper localhost:2181 --topic <name>

 

3.7 发送消息

# 新起一个终端4,作为生产者,用于发送消息,每一行算一条消息,将消息发送到kafka服务器
cd /usr/local/Cellar/kafka/2.4.1  
./bin/kafka-console-producer --broker-list localhost:9092 --topic test 
 > This is a message
 > This is another message

 

3.8 消费消息(接收消息)

# 新起一个终端5作为消费者,接收消息
cd /usr/local/Cellar/kafka/2.4.1
./bin/kafka-console-consumer --bootstrap-server localhost:9092 --topic test --from-beginning

This is a message
This is a message1
This is another message

 

最后,重复3.7 和 3.8 即可。

 

4、Python如何安装使用kafka?【代码篇】

参考博客:kafka-python初体验

4.1 安装kafka-python包

pip install kafka-python

4.2 先按照上面的方法启动Zookeeper,再启动kafka。

4.3 新建生产者代码kafka_producer_demo.py

from kafka import KafkaProducer

producer = KafkaProducer(bootstrap_servers=['localhost:9092'])
future = producer.send('my_topic' ,  value= b'aaaaaaaaa', partition= 0)
result = future.get(timeout= 10)
print(result)

说明:在 my_topic 主题下,发布消息为 aaaaaaaaa 的消息。

运行结果:

 

4.4 新建消费者代码kafka_consumer_demo.py

from kafka import KafkaConsumer

consumer = KafkaConsumer('my_topic',  bootstrap_servers= ['localhost:9092'])
for msg in consumer:
    print(msg)

说明:运行消费者代码,他就一直监听生产者发布的消息,只要生产者新产生了一条消息,他就会 print 输出 msg。

运行结果:

 

同理,重复运行生产者代码,消费者代码在运行的情况下就能不断接收到来自生产者新产生的消息!

当然,觉得麻烦的朋友,可以写一个shell脚本,一键运行!

到这里,kafka的基础就算说完了,如果想接触高阶操作,请自己阅读kafka官方文档。码字不易,看到这里的朋友点个赞吧。😂

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页