长期整合常面试考点,喜欢的可以收藏。Java面试题目大纲导航
整合kafka相关的知识点。
【版权所有,文章不得已任何形式转载,违者必究】
Kafka可以代替传统的消息队列软件(阿里的队列软件RocketMQ就是基于Kafka实现的),稳定性强、分布式容灾好、数据量不会影响到KafKa的速度等优点,在队列软件的选择上Kafka已经成了不二之选。
Kafka可以为外部系统提供一种持久性日志的分布式系统。日志可以在多个节点间进行备份,Kafka为故障节点数据恢复提供了一种重新同步的机制。同时,Kafka很方便与HDFS和Flume进行整合,这样就方便将Kafka采集的数据持久化到其他外部系统。
为了更好地了解用户行为、操作习惯,改善用户体验,进而对产品升级改进,将用户操作轨迹、内容等信息发送到Kafka集群上,通过Hadoop、Spark或Strom等进行数据分析处理,生成相应的统计报告,为推荐系统推荐对象建模提供数据源,进而为每个用户进行个性化推荐。
Kafka中消息处理一般包含多个阶段,其中原始输入数据是从Kafka主题中消费,然后汇总处理,或者以其他的方式处理转化为新主题。例如,一个推荐新闻文章,文章内容可能从某个主题获取。然后进一步处理内容,得到一个处理后的新内容,最后推荐给用户。这种处理是基于单个主题的实时数据流,从0.10.0.0开始。
利用Kafka采集应用程序和服务器健康相关的指标,如CPU占用率、IO、内存、连接数、TPS、QPS 等,然后将指标信息进行处理,从而构建一个具有监控仪表盘、曲线图等可视化监控系统。例如,很多公司采用Kafka与ELK(ElasticSearch、Logstash 和 Kibana)整合构建应用服务监控系统。
这里的概念部分信息参照Kafka基础知识;震惊了!原来这才是 Kafka!(多图+深入)
生产者,负责发布消息到Broker
创建一条记录,记录中一个要指定对应的topic和value,key和partition可选。
先序列化,然后按照topic和partition,放进对应的发送队列中。kafka
produce都是批量请求,会积攒一批,然后一起发送,不是调send()就进行立刻进行网络发包。
- 如果partition没填,那么情况会是这样的:
key有填 按照key进行哈希,相同key去一个partition。(如果扩展了partition的数量那么就不能保证了)
key没填 round-robin来选partition这些要发往同一个partition的请求按照配置,攒一波,然后由一个单独的线程一次性发过去。
消费者,负责从Broker中读取消息。
若干个Consumer组成的集合,每个Consumer属于一个特定的Consumer Group。每个Consumer可指定Group Name,若不指定,则属于默认的Group。
一台 Kafka 服务器就是一个Broker,一个集群由多个Broker组成, 一个 Broker可以容纳多个Topic。
Zookeeper 选出来的broker,它维护leader/follower信息
每条发布到 Kafka 集群的消息都有一个类别,这个类别被称为 Topic。
而topic是一个逻辑概念,实际写入partition。每个主题至少有一个分区,主题只是一组命名的分区,而分区才是实际上的数据流。应用通常只向主题发送或订阅消息,每个分区内部消息是有序的,通过 offset 维护消息序号。
相关链接 kafka中的topic为什么要进行分区?
物理上的概念,每个 Topic 包含一个或多个 Partition
一个Partition在服务器上对应的是一个具体的文件目录,目录下存放的是消息文件和索引文件。一个Topic可以分为多个Partition,每个Partition是一个有序的队列且都有一个Leader。
Partitions & Consumer
消费者需要知道应该处理哪个分区上的数据[from Zookeeper(topic) and Brokers(leader)],以便相同消费群组中的消费者互不干扰。对于每个消费群组包含的消费者数量需小于分区数量,否则有些消费者将没有分区可以处理。为了均衡消费者的处理能,通常将分区数量配置为消费者的整数倍。
相关链接 解析Kafka中的 Topic 和 Partition
Kafka还将Partition进一步分割成多个段(Segment),一个段对应一个服务器上的log文件。这样分割好处就是在清理过期的消息时,可以对整个段的文件作删除操作,从而避免对文件的随机写操作,提高吞吐量。
Kafka中同一条消息能够被拷贝到多个地方以提供数据冗余,副本分为领导者副本和追随者副本,副本在分区的层级下,每个分区可配置多个副本实现高可用。
Kafka为每条在分区的消息保存一个偏移量offset,这也是消费者在分区的位置。比如一个偏移量是5的消费者,表示已经消费了从0-4偏移量的消息,下一个要消费的消息的偏移量是5。
当一些原因导致Consumer对Partition消费不再均匀时,或者消费者组内某个消费者实例挂掉后,Kafka 会自动执行Reblance,使得Consumer对Partition的消费再次平衡。重平衡是Kafka消费者端实现高可用的重要手段。
在业务中,常常都是使用At least once的模型,整体的消息投递语义需要Producer端和Consumer端两者来保证。
此处笔记,参照链接 再过半小时,你就能明白kafka的工作原理了 ,侵权删
上面介绍了kafka的基础架构及基本概念,不知道大家看完有没有对kafka有个大致印象,如果对还比较懵也没关系!我们接下来再结合上面的结构图分析kafka的工作流程,最后再回来整个梳理一遍我相信你会更有收获!
我们看上面的架构图中,producer就是生产者,是数据的入口。注意看图中的红色箭头,Producer在写入数据的时候永远的找leader,不会直接将数据写入follower!那leader怎么找呢?写入的流程又是什么样的呢?我们看下图:
发送的流程就在图中已经说明了,就不单独在文字列出来了!需要注意的一点是,消息写入leader后,follower是主动的去leader进行同步的!producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的!写入示意图如下:
上面说到数据会写入到不同的分区,那kafka为什么要做分区呢?相信大家应该也能猜到,分区的主要目的是:
- 1、 方便扩展。因为一个topic可以有多个partition,所以我们可以通过扩展机器去轻松的应对日益增长的数据量。
- 2、 提高并发。以partition为读写单位,可以多个消费者同时消费数据,提高了消息的处理效率。
熟悉负载均衡的朋友应该知道,当我们向某个服务器发送请求的时候,服务端可能会对请求做一个负载,将流量分发到不同的服务器,那在kafka中,如果某个topic有多个partition,producer又怎么知道该将数据发往哪个partition呢?kafka中有几个原则:
- 1、 partition在写入的时候可以指定需要写入的partition,如果有指定,则写入对应的partition。
- 2、 如果没有指定partition,但是设置了数据的key,则会根据key的值hash出一个partition。
- 3、 如果既没指定partition,又没有设置key,则会轮询选出一个partition。
保证消息不丢失是一个消息队列中间件的基本保证,那producer在向kafka写入消息的时候,怎么保证消息不丢失呢?其实上面的写入流程图中有描述出来,那就是通过ACK应答机制!在生产者向队列写入数据的时候可以设置参数来确定是否确认kafka接收到数据,这个参数可设置的值为0、1、all。
- 0代表producer往集群发送数据不需要等到集群的返回,不确保消息发送成功。安全性最低但是效率最高。
- 1代表producer往集群发送数据只要leader应答就可以发送下一条,只确保leader发送成功。
- all代表producer往集群发送数据需要所有的follower都完成从leader的同步才会发送下一条,确保leader发送成功和所有的副本都完成备份。安全性最高,但是效率最低。
最后要注意的是,如果往不存在的topic写数据,能不能写入成功呢?kafka会自动创建topic,分区和副本的数量根据默认配置都是1。(需要开启auto.create.topics.enable=true)
Producer将数据写入kafka后,集群就需要对数据进行保存了!kafka将数据保存在磁盘,可能在我们的一般的认知里,写入磁盘是比较耗时的操作,不适合这种高并发的组件。Kafka初始会单独开辟一块磁盘空间,顺序写入数据(效率比随机写入高)。
前面说过了每个topic都可以分为一个或多个partition,如果你觉得topic比较抽象,那partition就是比较具体的东西了!Partition在服务器上的表现形式就是一个一个的文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件(早期版本中没有)三个文件, log文件就实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息。
如上图,这个partition有三组segment文件,每个log文件的大小是一样的,但是存储的message数量是不一定相等的(每条的message大小不一致)。文件的命名是以该segment最小offset来命名的,如000.index存储offset为0~368795的消息,kafka就是利用分段+索引的方式来解决查找效率的问题。
上面说到log文件就实际是存储message的地方,我们在producer往kafka写入的也是一条一条的message,那存储在log中的message是什么样子的呢?消息主要包含消息体、消息大小、offset、压缩类型……等等!我们重点需要知道的是下面三个:
1、 offset:offset是一个占8byte的有序id号,它可以唯一确定每条消息在parition内的位置!
2、 消息大小:消息大小占用4byte,用于描述消息的大小。
3、 消息体:消息体存放的是实际的消息数据(被压缩过),占用的空间根据具体的消息而不一样。
无论消息是否被消费,kafka都会保存所有的消息。那对于旧数据有什么删除策略呢?
1、 基于时间,默认配置是168小时(7天)。
2、 基于大小,默认配置是1073741824。
需要注意的是,kafka读取特定消息的时间复杂度是O(1),所以这里删除过期的文件并不会提高kafka的性能!
消息存储在log文件后,消费者就可以进行消费了。在讲消息队列通信的两种模式的时候讲到过点对点模式和发布订阅模式。Kafka采用的是点对点的模式,消费者主动的去kafka集群拉取消息,与producer相同的是,消费者在拉取消息的时候也是找leader去拉取。
多个消费者可以组成一个消费者组(consumer group),每个消费者组都有一个组id!同一个消费组者的消费者可以消费同一topic下不同分区的数据,但是不会组内多个消费者消费同一分区的数据!!!是不是有点绕。我们看下图:
图示是消费者组内的消费者小于partition数量的情况,所以会出现某个消费者消费多个partition数据的情况,消费的速度也就不及只处理一个partition的消费者的处理速度!如果是消费者组的消费者多于partition的数量,那会不会出现多个消费者消费同一个partition的数据呢?上面已经提到过不会出现这种情况!多出来的消费者不消费任何partition的数据。所以在实际的应用中,建议消费者组的consumer的数量与partition的数量一致!
在保存数据的小节里面,我们聊到了partition划分为多组segment,每个segment又包含.log、.index、.timeindex文件,存放的每条message包含offset、消息大小、消息体……我们多次提到segment和offset,查找消息的时候是怎么利用segment+offset配合查找的呢?假如现在需要查找一个offset为368801的message是什么样的过程呢?我们先看看下面的图:
1、 先找到offset的368801message所在的segment文件(利用二分法查找),这里找到的就是在第二个segment文件。
2、 打开找到的segment中的.index文件(也就是368796.index文件,该文件起始偏移量为368796+1,我们要查找的offset为368801的message在该index内的偏移量为368796+5=368801,所以这里要查找的相对offset为5)。由于该文件采用的是稀疏索引的方式存储着相对offset及对应message物理偏移量的关系,所以直接找相对offset为5的索引找不到,这里同样利用二分法查找相对offset小于或者等于指定的相对offset的索引条目中最大的那个相对offset,所以找到的是相对offset为4的这个索引。
3、 根据找到的相对offset为4的索引确定message存储的物理偏移位置为256。打开数据文件,从位置为256的那个地方开始顺序扫描直到找到offset为368801的那条Message。
这套机制是建立在offset为有序的基础上,利用segment+有序offset+稀疏索引+二分查找+顺序查找等多种手段来高效的查找数据!至此,消费者就能拿到需要处理的数据进行处理了。那每个消费者又是怎么记录自己消费的位置呢?在早期的版本中,消费者将消费到的offset维护zookeeper中,consumer每间隔一段时间上报一次,这里容易导致重复消费,且性能不好!在新的版本中消费者消费到的offset已经直接维护在kafk集群的__consumer_offsets这个topic中!
Kafka集群搭建与SpringBoot项目集成
SpringBoot集成kafka全面实战
Kafka基础知识
Kafka学习笔记
震惊了!原来这才是 Kafka!(多图+深入)
kafka解决了什么问题
再过半小时,你就能明白kafka的工作原理了★★★★★
Kafka 基本原理(8000 字小结)
Kafka零拷贝
Kafka如何实现每秒上百万的超高并发写入?掌握好面试给你打满分
Kafka史上最详细原理总结 ----用于自己看的★★★★★
Kafka 设计与原理详解
消息队列Kafka、RocketMQ、RabbitMQ的优劣势比较
Kafka深度解析★★★★★
1、kafka 需要java环境;
2、kafka 最新版本内置了 zookeeper,所以不需要安装zookeeper;
3、下载kafka最新版本,点击下载,因为下载的是tgz文件,所以不需要安装,解压到相应的地方就可以了。
4、bin 目录下放的是启动kafka的文件,conf目录下放的是kafka的各种配置文件。
运行
简单demo测试,不需要修改任何配置文件,只需要知道 zookeeper的默认端口是2181,生产者的默认端口是9092。
1、启动zookeeper
2、启动kafka
bin\windows\kafka-server-start.bat config\server.properties
遇到:windows下kafka启动报错,找不到或无法加载主类
Files\Java\jdk1.8.0_191\lib\dt.jar;C:\Program
- 解决方案\bin\windows里面的kafka-run-class,修改大约在179行(notepad打开的话在179行),就是在后面%CLASSPATH%“加上英文双引号”%CLASSPATH%
set COMMAND=%JAVA% %KAFKA_HEAP_OPTS% %KAFKA_JVM_PERFORMANCE_OPTS% %KAFKA_JMX_OPTS% %KAFKA_LOG4J_OPTS% -cp "%CLASSPATH%" %KAFKA_OPTS% %*
windows下kafka常用命令行
1.启动/关闭zookeeper
.\windows\zookeeper-server-start.bat ..\config\zookeeper.properties .\windows\zookeeper-server-stop.bat ..\config\zookeeper.properties
2.启动/关闭kafka
.\windows\kafka-server-start.bat ..\config\server.properties .\windows\kafka-server-stop.bat ..\config\server.properties
3.消费消息
.\windows\kafka-console-consumer.bat --bootstrap-server localhost:9092 --from-beginning --topic test
4.创建消息
.\windows\kafka-console-producer.bat --broker-list localhost:9092 --topic test
5.创建topic
.\windows\kafka-topics.bat --create -zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
6.删除topic
.\windows\kafka-topics.bat — zookeeper localhost:2181 --delete --topic test
7.查询topic列表
.\windows\kafka-topics.bat --list --zookeeper localhost:2181
kafka介绍和使用
Kafka linux 安装步骤