本文已收录在Github仓库,内容包括计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模型、架构、校招社招分享等核心知识点,欢迎star~Github地址:https://github.com/Tyson0314/Java-learningKafka有什么特点?高吞吐低延迟:Kafka每秒可处理数十万条消息,延迟低至几毫秒。每个topic可以分为多个partition,consumergroup消费这些partition。可扩展性:Kafka集群支持热扩持久化,可靠性:消息持久化到本地磁盘,支持数据备份,防止数据丢失容错性:允许集群中的节点发生故障(如果副本数为n,n-1允许节点失效)高并发:支持上千客户端同时读写请简单描述一下您会选择Kafka的场景?日志收集:一个公司可以使用Kafka收集各种服务的日志,通过Kafka作为一个统一的接口服务开放给各种消费者,比如Hadoop、HBase、Solr等。消息系统:与生产者消费者解耦,缓存消息等用户活动跟踪:Kafka常用于记录web用户或app用户的各种活动,如浏览网??页、搜索、点击等活动。这些活动信息由各个服务器发布到Kafka的主题中,然后订阅者订阅这些主题来做实时的监控和分析,或者加载到hadoop或数据仓库中进行离线分析和挖掘。运营指标:Kafka也常用于记录运营监控数据。这包括从各种分布式应用程序收集数据并为各种操作(例如警报和报告)生成集中反馈。流处理:你知道SparkStreaming和FlinkKafka的设计架构吗?Kafka架构分为以下几个部分:Producer:消息生产者是向Kafkabroker发送消息的客户端。Consumer:消息消费者,从kafkabroker中获取消息的客户端。Topic:可以理解为一个队列,一个Topic分为一个或多个分区。ConsumerGroup:Kafka使用它来广播(发送给所有消费者)和单播(发送给任何消费者)主题消息。方法。一个主题可以有多个消费者组。Broker:一个kafka服务器就是一个broker。一个集群由多个代理组成。一个代理可以持有多个主题。Partition:为了实现可伸缩性,可以将一个非常大的topic分布到多个broker上,每个partition是一个有序队列。分区中的每条消息都分配了一个有序的id(偏移量)。Kafka向消费者发送消息时,只保证消息在一个分区中的顺序,而不是一个主题整体(在多个分区之间)的顺序。Offset:Kafka的存储文件都是以offset.kafka命名的。使用偏移量作为名称的好处是它很容易找到。比如你要查找2049的位置,只要找到2048.kafka这个文件即可。当然第一个offset是00000000000.kafka。Kafka分区的目的?分区对于Kafka集群的好处是:实现负载均衡。对于消费者来说,分区可以增加并发,提高效率。你知道Kafka是如何实现消息的顺序的吗?Kafka中每个partition中的消息在写入的时候是有序的,单个partition只能被一个consumer消费,所以在里面可以保证消息的顺序。但是不能保证分区之间的消息是有序的。KafkaProducer的执行过程?1.Producer生产消息-->2.从Zookeeper中找到Partition的Leader-->3.推送消息-->4.通过ISR列表通知Follower-->5.Follower从Leader拉取消息并发送ack->6.Leader收到所有replicas的ack,更新Offset,向Producer发送ack,表示消息写入成功。说一下你用KafkaConsumer消费消息时的线程模型。为什么要这样设计?Thread-Per-ConsumerModel,这种多线程模型利用了Kafka的topic划分多个partition的机制来实现并行:每个线程都有自己的consumer实例,负责消费几个partition。每个线程完全独??立,不涉及任何线程同步和通信,所以实现起来非常简单。请谈谈Kafka的数据一致性原则。Consistencymeansthatconsumerscanreadthesamedataregardlessofwhetheritisanoldleaderoranewlyelectedleader.假设分区的replica为3,其中replica0为leader,replica1和replica2为follower,在ISR列表中。副本0虽然写了Message4,但是Consumer只能读Message2。因为所有ISR都同步Message2,所以Consumers只能读取HighWaterMark以上的消息,而HighWaterMark取决于ISR列表中offset最小的partition,对应上图中的copy2,很像木桶原理。这样做的原因是,没有被足够多的副本复制的消息被认为是“不安全的”,如果领导者崩溃而另一个副本成为新的领导者,那么这些消息很可能会丢失。如果我们允许消费者阅读这些消息,我们可能会破坏一致性。试想一下,消费者从当前领导者(副本0)读取并处理Message4。这时leader挂了,选举copy1为新的leader。这时,另一个消费者读取了新领导者的消息。发现这条消息实际上并不存在,导致数据不一致的问题。当然,引入HighWaterMark机制会导致Brokers之间的消息复制由于某种原因变慢,消息到达消费者的时间也会变长(因为我们会等待消息复制完成第一的)。延迟时间可以通过参数replica.lag.time.max.ms参数进行配置,该参数指定replica在复制消息时允许的最大延迟时间。什么是ISR、OSR和AR?ISR:In-SyncReplicas副本同步队列OSR:Out-of-SyncReplicasAR:AssignedReplicas所有副本ISR都由leader维护,follower从leader同步数据有一定的延迟(见图Kafka副本复制机制的详细信息)。如果超过相应的阈值,follower会从ISR中移除并存入OSR(Out-of-SyncReplicas)列表中,新加入的follower也会先存入OSR中。AR=ISR+OSR。LEO、HW、LSO、LW等代表什么?LEO:是LogEndOffset的缩写,代表当前日志文件中的下一个HW:术语waterlevel或watermark,也称为highwatermark,通常用于流处理领域(如ApacheFlink、ApacheSpark、等),以表示基于时间的元素或事件的进展。在Kafka中,水位的概念与时间无关,而是与位置信息有关。严格来说,它代表的是位置信息,即位移(offset)。将partition对应的ISR中最小的LEO作为HW,consumer在HW所在位置最多只能消费一条信息。LSO:是LastStableOffset的缩写。对于未完成的事务,LSO的值??等于事务中第一条消息的位置(firstUnstableOffset)。对于已完成的交易,其价值与HW相同。LW:LowWatermarkLowWaterlevel,代表AR集合中logStartOffset的最小值。有多少种数据传输交易?数据传输的事务定义通常有以下三个层次:(1)atmostonce:消息不会重复发送,至多一次,但可能不会一次发送(2)atmostonce:消息不会漏掉,至少会被传送一次,但也有可能会被重复传送。(3)Exactlyonce:没有漏传和重传,每条消息都由Kafka传输。消费者是否可以消费指定的分区消息?Kafa消费者在消费消息时,会向broker发送fetch请求来消费特定partition的消息。消费者指定消息在日志中的偏移量(offset),可以从这个位置开始消费消息。客户可以控制偏移量。能够回滚以重新使用以前的消息是有意义的。Kafka消息使用Pull方式还是Push方式?Kafka最初的考虑是客户应该从broker拉取消息还是broker向消费者推送消息,即pull还是push。在这方面,Kafka遵循大多数消息系统通用的传统设计:生产者向代理推送消息,消费者从代理拉取消息。一些消息系统如Scribe、ApacheFlume等采用推送的方式向下游消费者推送消息。这有利也有弊:消息推送的速率由broker决定,对于不同消费速率的消费者来说不太好处理。消息系统致力于让消费者以最快的速率消费消息,但不幸的是,在推送模式下,当broker推送的速率远高于消费者消费的速率时,消费者可能坍塌。最终Kafka选择了传统的pull模式。Pull模式的另一个好处是消费者可以自主决定是否批量从broker拉取数据。Push模式必须在不知道下游消费者的消费能力和消费策略的情况下,决定是每条消息立即推送,还是先缓存后分批推送。如果使用较低的推送速率来避免消费者崩溃,则可能会导致一次推送较少消息的浪费。在Pull模式下,消费者可以根据自己的消费能力来决定这些策略。Pull的缺点是如果broker没有消息可以消费,会导致consumer一直循环轮询,直到有新消息到来。为了避免这种情况,Kafka有一个参数让消费者阻塞直到有新消息到达(当然也可以阻塞直到消息数达到一定数量,这样Kafka就可以批量发送了。高效的文件存储设计特点Kafka将一个topic中的paritionlarge文件分割成多个小文件段,通过多个小文件段,方便定时清除或删除消耗的文件,减少磁盘占用,索引信息可用于快速定位消息并确定响应的最大大小。通过索引元数据将所有映射到内存,可以避免段文件的IO磁盘操作。通过稀疏存储索引文件,可以大大减少索引文件元数据占用的空间。Kafka创建时一个topic,如何在不同的Brokers中放置partition?copyfactor不能大于Brokers的个数;第一个partition(编号0)的第一个副本的放置位置是从brokerList中随机选择的;其他分区的第一个副本的放置位置相对于第0个分区向后移动。即如果我们有5个Broker,5个分区,假设第一个分区放在第四个Broker上,那么第二个分区就会放在第五个Broker上;第三个分区将放在第一个Broker上;第四个分区会放在第二个Broker上,以此类推;剩余副本相对于第一个副本的位置实际上是由nextReplicaShift决定的,这个数字也是随机生成的。说说Kafka中的KafkaRebalancing,当有新的消费者加入或者订阅的topic数量发生变化时,就会触发Rebalance(rebalance:在同一个消费者组中,分区的所有权从一个消费者转移到另一个消费者)机制。Rebalance,顾名思义,就是Rebalance消费者消费。Rebalance的过程如下:第一步:所有成员向协调器发送加入组的请求。一旦所有成员都发送了请求,协调者就会选择一个消费者来担任领导者的角色,并将组成员信息和订阅信息发送给领导者。Step2:leader开始分配消费计划,指定哪个consumer负责消费哪个topic的哪个partition。分配完成后,领导者会将计划发送给协调者。协调器收到分配计划后,会将计划发送给每个消费者,让组内的所有成员都知道应该消费哪些分区。所以对于Rebalance来说,Coordinator起到了至关重要的作用。Kafka是如何实现高吞吐量的?Kafka是一个分布式消息系统,需要处理海量消息。Kafka的设计是将所有消息写入低速大容量的硬盘,以换取更强的存储能力。但实际上,使用硬盘并不会带来过多的性能损失。Kafka主要通过以下方式实现超高吞吐量:顺序读写;零拷贝文件分段发送,压缩数据。卡夫卡的缺点?因为是分批发送,所以数据不是实时的;不支持mqtt协议;不支持直接访问物联网传感器数据;只支持统一分区内的有序消息,无法实现全局消息的有序;监控不完善,需要安装插件;依靠zookeeper进行元数据管理;新老Kafka消费者的区别老Kafka消费者API主要包括:SimpleConsumer(简单消费者)和ZookeeperConsumerConnectir(高级消费者)。SimpleConsumer这个名字看似是一个简单的消费者,但实际操作起来却不是很简单。您可以使用它开始从特定分区和偏移量读取消息。高级消费者有点像新消费者。它具有消费者群体和分区重新平衡。但是它使用ZK来管理消费组,不具备offset和rebalancing的可控性。今天的消费者支持这两种行为,那么为什么要使用旧的消费者API?Kafkapartitions的个数可以增减吗?为什么?我们可以使用bin/kafka-topics.sh命令将Kafka分区数据添加到Kafka中,但是Kafka不支持减少分区数量。Kafka分区数据不支持reduce的原因有很多,比如reduce分区的数据放哪里?删除,还是保留?如果删除它,那么这些未使用的消息将丢失。如何将这些消息保存在其他分区中?如果追加到其他分区,会破坏Kafka单个分区的顺序。如果要保证被删除的分区数据插入到其他分区中以保证有序性,实现逻辑会非常复杂。最后给大家分享一个Github仓库,里面有大斌编译的300多本经典计算机书籍PDF,包括C语言、C++、Java、Python、前端、数据库、操作系统、计算机网络、数据结构还有算法,机器学习,编程生活等等,可以star一下,下次找书的时候可以直接在上面搜索,仓库持续更新中~Github地址:https://github.com/Tyson0314/java-books
