python-kafka安装和使用
一.kafka介绍
Kafka是一种高吞吐量的分布式发布订阅消息系统(消息引擎系统),它可以处理消费者在网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。
一个消息系统负责将数据从一个应用传递到另外一个应用,应用只需关注于数据,无需关注数据在两个或多个应用间是如何传递的。分布式消息传递基于可靠的消息队列,在客户端应用和消息系统之间异步传递消息。有两种主要的消息传递模式:点对点传递模式、发布-订阅模式。大部分的消息系统选用发布-订阅模式。Kafka就是一种发布-订阅模式。
点对点消息传递模式
在点对点消息系统中,消息持久化到一个队列中。此时,将有一个或多个消费者消费队列中的数据。但是一条消息只能被消费一次。当一个消费者消费了队列中的某条数据之后,该条数据则从消息队列中删除。该模式即使有多个消费者同时消费数据,也能保证数据处理的顺序。这种架构描述示意图如下:
发布-订阅消息传递模式
在发布-订阅消息系统中,消息被持久化到一个topic中。与点对点消息系统不同的是,消费者可以订阅一个或多个topic,发布者发送到topic的消息,只有订阅了topic的订阅者才会收到消息,消费者可以消费该topic中所有的数据,同一条数据可以被多个消费者消费,数据被消费后不会立马删除。在发布-订阅消息系统中,消息的生产者称为发布者,消费者称为订阅者。该模式的示例图如下:
1、写消息时允许多个生产者写到同一个Partition中。
2、读消息时一个Partition只允许被一个消费组中的一个消费者所消费,而一个消费者可以消费多个Partition。
3、kafka不会直接把消息传递给消费者,而是在broker中进行存储,为了减少磁盘写入的次数,broker会将消息暂时缓存起来,当消息的个数或尺寸、大小达到一定阀值时,再统一写到磁盘上。
4、kafka中每条消息写到partition中,是顺序写入磁盘的。
5、推荐partition的数量一定要大于同时运行的consumer的数量,partition的数量要小于等于集群broker的数量,这样消息数据就可以均匀的分布在各个broker中。
kafka为什么会存在
上面我们提到kafka是个中间商,我们为什么不能去掉这个中间商呢,凭着我们的想象也会觉得去掉这些消息引擎系统会更好吧,那我们来谈谈消息引擎系统存在的意义:
原因就是“削峰填谷”。这四个字简直比消息引擎本身还要有名气。
所谓的“削峰填谷”就是指缓冲上下游瞬时突发流量,使其更平滑。特别是对于那种发送能力很强的上游系统,如果没有消息引擎的保护,“脆弱”的下游系统可能会直接被压垮导致全链路服务“雪崩”。但是,一旦有了消息引擎,它能够有效地对抗上游的流量冲击,真正做到将上游的“峰”填满到“谷”中,避免了流量的震荡。消息引擎系统的另一大好处在于发送方和接收方的松耦合,这也在一定程度上简化了应用的开发,减少了系统间不必要的交互。
我们想象一下在双11期间我们购物的情景来形象的理解一下削峰填谷,感受一下Kafka在这中间是怎么去“抗”峰值流量的吧:
当我们点击某个商品以后进入付费页面,可是这个简单的流程中就可能包含多个子服务,比如点击购买按钮会调用订单系统生成对应的订单,而处理该订单会依次调用下游的多个子系统服务 ,比如调用支付宝和微信支付的接口、查询你的登录信息、验证商品信息等。显然上游的订单操作比较简单,所以它的 TPS(每秒事务处理量) 要远高于处理订单的下游服务,因此如果上下游系统直接对接,势必会出现下游服务无法及时处理上游订单从而造成订单堆积的情形。特别是当出现类似于秒杀这样的业务时,上游订单流量会瞬时增加,可能出现的结果就是直接压跨下游子系统服务。
解决此问题的一个常见做法是我们对上游系统进行限速,但这种做法对上游系统而言显然是不合理的,毕竟问题并不出现在它那里。所以更常见的办法是引入像 Kafka 这样的消息引擎系统来对抗这种上下游系统 TPS 的错配以及瞬时峰值流量。
还是这个例子,当引入了 Kafka 之后。上游订单服务不再直接与下游子服务进行交互。当新订单生成后它仅仅是向 Kafka Broker 发送一条订单消息即可。类似地,下游的各个子服务订阅 Kafka 中的对应主题,并实时从该主题的各自分区(Partition)中获取到订单消息进行处理,从而实现了上游订单服务与下游订单处理服务的解耦。这样当出现秒杀业务时,Kafka 能够将瞬时增加的订单流量全部以消息形式保存在对应的主题中,既不影响上游服务的 TPS,同时也给下游子服务留出了充足的时间去消费它们。这就是 Kafka 这类消息引擎系统的最大意义所在
https://blog.csdn.net/wudidahuanggua/article/details/127086186
二.windows环境安装kafka
在安装kafka之前需要首先安装jdk
下载地址:www.oracle.com/java/technologies/downloads
安装的目录不要和下载的目录一样
安装完成之后需要配环境变量:
1.在用户变量内新建一个环境变量,变量名:“JAVA_HOME” 变量值:“D:\kafka\jdk-17.0.1” (jdk安装目录)
2.在用户变量中的Path变量,双击打开
新建两个路径:
(1)"%JAVA_HOME%\bin"
(2)"%JAVA_HOME%\jre\bin"
然后点击确认
3.继续在用户变量中新建一个环境变量,变量名:“CLASSPATH”,变量值:“.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar”
以上三步操作好后,窗口全部都点击确认。测试是否安装成功:
在cmd任意路径输入:java -version
出现以下界面说明jdk安装成功:
安装kafka:
1.安装地址:kafka.apache.org/
(windows 安装kafka,建议安装 kafka_2.13-3.2.1.tgz 否则可能会报ERROR Error while writing to checkpoint错误)
2.下载之后解压到安装目录,无需安装
进入到config文件夹里面,找到server.properties文件,进行编辑,找到log.dirs,修改这个参数的路径为:
log.dirs=D:\kafka\kafka_2.13-3.2.1\kafka-logs (安装目录\kefke-log)
kafka-logs自动创建,不用手动创建!
进入到config文件夹里面,找到zookeeper.properties文件,进行编辑,找到dataDir,修改这个参数路径为:D:\kafka\kafka_2.13-3.2.1\zookeeper-data(安装目录\zookeeper-data)
此时kafka已经安装完成
三.启动kafka
1.启动zookeeper
打开cmd,进入kafka安装目录,执行:
.\bin\windows\zookeeper-server-start.bat .\config\zookeeper.properties
如图是zookeeper启动成功:
2.启动kafka
再打开一个cmd,进入kafka安装目录,执行:
.\bin\windows\kafka-server-start.bat .\config\server.properties
如图示kafka启动成功:
四.命令行操作kafka
操作命令首先要切换到kafka的安装包下
1.新增topic
.\bin\windows\kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic topic名
五.python操作kafka
1.查看所有topic
可以通过KafkaConsumer对象查看
from kafka import KafkaConsumer
consumer = KafkaConsumer('test', bootstrap_servers=['localhost:9092'])
'''查看所有topic'''
all_topic = consumer.topics()
print(all_topic)
也可以通过KafkaClient对象查看:
from pykafka import KafkaClient
client = KafkaClient(hosts="127.0.0.1:9092")
for topic in client.topics:
print(topic)
2.给kafka存入信息
from kafka import KafkaProducer
producer = KafkaProducer(bootstrap_servers=['127.0.0.1:9092'])
# 此处ip可以是多个['0.0.0.1:9092','0.0.0.2:9092','0.0.0.3:9092' ]
for i in range(3):
msg = 'msg %d' % i
print(msg)
'''存入时第一个参数是topic名,第二个参数是内容,需要转成utf8编码。当存入的topic不存在时,会自动创建一个'''
producer.send('test',msg.encode('utf8'))
producer.close()
3.查看broker信息
from pykafka import KafkaClient
client = KafkaClient(hosts="127.0.0.1:9092")
print(client.brokers)
for i in client.brokers:
host = client.brokers[i].host
port = client.brokers[i].port
id = client.brokers[i].id
print(host,port,id)
4.直接消费kafka:
from pykafka import KafkaClient
client = KafkaClient(hosts="127.0.0.1:9092")
'''client.topics中包含了各个topic的消息,查看哪个topic的消息在这里选择'''
topic = client.topics['test']
'''consumer中存了很多消息,一条消息就是一个对象'''
consumer = topic.get_simple_consumer(consumer_group="test",reset_offset_on_start=True)
for message in consumer:
print(message)
if message:
print('message.offset',message.offset) # 给队列当中消息的索引,从0开始
print('message.value',message.value) # 消息内容,取出来是二进制