Kafka 核心原理(贼全面)
一、Kafka 概述
1.1 定义
Kafka
是一个分布式的基于发布/订阅模式的消息队列(Message Queue
),主要应用于大数据实时处理领域,处于大数据数据传输层,属于消息中间件
。如AB两个系统需要通信,但并不是直连中间通过消息中间件,还可以实现解耦。
1.2 消息队列
1.2.1 传统消息队列的应用场景
(1)同步处理
整个线程串行,并不高效
(2)异步处理
请求数据写入MQ,并返回响应结果,可以做到解耦,等系统上线时去MQ取数据;还可以缓解服务端的压力(削峰)
(3)使用消息队列的好处
1)解耦
允许独立的拓展或者修改两边的处理过程。只要确保它们遵守同样的接口约束。
2)可恢复性
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
3)缓冲
有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。更多的是解决生产大于消费的问题。
4)灵活性 & 峰值处理能力
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
5)异步通信
很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
1.2.2 消息队列的两种方式
(1)点对点模式
消息生产者生产消息发送到queue
中,然后消息消费者从queue
中取出并且消费消息。消息被消费以后,queue
中不再有存储,所以消息消费者不可能消费到已经被消费的消息。queue
支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。
总结:一对一
,消费者主动拉去数据,消息收到后消息清除。消息不可复用缺点明显
(2)发布/订阅模式
消息生产者(发布)将消息发布到 topic 中,同时有多个消息消费者(订阅)消费该消息。和点对点方式不同,发布到 topic 的消息会被所有订阅者消费。
总结:一对多
,消费者消费数据后不会清除消息,但毕竟是个消息队列不是类似hdfs
的文件存储系统,数据不会无限期的保存,一定时间后会被删除。
分析:对于消费者消费数据有两种方式:消息队列推数据给消费者、消费者主动拉去数据。对于推
这种形式,是由当前队列来决定,下游的消费者可能处理速度不同,例如消费者1消息处理速度为10M/s
,消费者2消息处理速度为100M/s
,但是消息队列推出消息的速度统一为50M/s
,因此消费者1直接崩溃,消费者2造成资源浪费。Kafka
是基于第二种,消费者主动拉取数据,因此消费者的消费速度可以由消费者自己决定。但是这种模式也有一个缺点,消费者主动拉取数据一定要做长轮询
,如果消息队列长时间没有推送数据也会造成一定的资源浪费。
1.3 Kafka 基础架构
1)Producer
:消息生产者,就是向 kafka broker
发消息的客户端
2)Consumer
:消息消费者,向 kafka broker
取消息的客户端
3)Consumer Group (CG)
:消费者组,由多个 consumer
组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者,提高消费能力但一个消费者组理论上不高于一个消息主题的分区个数。
4)Broker
:一台 kafka
服务器就是一个 broker
。一个集群由多个broker
组成。一个broker
可以容纳多个topic
,kafka
的多节点使用的zk
是同一个集群那么就能组成kafka
集群
5)Topic
:可以理解为一个队列,生产者和消费者面向的都是一个 topic
,作用为分类消息。
6)Partition
:为了实现扩展性,一个非常大的 topic
可以分布到多个broker
(即服务器)上,一个 topic
可以分为多个partition
,每个 partition
是一个有序的队列
7)Replica
:副本,为保证集群中的某个节点发生故障时,该节点上的 partition
数据不丢失,且kafka
仍然能够继续工作,kafka
提供了副本机制,一个 topic 的每个分区都有若干个副本,一个 leader
和若干个follower
8)leader
:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是leader
9)follower
:每个分区多个副本中的“从”,实时从 leader
中同步数据,保持和 leader
数据的同步。leader
发生故障时,某个 follower
会成为新的 follower
10)zk
:帮助kafka
集群存储一些信息;帮助消费者存储消费位置信息。0.9
版本后存储在kafka
本地(不是本地磁盘)
1.3.1 总结
首先群起kafka
集群,brocker
相当于一个节点起的一个kafka
进程,消息都是存储在brocker
中,如果只有一个brocker
存储数据容易乱套,如多个生产者生产数据都要使用kafka
会导致消息数据混乱。这时候就需要topic
,相当于把许多消息进行分类,消费者按需求去对应的topic
取消息数据;同一个主题会在不同的brocker
存在,即进行分区,提高某个节点的负载均衡,将来消息数据生产出来,均分给不同节点的相同topic
,一定意义上提高了集群的并发和负载能力;同时一个分区topic
对应一个leader
和一个follower
,这个follower
相当于备份作用提供集群的高可用(只有在leader
挂了才会起作用,正常情况消费者只从leader
取数据),因此同一个分区topic
的leader
和一个follower
必定是在两个不同的节点上,将来leader
所在的节点挂了可以将follower
提升为leader
继续工作。
对于消费者有个消费者组概念,可以把多个消费者用一个组名,同时消费者组有一个特点:一个分区只能被一个组的一个消费者消费,大大提高消费能力,但一个消费者组的消费者个数不能大于一个主题的分区数否则会造成资源的浪费,因此理想的并发度是消费者组的消费者个数等于某个主题的分区数。
对于zk
会帮助kafka
集群存储一些信息,同时在接下来搭建kafka
集群的时候会发现没有所谓hdfs
的namenode
,kafka
集群则是靠使用一个集群的zk
来组成自己的集群,即只要kafka
各个节点使用的zk
是同一个集群,那么我就是一个kafka
集群。
对于消费者最重要的是要实现类似断点续传功能,即一个消费者挂掉重启后还可以接着原来的位置继续消费。在0.9
版本之前将偏移量offset
存储在zk
中,但是0.9
之后将其存储在kafka
中的系统topic
中(本地磁盘,默认存储7天)。why?考虑到消费者既要连接kafka
消费数据同时要实时的向zk
中存储数据,效率低下。
二、Kafka 快速入门
2.1 集群搭建
2.1.1 上传压缩包并解压
tar -zxvf kafka_2.13-2.5.0.tgz
2.13
代表scala
版本,2.5.0
为kafka
版本
2.1.2 修改配置文件
cd kafka_2.13-2.5.0/config/
# The id of the broker. This must be set to a unique integer for each broker
broker.id=0# A comma separated list of directories under which to store log files
log.dirs=/usr/local/soft/kafka_2.13-2.5.0/logs# Zookeeper connection string (see zookeeper docs for details).
# This is a comma separated host:port pairs, each corresponding to a zk
# server. e.g. "127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002".
# You can also append an optional chroot string to the urls to specify the
# root directory for all kafka znodes.
zookeeper.connect=master:2181,slave01:2181,slave02:2181
2.1.3 配置环境变量并分发
分发脚本
#!/bin/bash
#1 获取输入参数个数,如果没有参数,直接退出
pcount=$#
if [ $pcount == 0 ]
thenecho no argsexit
fi
#2 获取文件名称
p1=$1
fname=`basename $p1`
echo fname=$fname#3 获取上级目录到绝对路径
pdir=`cd -P $(dirname $p1); pwd`
echo pdir=$pdir#4 获取当前用户名称
user=`whoami`rsync -rvl $pdir/$fname $user@slave01:$pdir
rsync -rvl $pdir/$fname $user@slave02:$pdir
2.1.4 编写群起脚本
kafka
没有实现类似hdfs
中workers
的群起集群功能,需要我们一个个节点启动(类似zk
),因此需要自己编写群起脚本
#!/bin/bash
pcount=$#
if [ $pcount == 0 ]
thenecho "no args"exit
ficase $1 in
"start"){echo ""echo "—————————————————————————————————————————"for i in master slave01 slave02doecho ""echo " $i start kafka successfully "echo ""ssh $i "/usr/local/soft/kafka_2.13-2.5.0/bin/kafka-server-start.sh -daemon /usr/local/soft/kafka_2.13-2.5.0/config/server.properties"doneecho "—————————————————————————————————————————"echo ""
};;
"stop"){echo ""echo "—————————————————————————————————————————"for i in master slave01 slave02doecho ""echo " $i stop kafka successfully "echo ""ssh $i "/usr/local/soft/kafka_2.13-2.5.0/bin/kafka-server-stop.sh /usr/local/soft/kafka_2.13-2.5.0/config/server.properties"doneecho "—————————————————————————————————————————"echo ""
};;
esac
注意:kafka关闭会有延迟,也就是说关闭后立刻jps可能还能看到kafka进程,稍等一下即可
2.2 Kafka 命令行操作
(1)创建一个主题
kafka-topics.sh --zookeeper master:2181 --create --topic first --partitions 2 --replication-factor 2
因为kafka
集群需要将元数据写入zk
中(0.9
版本后消费者的数据不写入zk
),因此需要连接zk
集群同时指定分区数和副本数(副本数有坑,注意和hdfs
的副本数区分,一会有shell演示),根据配置文件进入logs
文件夹(后面会将日志和消息数据分开),并查看所有节点的logs
文件夹。
first-0 first-1
表示分区数,即kafka
以主题名和分区数对topic
进行命名且以文件夹的形式,纵观三台节点可以发现副本数也是两个。
(2)查看所有的topic
kafka-topics.sh --zookeeper master:2181 --list
(3)查看topic
的详细信息
kafka-topics.sh --zookeeper master --describe --topic firstTopic: first PartitionCount: 2 ReplicationFactor: 2 Configs:Topic: first Partition: 0 Leader: 2 Replicas: 2,0 Isr: 2,0Topic: first Partition: 1 Leader: 0 Replicas: 0,1 Isr: 0,1
可以看出该topic
有2个分区(first-0
,first-1
)和2个副本,其中first-0
在broker.id
为0和2上,且leader
是broker.id
为2的分区;first-1
在broker.id
为0和1上,且leader
是broker.id
为0的分区,图示如下:
(4)删除topic
kafka-topics.sh --zookeeper master:2181 --delete --topic firstTopic first is marked for deletion.
Note: This will have no impact if delete.topic.enable is not set to true.
执行删除的topic
不会立刻删除而是被标记一下,随后才会被删除。
(5)浅谈副本数
在创建topic
时需要指定副本数即replication-factor
,很容易联想到hdfs
的副本数,在hdfs
中副本数可以配置任意值即使超过集群数,它的策略是当增加集群数时会自己拷贝副本数知道达到配置的副本数;在kafka
并不是这样,当创建的副本数大于可用的broker
时会报错,即原先的kafka
集群有三个broker
此时创建三个副本的topic
时不会报错,这时候突然有一个节点宕机原先的topic
不受影响但是随后不能再创建三个副本的topic
,一句话总结就是:hdfs
的副本数是最大副本数,kafka
的就是现在的副本数。
kafka-topics.sh -zookeeper master:2181 --partitions 4 --replication-factor 4Error while executing topic command : Replication factor: 4 larger than available brokers: 3.
[2020-07-30 17:08:06,756] ERROR org.apache.kafka.common.errors.InvalidReplicationFactorException: Replication factor: 4 larger than available brokers: 3.(kafka.admin.TopicCommand$)
但是分区不受影响。
kafka-topics.sh -zookeeper master:2181 --create --topic first--partitions 4 --replication-factor 4
查看topic
的详细信息
Topic: first PartitionCount: 4 ReplicationFactor: 3 Configs:Topic: first Partition: 0 Leader: 2 Replicas: 2,0,1 Isr: 2,0,1Topic: first Partition: 1 Leader: 0 Replicas: 0,1,2 Isr: 0,1,2Topic: first Partition: 2 Leader: 1 Replicas: 1,2,0 Isr: 1,2,0Topic: first Partition: 3 Leader: 2 Replicas: 2,1,0 Isr: 2,1,0
(6)日志数据分离
为了使日志和消息数据分开存储,我们需要将其分离,步骤如下
- 关闭
kafka
集群,删除logs
文件夹 - 进入
zk
删除kafka
相关[除了自己的东西其他全部删除] - 修改配置文件
log.dirs
[这个其实是配置数据的地方] - 启动
kafka
集群
已经实现了日志数据分离的效果,可以通过创建一个topic
来验证一下
(7)控制台测试生产者、消费者
常用命令都放在kafka/bin
中,见名知意可知需要的命令为
kafka-console-consumer.sh
kafka-console-producer.sh
- 生产者测试
生产者直接连接kafka
向指定主题生产数据,因此代码如下:
kafka-console-producer.sh --bootstrap-server master:9092 --topic first
会进入kafka
客户端,等待生产数据
- 消费者测试
上面说过0.9
版本消费者的消费记录存储在kafka
系统维护的主题(一会就能看到),因此消费者的代码也是一样
kafka-console-consumer.sh --bootstrap-server master:9092 --topic first
窗口会进入阻塞状态等待消费数据,此时可以在生产者那随便生产一点数据观察现象
kafka
是基于订阅/发布模式,且消费者消费数据是拉取模式,因此kafka
消息队列即使客户端不在线,当上线时会消费以前的数据(默认消费7天以内),注意:上面的测试代码会读取消费记录,即当重新上线不会重复消费,--from-beginning
参数会从头消费。当新建一个消费者会消费离线时发布的数据,同时查看data
文件可以发现,分区以一种轮换的方式进行。
Kafka 核心原理(贼全面)相关推荐
- Kafka核心设计与实践原理总结:进阶篇
作者:未完成交响曲,资深Java工程师!目前在某一线互联网公司任职,架构师社区合伙人! kafka作为当前热门的分布式消息队列,具有高性能.持久化.多副本备份.横向扩展能力.我学习了<深入理解K ...
- 《深入理解Kafka:核心设计与实践原理》笔误及改进记录
2019年2月下旬笔者的有一本新书--<深入理解Kafka:核心设计与实践原理>上架,延续上一本<RabbitMQ实战指南>的惯例,本篇博文用来记录现在发现的一些笔误,一是给购 ...
- 深入理解Kafka核心设计与实践原理_01
深入理解Kafka核心设计与实践原理_01 01_初识Kafka 1.1 基本概念 1.2 安装与配置 1.3 生产与消费 1.4 服务端参数配置 01_初识Kafka 1.1 基本概念 一个典型的 ...
- redis核心原理与设计思想
redis核心原理与设计思想 一.redis的5种基本数据结构 1.String(字符串) redis字符串扩容策略 2.list(列表) list常用命令 右边进左边出:队列 右边进右边出:栈 快速 ...
- 我挖掘Kafka底层原理!发现了它火爆宇宙的3个真相!
作者:陌北有棵树,一线互联网资深高级JAVA工程师,热爱研究开源技术,架构师社区合伙人! 目前市面上各种中间件层出不穷,我们在做具体的选型时难免会纠结,在这里阐述点粗浅的看法,其实每个中间件在其设计上 ...
- 消息中间件系列(五):MQ消息队列的12点核心原理总结
消息队列已经逐渐成为分布式应用场景.内部通信.以及秒杀等高并发业务场景的核心手段,它具有低耦合.可靠投递.广播.流量控制.最终一致性 等一系列功能. 无论是 RabbitMQ.RocketMQ.Act ...
- 消息中间件系列(二):Kafka的原理、基础架构、以及使用场景
一:Kafka简介 Apache Kafka是分布式发布-订阅消息系统,在 kafka官网上对 kafka 的定义:一个分布式发布-订阅消息传递系统. 它最初由LinkedIn公司开发,Linkedi ...
- kafka监听topic消费_分布式专题|最近一直死磕kafka设计原理,都肝吐了
kafka架构图 kafka核心控制器 定义 在kafka集群中,会选举出一个broker作为控制器(controller),负责管理集群中所有的分区和副本的状态: 职责 监听broker变化,通过监 ...
- 一文搞定Docker(内含docker-compose及docker核心原理)
01-Docker概述 Docker简介 Docker是基于Go语言实现的云开源项目. Docker的主要目标是: Build, Ship and Run Any App, Anywhere ,也就是 ...
最新文章
- gcc c语言标准,GCC 7.1发布 支持当前所有的C ++ 17标准
- ubuntu18.04安装pycharm专业版
- python 标准错误输出_过程的实时标准输出/错误捕获
- mysql练习_创建库与列表、增加列表信息、列表查询(包含多列表查询)_月隐学python第23课
- HashMap jdk1.7源码阅读与解析
- IE 8 下面的垂直水平居中
- excel的ADO读取ORACLE,【VBA研究】利用ADO让普通人用excel读取oracle数据库表的通用办...
- support.SerializationFailedException: Failed to deserialize payload.
- 深度神经网络 轻量化_正则化对深度神经网络的影响
- 【玩转CSS】学成在线(文末素材源码自取)
- matlab遗传算法tsp程序,遗传算法解TSP问题的程序
- 重磅!交叉学科将成我国第14个学科门类
- 研究人员开发实时歌词生成技术以激发歌曲创作灵感
- android 第三方相册,相册选择图片
- python用于cad_使用Python读取AutoCAD DXF文档
- 用心整理10个宝藏APP,涨薪刚需,入股不亏
- APA格式参考文献引用
- BIND配置文件详解(三)
- DXC Technology将收购领先数字创新公司Luxoft
- UI组件Kendo UI for jQuery数据管理入门指南 - TaskBoard/卡片
热门文章
- 2022年Roguelike“割草”游戏风潮为何刮的如此强劲?
- DB 查询分析器 6.04 发布 ,本人为之撰写的相关技术文章达78篇
- linux(centos7)内核升级
- 怎么旋转DIV 45度 要以中心旋转
- geometric distribution and exponential distribution(几何分布和指数分布)
- 美国软件开发实习生月薪排行榜
- 2017年5月问题记录与总结——powerpc p1020 spi flash驱动
- mysqljs基本操作快速上手
- 雷电安卓模拟器修改信息及常用adb命令整理
- python入门实例