kafka

1 篇文章 0 订阅

消息队列(message queue)的概念

消息是在两台计算机之间传递的数据单位,它可以是简单的字符串,也可以是复杂的嵌入对象。消息队列是消息传递过程中有序保存消息的容器,将消息从源头中继到 目标时充当中间人的角色。

 消息队列的作用

 解耦、异步、削峰。

使用场景:
当系统中出现生产和消费的速度和稳定性等因素不一致的时候,使用消息队列,作 为中间层,来弥合双方的差异。
点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
消息生产者生产消息发送到Queue中,然后消息消费者从Queue中取出并且消费消息。
消息被消费以后,queue中不再有存储,所以消息消费者不可能消费到已经被消费的消息。
Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。

 发布/订阅模式(一对多,消费者消费数据之后不会清除消息)

消息生产者(发布)将消息发布到topic中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不同,发布到 topic 的消息会被所有订阅者消费。

 常见的MQ框架

kafka activeMQ rabbitMQ zeroMQ metaMQ rocketMQ 等等。。。

 kafka简介

kafka是由apache软件基金会开发的一个开源流处理框架,由JAVA和scala语言编写。是一个高吞吐量的分布式的发布和订阅消息的一个系统。Kafka® 用于构建实时的数据管道和流式 的app.它可以水平扩展,高可用,速度快,并且已经运行在数千家公司的生产环境。

 基本术语

topic(话题): kafka将消息分门别类,每一类的消息称之 话题 ,是逻辑上的一个概念,如果是真正到磁盘上,映射的是一个 partition(分区) 的一个目录。
生产者( producer): 发布消息的对象称之为生产者,只负责数据的产生,生 产的来源,可以不在kafka集群上,而是来自其他的业务系统。
消费者(consumer): 订阅消息并处理发布消息的对象,称为消费者。
消费者组(consumerGroup): 多个消费者可以构成消费者组,同一个消费者组 的消费者,只能消费一个topic数据,不能重复消费。
broker : kafka本身可以是一个集群,集群中的每一个服务器都是一个代理,这个代理称为broker。只负责消息的存储,不管生产者和消费者,和他们没有任何关系。 在集群中每个broker有唯一个ID,不能重复。

kafka集群的搭建,启动和关闭

搭建kafka集群

在现有cluster1,2,3上搭建
上传kafka压缩包,到linux系统上
解压缩:

 tar -xzvf /root/software/kafka_2.12-2.7.0.tgz -C /usr/

 修改名称:

 mv /usr/kafka_2.12-2.7.0/ /usr/kafka

 配置环境变量:

vim /etc/profile

复制下面内容:
export KAFKA_HOME=/usr/kafka
export PATH=$PATH:$JAVA_HOME/bin:$ZK_HOME/bin:/usr/apache-tomcat-
9.0.52/bin:$KAFKA_HOME/bin

 让配置文件生效:

source /etc/profile

测试:
echo $KAFKA_HOME
进入kafka目录:
cd /usr/kafka
创建目录(存放消息),为后面配置做准备
mkdir logs
修改配置server.properties文件:
vim /usr/kafka/config/server.properties
修改下面内容:
#broker的全局唯一编号,不能重复 21行
broker.id=0
#是否允许删除topic 22行
delete.topic.enable=true
#处理网络请求和响应的线程数量 42行
num.network.threads=3
#用来处理磁盘IO的线程数量 45
num.io.threads=8
#发送套接字的缓冲区大小 48
socket.send.buffer.bytes=102400
#接收套接字的缓冲区大小 51
socket.receive.buffer.bytes=102400
#请求套接字的最大缓冲区大小 54
socket.request.max.bytes=104857600
#kafka运行日志存放的路径 60
log.dirs=/usr/kafka/logs
#topic在当前broker上的分区个数 65
num.partitions=1
#用来恢复和清理data下数据的线程数量 69
num.recovery.threads.per.data.dir=1
#以下配置控制日志段的处理。可以将策略设置为在一段时间后或在给定大小累积后删除段。只要满足这些条件中的*任一*项,就会删除段。删除总是从日志的末尾开始。
#segment文件保留的最长时间,超时将被删除,单位小时,默认是168小时,
也就是7天 103
log.retention.hours=168
#基于大小的日志保留策略。除非剩余的段低于log.retention.bytes,否则将从
日志中删除段。独立于log.retention.hours的功能
#log.retention.bytes=1073741824
#日志段文件的最大大小。当达到此大小时,将创建一个新的日志段。
log.segment.bytes=1073741824
#检查日志段以查看是否可以根据保留策略删除日志段的间隔
log.retention.check.interval.ms=300000
#配置连接Zookeeper地址(集群环境多台机器用逗号分隔) 123
zookeeper.connect=hdcluster1:2181
注意:zookeeper datadir要修改,myid要修改,防火墙要关闭 有问题要重启
因为配置文件中使用的zk主机名称链接,所以配置本地域名:
vim /etc/hosts
完整的hosts:
192.168.206.131 cluster1
192.168.206.132 cluster2
192.168.206.133 cluster3
修改producer.properties:
vim /usr/kafka/config/producer.properties
修改21行为:
bootstrap.servers=cluster1:9092,cluster2:9092,cluster3:9092
修改consumer.properties:
vim /usr/kafka/config/consumer.properties
修改19行为:
bootstrap.servers= cluster1:9092,cluster2:9092,cluster3:9092 
发送配置好的kafka到另外两台机子(先做免密登录)
ssh-keygen -t rsa
ssh-copy-id cluster2
ssh-copy-id cluster3
scp -r /usr/kafka/ cluster2:/usr/
scp -r /usr/kafka/ cluster3:/usr/
检查发送是否成功,在all session执行:
ls /usr
修改broker.id(切记)
cluster 2和 cluster 3上修改broker.id
vim /usr/kafka/config/server.properties
修改21行为
broker.id=1
broker.id=2
发送环境变量配置文件
scp -r /etc/profile cluster2:/etc/
scp -r /etc/profile cluster3:/etc/
在all session执行:
source /etc/profile
echo $KAFKA_HOME
发送hosts配置文件:
scp -r /etc/hosts cluster2:/etc/
scp -r /etc/hosts cluster3:/etc/
测试是否成功:
在all session执行:
cat /etc/hosts

集群的启动和关闭

启动kafka之前一定要保证zk在启动,并且可用:
启动zk:
/root/shelldir/zk-start-stop.sh
测试是否启动:
jps //在all session执行:
启动kafka:
//在all session执行
kafka-server-start.sh -daemon /usr/kafka/config/server.properties
jps (查看java程序进程)
停止kafka:
kafka-server-stop.sh
jps

常用命令

查看当前服务器中的所有topic主题:
kafka-topics.sh --zookeeper cluster1:2181 --list
如果是zk集群可以使用这样的命令:
kafka-topics.sh --zookeeper cluster1:2181,cluster2:2181,cluster3:2181 --list
创建topic: list
kafka-topics.sh --zookeeper cluster2:2181 --create --replication-factor 3 --
partitions 5 --topic ordertopic
kafka-topics.sh --zookeeper cluster2:2181 --create --replication-factor 2 --
partitions 2 --topic goodstopic
参数说明:
--zookeeper 链接zk
--replication-factor 指定副本数目(副本数目不能大于总的brokers数目)
--partitions 指定分区数
--topic 指定topic名称
删除topic:
kafka-topics.sh --zookeeper cluster1:2181 --delete --topic tp3
This will have no impact if delete.topic.enable is not set to true
如果这个配置没有设置为true,则消息是假删除
生产消息:
kafka-console-producer.sh --broker-list cluster2:9092 --topic goodstopic
消费消息:
kafka-console-consumer.sh --bootstrap-server cluster2:9092 --from-beginning --topic goodstopic
同组消费者消费消息(多个窗口):
kafka-console-consumer.sh --bootstrap-server kafka1:9092 --consumer-property group.id=gtest --from-beginning --topic tp1
查看一个topic详情:
kafka-topics.sh --zookeeper cluster2:2181,cluster1:2181 --describe --topic tp1
partitioncount 分区总数量
replicationfactor 副本数量
partition 分区
leader 每个分区有3个副本,每个副本都有leader
replicas 所有副本节点,不管leader follower
isr: 正在服务中的节点

kafka的整体工作流程

Kafka中消息是以 topic 进行分类的,生产者生产消息,消费者消费消息,都是面向topic的。
topic是逻辑上的概念,而 partition 是物理上的概念,每个 partition 对应于一个 log 文件,该
log 文件中存储的就是 producer 生产的数据。 Producer 生产的数据会被不断追加到该log文件末
端,且每条数据都有自己的 offset 。消费者组中的每个消费者,都会实时记录自己消费到了哪
offset ,以便出错恢复时,从上次的位置继续消费。
由于生产者生产的消息会不断追加到log文件末尾,为防止log文件过大导致数据定位效率
低下,Kafka采取了 分片 索引 机制,将每个partition分为多个segment。每个segment对应两
个文件—— “.index” 文件和 “.log” 文件。这些文件位于一个文件夹下,该文件夹的命名规则为:
topic名称+分区序号。例如,first这个 topic 有三个分区,则其对应的文件夹为first -0, first -1, first -2

分区的好处

方便集群的伸缩
每个 Partition 可以通过调整以适应它所在的机器,而一个 topic 又可以有多个 Partition 组成,因此整个集群就可以适应任意大小的数据了
可以提高并发
可以以 Partition 为单位读写,提高集群的读写速度

分区是如何分配到broker上

目的:
1. 保证所有的分区以及副本可以均衡在分布上所有的broker上
2. 保证同一个分区及其副本尽量不要分布在同一个broker上
规则:
让分区和broker进行排序 partition leader排序: p0 p1 p2 p3
                                        partition 副本:           p0r p1r p2r p3r
                                        broker排序:               br0 br1 br2
分区怎么分配到broker上: p0随机一个broker topic越多,每个topic都对应有一个p0
越平均的分配到不同的broker
leader p0->br1 p1->br2 p2 ->br0 p3->br1(p0随机,以后的放入下一 个)
副本随机: p0r->br0 p1r->br1 p2r->br1 p3r->br2
副本(replication)好处
提高kafka的系统的可靠性和稳定性,同一个partitation对应一个或者多个副本,创建topic时就可以设置(--replication-factor 2)。没有副本,一旦当前保存消息的服务器宕 机,就会造成消息丢失,如果有replication,当保存消息的服务器宕机后,从新选举新的leader, 继续进行消息读写,不会造成消息丢失。

zk保存kafka数据的目录结构是什么样子的,在kafka集群中的作用

1,broker在zk中注册:集群启动时,每个broker都会在/brokers/ids/下注册(创临时节点),如果broker挂掉了,zk就会删除该节点。
2,topic会在zk中注册:创建topic时,每个topic都会在/brokers/topics/下注册,topic删除,节点失效。每个broker和topic的对应关系也是由zk进行维护。
3,consumer(消费者)在zk注册:当新的消费者都会zk进行注册,zk在/consumers/consumer-group/ 创建3个节点 ids offsets(偏移量) owners
ids: 记录当前消费者组所有的消费者id
offsets:消费者在消费topic每个partition时,消费到哪个位置(offset 偏移量)
owners:记录该消费者组消费的topic信息(订阅了哪些topic)
新版本无效

生产者如何写入消息的

get /brokers/topics/tpa/partitions/0/state
{"controller_epoch":7,"leader":2,"version":1,"leader_epoch":19,"isr":[2]}
ack=-1/all 讲解画图实例
为保证 producer 发送的数据,能可靠的发送到指定的 topic topic 的每个 partition 收到producer 发送的数据后,都需要向 producer 发送 ack (acknowledgement 确认收到),如果 producer 收到 ack ,就会进行下一轮的发送,否则重新发送数据。

 消息写入时,放入分区的规则:

1, 指定分区 ,直接按照指定分区写入
2, 没有指定分区,但是消息中含有key(一般消息是key value的方式) ,通过key的值进行hash运
算,计算得到一个partition,写入到这个分区。(aaa hash运算后可能得到一个和aaa没有任何
关系的一个数值123132,对分区的总数量取模,根据结果,得到分区)
3, 如果没有指定分区,key都没有,使用轮询 (第一次调用时随机生成一个整数(后面每次调用
在这个整数上自增),将这个值与 topic 可用的 partition 总数取余得到 partition 值,也就是常说的 round-robin 算法),找出一个分区,并写入。

ack应答机制

0 producer不等待broker同步完成的确认,继续发送下一条(批)信息提供了最低的延迟。但是最弱的持久性,当服务器发生故障时,就很可能发生数据丢 失。例如leader已经死亡,producer不知情,还会继续发送消息broker接收不到数据就 会数据丢失
1 producer要等待leader成功收到数据并得到确认,才发送下一条message。此选项提供了较好的持久性较低的延迟性。Partition的Leader死亡,follwer尚未复制,数据就会 丢失
-1/all 意味着producer得到leader和所有follwer确认,才发送下一条数据

ISR(In Sync Replicas):

当ack配置-1时 leader收到数据,所有follower都开始同步数据,但有一个follower,因为某种故障,迟迟不能与leader进行同步,那leader就要一直等下去,直到它完成同步,才能发 送ack。这个问题怎么解决呢?
Leader维护了一个动态的in-sync replica set (ISR),意为和leader保持同步的follower集 合。当ISR中的follower完成数据的同步之后,leader就会给follower发送ack。如果follower长 时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.log.time.max.ms参 数设定。Leader发生故障之后,就会从ISR中选举新的leader。

消费者消费要点

消息的消费模式有两种: 推送模式(push) 和拉取模式(pull)
kafka采取的拉取模式(pull),由消费者自己记录消费状态(消费者自己记录自己的消费位置
(offset偏移量)),每个消费者相互独立的消费每个一个分区的消息。每个消费者消费完了后,
对消息本身不做任何处理,决定该消息是否能被删除,跟消费者没有任何关系,与配置的消息过
期时间和消息总容量的大小配置参数有关( log.retention.hours=168 log.retention.bytes=1G )。
消费者是以消费者组( consumer group)的方式,由一个或者多个消费者组成一个组,共同消费一个topic(主题),在同一时刻,只能由同一个组的一个消费者去消费同一个分区。
pull模式不足之处是,如果kafka没有数据,消费者可能会陷入循环中,一直返回空数据。
针对这一点,Kafka的消费者在消费数据时会传入一个时长参数timeout,如果当前没有数据可供消费,consumer会等待一段时间之后再返回,这段时长即为timeout。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值