kafka原理架构深入

news2024/9/21 0:24:42

目录

  • 1. 下载安装
  • 2. 命令行命令
  • 3. 概述
    • 3.1 定义
    • 3.2 基本架构
  • 4. 架构深入
    • 4.1 生产者
      • 4.1.1 分区
      • 4.1.2 数据可靠性保证
      • 4.1.3 Exactly Once语义
      • 4.1.4 发送消息流程
    • 4.2 broker
      • 4.2.1 日志结构
      • 4.2.2 存储策略
      • 4.2.3 Controller & ZooKeeper
      • 4.2.4 高效读写数据
    • 4.3 消费者
      • 4.3.1 消费方式
      • 4.3.2 分区分配策略
      • 4.3.3 offset的维护
      • 4.3.4 Eactly Once语义
    • 4.4 拦截器
  • 5. 面试题

1. 下载安装

https://www.cnblogs.com/zhangzhonghui/articles/12444070.html
kafka配置详解
若kafka运行在内网服务器允许外网访问,例如内网ip: 172.10.22.134,外网ip: 9.70.168.130
进行如下配置:

listeners=PLAINTEXT://:9092
advertised.listeners=PLAINTEXT://9.70.168.130:9092

外网访问时使用9.70.168.130:9092访问即可

2. 命令行命令

cd kafka安装目录

cd ~/kafka
  1. 后台启动
# zookeeper
bin/zookeeper-server-start.sh -daemon config/zookeeper.properties
# kafka
bin/kafka-server-start.sh -daemon config/server.properties
  1. 停止
bin/kafka-server-stop.sh
  1. topic
#创建topic
bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic your_topic
# 查看topic
bin/kafka-topics.sh --zookeeper localhost:2181 --list
# 查看特定topic
bin/kafka-topics.sh --zookeeper localhost:2181 --topic your_topic --describe
  1. producer
# 发送数据
bin/kafka-console-producer.sh --broker-list localhost:9092 --topic your_topic
  1. 查看 consumer-groups
# 新版
bin/kafka-consumer-groups.sh --new-consumer --bootstrap-server localhost:9092 --list
# 旧版
bin/kafka-consumer-groups.sh --zookeeper localhost:2181 --list

# 新版特定consumer-groups
bin/kafka-consumer-groups.sh --new-consumer --bootstrap-server localhost:9292 --group YOUR_GROUP_ID --describe

# 旧版特定consumer-groups
bin/kafka-consumer-groups.sh --zookeeper localhost:2181 --group YOUR_GROUP_ID --describe

  1. 开启consumer消费某个topic(从头消费)
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic TOPIC --from-beginning

3. 概述

3.1 定义

Kafka是一个分布式的基于发布/订阅模式的消息队列,主要应用于大数据实时处理领域。Kafka对消息保存时根据Topic进行归类,发送消息者称为Producer,消息接受者称为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。

3.2 基本架构

在这里插入图片描述
在这里插入图片描述
1)Producer :消息生产者,就是向kafka broker发消息的客户端。
2)Consumer :消息消费者,向kafka broker取消息的客户端
3)Topic :可以理解为一个队列。
4) Consumer Group (CG):消费者组,由多个consumer组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
5)Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。
6)Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序。
7)Replica:副本,为保证集群中的某个节点发生故障时,该节点上的partition数据不丢失,且kafka仍然能够继续工作,kafka提供了副本机制,一个topic的每个分区都有若干个副本,一个leader和若干个follower。
8)leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是leader。
9)follower:每个分区多个副本中的“从”,实时从leader中同步数据,保持和leader数据的同步。leader发生故障时,某个follower会成为新的follower。
10)Offset:kafka的存储文件都是按照offset.kafka来命名,用offset做名字的好处是方便查找。例如你想找位于2049的位置,只要找到2048.kafka的文件即可。当然the first offset就是00000000000.kafka

4. 架构深入

4.1 生产者

4.1.1 分区

1)分区的原因

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

2)分区的原则
我们需要将producer发送的数据封装成一个ProducerRecord对象。
在这里插入图片描述

  1. 指明 partition 的情况下,直接将指明的值直接作为 partiton 值;
  2. 没有指明 partition 值但有 key 的情况下,将 key 的 hash 值与 topic 的 partition 数进行取余得到 partition 值;
  3. 既没有 partition 值又没有 key 值的情况下,第一次调用时随机生成一个整数(后面每次调用在这个整数上自增),将这个值与 topic 可用的 partition 总数取余得到 partition 值,也就是常说的 round-robin 算法。

4.1.2 数据可靠性保证

为保证producer发送的数据,能可靠的发送到指定的topic,topic的每个partition收到producer发送的数据后,都需要向producer发送ack(acknowledgement确认收到),如果producer收到ack,就会进行下一轮的发送,否则重新发送数据。
在这里插入图片描述
1)副本数据同步策略

方案优点缺点
半数以上完成同步,就发送ack延迟低选举新的leader时,为了容忍n台节点的故障,需要2n+1个副本
全部完成同步,才发送ack选举新的leader时,容忍n台节点的故障,只需要n+1个副本延迟高

Kafka选择了第二种方案,原因如下:

  1. 同样为了容忍n台节点的故障,第一种方案需要2n+1个副本,而第二种方案只需要n+1个副本,而Kafka的每个分区都有大量的数据,第一种方案会造成大量数据的冗余。
  2. 虽然第二种方案的网络延迟会比较高,但网络延迟对Kafka的影响较小。

2)ISR

采用第二种方案之后,设想以下情景:leader收到数据,所有follower都开始同步数据,但有一个follower,因为某种故障,迟迟不能与leader进行同步,那leader就要一直等下去,直到它完成同步,才能发送ack。这个问题怎么解决呢?

Leader维护了一个动态的in-sync replica set (ISR),即leader保持同步的follower集合。当ISR中的follower完成数据的同步之后,leader就会给follower发送ack。如果follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.lag.time.max.ms参数设定。Leader发生故障之后,就会从ISR中选举新的leader。之前旧版本还有保留 replica.lag.max.messages,但后续被删除了, 因为假如某个时刻数据量很大,follower还没反应过来就被踢了,但follower本身是健康的,这显然是不合理的。

3)ack应答机制

对于某些不太重要的数据,对数据的可靠性要求不是很高,能够容忍数据的少量丢失,所以没必要等ISR中的follower全部接收成功。所以Kafka为用户提供了三种可靠性级别,用户根据对可靠性和延迟的要求进行权衡,选择以下的配置。
acks:

  • 0:producer不等待broker的ack,这一操作提供了一个最低的延迟,broker一接收到还没有写入磁盘就已经返回,当broker故障时有可能丢失数据

  • 1:producer等待broker的ack,partition的leader落盘成功后返回ack,如果在follower同步成功之前leader故障,那么将会丢失数据
    在这里插入图片描述

  • -1(all):producer等待broker的ack,partition的leader和follower全部落盘成功后才返回ack。但是如果在follower同步完成后,broker发送ack之前,leader发生故障,那么会造成数据重复
    在这里插入图片描述
    4)故障处理细节
    在这里插入图片描述
    (1)follower故障
    follower发生故障后会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次的HW,并将log文件高于HW的部分截取掉,从HW开始向leader进行同步。等该follower的LEO大于等于该Partition的HW,即follower追上leader之后,就可以重新加入ISR了。
    (2)leader故障
    leader发生故障之后,会从ISR中选出一个新的leader,之后,为保证多个副本之间的数据一致性,其余的follower会先将各自的log文件高于HW的部分截掉,然后从新的leader同步数据。

注意:这只能保证副本之间的数据一致性,并不能保证数据不丢失或者不重复。数据的不丢失或不重复由ack来决定

4.1.3 Exactly Once语义

对于某些比较重要的消息,我们需要保证exactly once语义,即保证每条消息被发送且仅被发送一次。
在0.11版本之后,Kafka引入了幂等性机制(idempotent),配合acks = -1时的at least once语义,实现了producer到broker的exactly once语义(消费者的exactly once后续再说)。

使用时,只需将enable.idempotence属性设置为true,kafka自动将acks属性设为-1

在Kafka中幂等性指相同的多条数据只会保存一条,那如何确认是相同的数据?kafka中对于每条数据都有个id,id由producerId+SequenceNumber组成,当数据到达kafka后,id将会被暂时缓存起来,若此时producer没有收到ack会重发数据,发现数据跟缓存中的数据id是一致的则不持久化
在这里插入图片描述

Properties props = new Properties();
props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true");
props.put("acks", "all"); // 当 enable.idempotence 为 true,这里默认为 all
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
KafkaProducer producer = new KafkaProducer(props);
producer.send(new ProducerRecord(topic, "test");

4.1.4 发送消息流程

Kafka的Producer发送消息采用的是异步发送的方式。在消息发送的过程中,涉及到了两个线程——main线程和Sender线程,以及一个线程共享变量——RecordAccumulator。main线程将消息发送给RecordAccumulator,Sender线程不断从RecordAccumulator中拉取消息发送到Kafka broker。
在这里插入图片描述
相关参数:

  • batch.size:只有数据积累到batch.size之后,sender才会发送数据。
  • linger.ms:如果数据迟迟未达到batch.size,sender等待linger.time之后就会发送数据。
  • buffer.memory:RecordAccumulator缓冲区大小
package com.atguigu.kafka;

import org.apache.kafka.clients.producer.*;

import java.util.Properties;
import java.util.concurrent.ExecutionException;

public class CustomProducer {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Properties props = new Properties();
        props.put("bootstrap.servers", "hadoop102:9092");//kafka集群,broker-list
        props.put("acks", "all");
        props.put("retries", 1);//重试次数
        props.put("batch.size", 16384);//批次大小
        props.put("linger.ms", 1);//等待时间
        props.put("buffer.memory", 33554432);//RecordAccumulator缓冲区大小
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        Producer<String, String> producer = new KafkaProducer<>(props);
        for (int i = 0; i < 100; i++) {
        	// 同步方式 -- get()
        	// producer.send(new ProducerRecord<String, String>("first", Integer.toString(i), Integer.toString(i))).get();
        	// 异步:不带回调函数
            // producer.send(new ProducerRecord<String, String>("first", Integer.toString(i), Integer.toString(i)));
            // 异步:带回调函数
            producer.send(new ProducerRecord<String, String>("first", Integer.toString(i), Integer.toString(i)), new Callback() {

                //回调函数,该方法会在Producer收到ack时调用,为异步调用
                @Override
                public void onCompletion(RecordMetadata metadata, Exception exception) {
                    if (exception == null) {
                        System.out.println("success->" + metadata.offset());
                    } else {
                        exception.printStackTrace();
                    }
                }
            });
        }
        producer.close();
    }
}

4.2 broker

4.2.1 日志结构

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,每个文件夹下有如下文件:

00000000000000000000.index
00000000000000000000.log
00000000000000170410.index
00000000000000170410.log
00000000000000239430.index
00000000000000239430.log

“.index”文件存储大量的索引信息,“.log”文件存储大量的数据,索引文件中的元数据指向对应数据文件中message的物理偏移地址,index和log文件以当前segment的第一条消息的offset命名
在这里插入图片描述

4.2.2 存储策略

无论消息是否被消费,kafka都会保留所有消息,当然可对消息进行压缩或者删除。
有两种策略可以删除旧数据:
1)基于时间:log.retention.hours=168
2)基于大小:log.retention.bytes=1073741824
需要注意的是,因为Kafka读取特定消息的时间复杂度为O(1),即与文件大小无关,所以这里删除过期文件与提高 Kafka 性能无关。

4.2.3 Controller & ZooKeeper

Kafka集群中有一个broker会被选举为Controller(先到先得),负责管理集群broker的上下线,所有topic的分区副本分配和leader选举等工作,Controller的管理工作都是依赖于Zookeeper的。
以下为partition的leader选举过程:
在这里插入图片描述
(1) 到zookeeper中的brokers/ids/注册节点信息 [0,1,2]
(2) 从ISR中获取选取leader 0,到/brokers/topics/first/partitions/0/state更新 topic的partition信息
(3) leader 0发生故障,通知 /brokers/ids/节点,更新为 [1,2]
(4) Controller监听到节点发生变化,则重新获取ISD,选举新leader,再更新leader及ISR

4.2.4 高效读写数据

1)顺序写磁盘
Kafka的producer生产数据,要写入到log文件中,写的过程是一直追加到文件末端,为顺序写。官网有数据表明,同样的磁盘,顺序写能到到600M/s,而随机写只有100k/s。这与磁盘的机械机构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间。

2) Page Cache
为了优化读写性能,Kafka 利用了操作系统本身的 Page Cache。数据通过mmap内存映射的方式直接写入page cache,定时刷新脏页到磁盘。消费者拉取消息时,如果数据在page cache中,甚至能不需要去读磁盘io。读操作可直接在 Page Cache 内进行。如果消费和生产速度相当,甚至不需要通过物理磁盘(直接通过 Page Cache)交换数据。

3)零拷贝技术
在这里插入图片描述
传统路径:File -> Page Cache -> Application Cache -> Socket Cache -> NIC
Kafka零拷贝过程:File -> Page Cache -> NIC
为啥可以进行零拷贝?因为kafka写进去.log文件的数据就是经过序列化的,读取出来的数据就不要经过用户空间的处理了,减少了不必要的拷贝次数和用户态和内核态的切换,大大减少读取的时延

参考:kafka的零拷贝

4) 分区分段+稀疏索引
Kafka 的 message 是按 topic分 类存储的,topic 中的数据又是按照一个一个的 partition 即分区存储到不同 broker 节点。每个 partition 对应了操作系统上的一个文件夹,partition 实际上又是按照segment分段存储的。通过这种分区分段的设计,Kafka 的 message 消息实际上是分布式存储在一个一个小的 segment 中的,每次文件操作也是直接操作的 segment。为了进一步的查询优化,Kafka 又默认为分段后的数据文件建立了索引文件,就是文件系统上的.index文件。这种分区分段+索引的设计,不仅提升了数据读取的效率,同时也提高了数据操作的并行度。

5) 批量读写
生产者可以借助累加器,批量发送消息,消费者也可以批量拉取消费

4.3 消费者

4.3.1 消费方式

push(推)模式很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的。它的目标是尽可能以最快速度传递消息,但是这样很容易造成consumer来不及处理消息,典型的表现就是拒绝服务以及网络拥塞。而pull模式则可以根据consumer的消费能力以适当的速率消费消息。
所以consumer采用pull(拉)模式从broker中读取数据。
pull模式不足之处是,如果kafka没有数据,消费者可能会陷入循环中,一直返回空数据。针对这一点,Kafka的消费者在消费数据时会传入一个时长参数timeout,如果当前没有数据可供消费,consumer会等待一段时间之后再返回,这段时长即为timeout。

4.3.2 分区分配策略

一个consumer group中有多个consumer,一个 topic有多个partition,所以必然会涉及到partition的分配问题,即确定那个partition由哪个consumer来消费。
Kafka有三种消费者分区分配策略:
1.RoundRobin
2.Range
3.Sticky

kafka在0.11版本引入了Sticky分区分配策略,它的两个主要目的是:

  • 分区的分配要尽可能的均匀,分配给消费者者的主题分区数最多相差一个;
  • 分区的分配尽可能的与上次分配的保持相同。

当两者发生冲突时,第一个目标优先于第二个目标。

参考:kafka的消费者分区分配策略

4.3.3 offset的维护

由于consumer在消费过程中可能会出现断电宕机等故障,consumer恢复后,需要从故障前的位置的继续消费,所以consumer需要实时记录自己消费到了哪个offset,以便故障恢复后继续消费。
Kafka 0.9版本之前,consumer默认将offset保存在Zookeeper中,从0.9版本开始,consumer默认将offset保存在Kafka一个内置的topic中,该topic为__consumer_offsets

4.3.4 Eactly Once语义

需要保证消费数据和提交offset是原子性的

4.4 拦截器

Producer拦截器(interceptor)是在Kafka 0.10版本被引入的,主要用于实现clients端的定制化控制逻辑。
对于producer而言,interceptor使得用户在消息发送前以及producer回调逻辑前有机会对消息做一些定制化需求,比如修改消息等。同时,producer允许用户指定多个interceptor按序作用于同一条消息从而形成一个拦截链(interceptor chain)。Intercetpor的实现接口是org.apache.kafka.clients.producer.ProducerInterceptor,其定义的方法包括:

(1)configure(configs)
获取配置信息和初始化数据时调用。
(2)onSend(ProducerRecord):
该方法封装进KafkaProducer.send方法中,即它运行在用户主线程中。Producer确保在消息被序列化以及计算分区前调用该方法。用户可以在该方法中对消息做任何操作,但最好保证不要修改消息所属的topic和分区,否则会影响目标分区的计算。
(3)onAcknowledgement(RecordMetadata, Exception):
该方法会在消息从RecordAccumulator成功发送到Kafka Broker之后,或者在发送过程中失败时调用。并且通常都是在producer回调逻辑触发之前。onAcknowledgement运行在producer的IO线程中,因此不要在该方法中放入很重的逻辑,否则会拖慢producer的消息发送效率。
(4)close:
关闭interceptor,主要用于执行一些资源清理工作
如前所述,interceptor可能被运行在多个线程中,因此在具体实现时用户需要自行确保线程安全。另外倘若指定了多个interceptor,则producer将按照指定顺序调用它们,并仅仅是捕获每个interceptor可能抛出的异常记录到错误日志中而非在向上传递。这在使用过程中要特别留意。

案例:
在消息发送前将时间戳信息加到消息value的最前部

package com.atguigu.kafka.interceptor;
import java.util.Map;
import org.apache.kafka.clients.producer.ProducerInterceptor;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.RecordMetadata;

public class TimeInterceptor implements ProducerInterceptor<String, String> {

	@Override
	public void configure(Map<String, ?> configs) {

	}

	@Override
	public ProducerRecord<String, String> onSend(ProducerRecord<String, String> record) {
		// 创建一个新的record,把时间戳写入消息体的最前部
		return new ProducerRecord(record.topic(), record.partition(), record.timestamp(), record.key(),
				System.currentTimeMillis() + "," + record.value().toString());
	}
	@Override
	public void onAcknowledgement(RecordMetadata metadata, Exception exception) {

	}

	@Override
	public void close() {

	}
}

主程序

package com.atguigu.kafka.interceptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;

public class InterceptorProducer {

	public static void main(String[] args) throws Exception {
		// 1 设置配置信息
		Properties props = new Properties();
		props.put("bootstrap.servers", "hadoop102:9092");
		props.put("acks", "all");
		props.put("retries", 0);
		props.put("batch.size", 16384);
		props.put("linger.ms", 1);
		props.put("buffer.memory", 33554432);
		props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
		props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
		
		// 2 构建拦截链
		List<String> interceptors = new ArrayList<>();
		interceptors.add("com.atguigu.kafka.interceptor.TimeInterceptor");
		props.put(ProducerConfig.INTERCEPTOR_CLASSES_CONFIG, interceptors);
		 
		String topic = "first";
		Producer<String, String> producer = new KafkaProducer<>(props);
		
		// 3 发送消息
		for (int i = 0; i < 10; i++) {
			
		    ProducerRecord<String, String> record = new ProducerRecord<>(topic, "message" + i);
		    producer.send(record);
		}
		 
		// 4 一定要关闭producer,这样才会调用interceptor的close方法
		producer.close();
	}
}

5. 面试题

  1. Kafka中的ISR、AR又代表什么?
    ISR:与leader保持同步的follower集合
    AR:分区的所有副本

  2. Kafka中的HW、LEO等分别代表什么?
    LEO:没个副本的最后条消息的offset
    HW:一个分区中所有副本最小的offset

  3. Kafka中是怎么体现消息顺序性的?
    每个分区内,每条消息都有一个offset,故只能保证分区内有序。

  4. Kafka中的分区器、序列化器、拦截器是否了解?它们之间的处理顺序是什么?
    拦截器 -> 序列化器 -> 分区器
    但拦截器中主要有两个方法,onSend() 和 onAcknowledgement(),onSend()是在消息被序列化以及计算分区前调用该方法,onAcknowledgement()成功发送到Kafka Broker之后,或者在发送过程中失败时调用

  5. Kafka生产者客户端的整体结构是什么样子的?使用了几个线程来处理?分别是什么?
    两个线程:主线程和sender线程

  6. “消费组中的消费者个数如果超过topic的分区,那么就会有消费者消费不到数据”这句话是否正确?
    正确

  7. 消费者提交消费位移时提交的是当前消费到的最新消息的offset还是offset+1?
    offset+1

  8. 有哪些情形会造成重复消费?
    生产者:ack=-1时,leader和follower同步完成后,broker发送ack之前,leader发生故障,那么会造成数据重复。
    消费者:先消费后提交offset

  9. 那些情景会造成消息漏消费?
    生产者:ack=0,broker还没完成写入 或 ack=-1,leader落盘返回ack,但follower还没完成同步leader就挂了
    消费者:先提交offset,后消费,有可能造成数据的重复

  10. 当你使用kafka-topics.sh创建(删除)了一个topic之后,Kafka背后会执行什么逻辑?
    1)会在zookeeper中的/brokers/topics节点下创建一个新的topic节点,如:/brokers/topics/first
    2)触发Controller的监听程序
    3)kafka Controller 负责topic的创建工作,并更新metadata cache

  11. topic的分区数可不可以增加?如果可以怎么增加?如果不可以,那又是为什么?
    可以增加
    bin/kafka-topics.sh --zookeeper localhost:2181/kafka --alter --topic topic-config --partitions 3

  12. topic的分区数可不可以减少?如果可以怎么减少?如果不可以,那又是为什么?
    不可以减少,被删除的分区数据难以处理(该分区的数据该如何被其他分区消费?如何分配?从哪里开始消费?等一系列难以处理的问题,所以kafka不支持)。

  13. Kafka有内部的topic吗?如果有是什么?有什么所用?
    __consumer_offsets,保存消费者offset

  14. Kafka分区分配的概念?
    一个topic多个分区,一个消费者组多个消费者,故需要将分区分配个消费者(roundrobin、range、Sticky)

  15. 简述Kafka的日志目录结构?
    每个分区对应一个文件夹,文件夹的命名为topic-0,topic-1,内部为.log和.index文件

  16. 聊一聊Kafka Controller的作用?
    负责管理集群broker的上下线,所有topic的分区副本分配和leader选举等工作。

  17. Kafka中有那些地方需要选举?这些地方的选举策略又有哪些?
    partition leader(ISR),controller(先到先得)

  18. 失效副本是指什么?有那些应对措施?
    不能及时与leader同步,暂时踢出ISR,恢复后读取磁盘中持久化的HW,从HW开始消费,等其追上leader之后再重新加入

  19. Kafka的那些设计让它有如此高的性能?
    分区,顺序写磁盘,0-copy

  20. Kafka如何保证Exactly Once语义
    生产者:ack=-1并且开启幂等性,enable.idempotence属性设置为true(该选项会自动将ack设置为-1)
    消费者:保证消费和提交offset是原子性的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/659989.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

模型-视图-控制器模式(MVC模式,10种常见体系架构模式之一)

、简介&#xff1a; 架构模式是一个通用的、可重用的解决方案&#xff0c;用于在给定上下文中的软件体系结构中经常出现的问题。架构模式与软件设计模式类似&#xff0c;但具有更广泛的范围。 模型-视图-控制器模式&#xff0c;也称为MVC模式。是软件工程中的一种软件架构模式&…

Word模板引擎poi-tl

文章目录 ◆ 方案对比◆ 版本◆ 特性◆ 模板◆ 数据◆ 输出◆ 数据模型◆ 标签1. 文本2. 图片3. 表格4. 列表5. 嵌套6. 区块对 ◆ SpingEL2. 单系列图标3. 多系列图标4. 组合图表 ◆ 配置1. 标签前后缀2. 标签类型3. 标签匹配值4. 标签值计算5. SpringEL6. 数据模型序列化7. 错…

设计模式之抽象工厂笔记

设计模式之抽象工厂模式笔记 说明Abstract Factory(抽象工厂)目录UML抽象工厂示例类图甜品抽象类甜品提拉米苏类甜品抹茶慕斯类 咖啡抽象类美式咖啡类拿铁咖啡类 甜品工厂接口美式风味的甜品工厂意大利风味的甜品工厂 测试类模式扩展 说明 记录下学习设计模式-抽象工厂模式的写…

吴恩达471机器学习入门课程3第1周——K-means

K-means 聚类 1 - 实现 K-means1.1 找到最近的质心练习11.2 计算质心均值练习2 2 - K-means在样本数据集上的应用3 - 随机初始化4 - K-means图像压缩4.1 数据集可视化处理数据 4.2图像像素上的 K-mean4.3 压缩图片 实现 K-means 算法&#xff0c;并将其用于图像压缩。 您将从一…

Autoware 跑 Demo(踩坑指南)

Autoware 跑 Demo&#xff08;踩坑指南&#xff09; 网上的博客和官方的教程&#xff0c;几乎都是一样的&#xff0c;但实际上跑不起来 Autoware 1.12学习整理–01–运行rosbag示例 Autoware入门学习&#xff08;三&#xff09;——Autoware软件功能使用介绍&#xff08;1/3&a…

MySQL的IF(exp1, exp2, exp3)、IFNULL(exp1, exp2)函数的用法

本章主要是讲解一下mysql的常用方法if()和ifnull()的使用 1、if(exp1, exp2, exp3) 如果表达式exp1成立&#xff0c;则返回的结果是表达式exp2&#xff0c;否则返回的是表达式exp3 案例&#xff1a;现在有一个星印类型表xingyin_type 通过这个表来介绍一下这个函数的使用 sel…

轻松掌握Seata源码分析之AT模式整体大纲流程跟踪

如下为订单和库存的实例代码&#xff0c;在事务开启处即订单服务处使用GlobalTransactional即可。当添加了异常代码使订单无法加一&#xff0c;这时减库存服务也会回滚&#xff0c;根据的就是undolog。回滚完undolog记录会被释放删除。 AT模式整体大纲流程跟踪如下&#xff1…

第37步 深度学习图像识别:CNN建模(Tensorflow)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;深度学习图像识别的原理 我们思考一下&#xff0c;当你看到一张椅子的图片&#xff0c;你的大脑会告诉你这是个椅子&#xff0c;但你有没有想过&#xff1a;为什么你知道这是椅子&#xff0c;你的大脑是怎么…

【Spring Cloud 系列】Eureka控制台参数说明

【Spring Cloud 系列】Eureka控制台参数说明 前面我们在《Eureka使用详解》一文中介绍了Eureka的使用。本文将介绍Eureka控制板面各参数&#xff1a; System Status 编号名称说明1Environment环境&#xff0c;默认为test&#xff0c;该参数在实际使用过程中&#xff0c;可以不…

单目标应用:Tiki-taka算法(TTA)求解太阳能光伏模型MATLAB

一、四种太阳能光伏模型 随着石油、煤炭、天然气等不可再生能源的快速枯竭&#xff0c;以及空气环境的严重污染&#xff0c;可持续、无污染的能源供应成为热点和关键问题。风能、太阳能、水能、潮汐能等可再生能源的开发利用&#xff0c;必然在未来的可持续发展中发挥至关重要…

德国企业数据统计分析【1】-基于pandas的GENESIS ONLINE数据简单统计与柱状图可视化

引言: 德国拥有很多年销售额不超过50亿美元的中小企业,但他们却是某些细分制造、工业领域的翘楚。并且隐身于大众视野之外。此处,隐形冠军指的就是细分领域行业处于绝对领先地位并且年销售额不超过50亿美元的中小企业。这一概念是由德国著名中小企业管理学家赫尔曼西蒙创立的…

电脑开机密码忘记了怎么办?使用优盘重装系统

大家可以在网上搜索&#xff0c;其他方法。尽量找回密码。我这是因为已经很久没有使用这个电脑&#xff0c;而且c盘也没有怎么重要资料的情况下。我才选择重装系统的。 请慎重。 前期准备&#xff1a; 1、准备一个4G以上的U盘 2、备份U盘重要文件&#xff0c;制作过程中会格式…

「深度学习之优化算法」(五)差分进化算法

1. 差分进化算法简介 &#xff08;以下描述&#xff0c;均不是学术用语&#xff0c;仅供大家快乐的阅读&#xff09; 差分进化算法&#xff08;Differential Evolution Algorithm&#xff0c;DE&#xff09;是一种基于群体的进化算法&#xff0c;它模拟了群体中的个体的合作与竞…

黑马点评短信登录功能

一、基于session实现短信登录 1、发送短信验证码 流程图如下&#xff1a; 1、实现UserController下的sendCode方法&#xff1a; /*** 发送手机验证码*/PostMapping("/code")public Result sendCode(RequestParam("phone") String phone, HttpSession se…

微博粉丝清理工具丨2023年最新粉丝批量清理_微博怎么批量清理粉丝

2023年最新微博怎么批量清理粉丝&#xff1f;可能还有不少小伙伴不太清楚 接下来就为大家带来微博批量清理僵尸粉方法 有需要的朋友可以来了解一下&#xff0c;希望下文可以帮到大家 第一种&#xff1a;客服界面清粉方法 然后在客服中心界面选择修正粉丝; 最后点击一下确认就…

const修饰的成员函数

const修饰的成员函数 问题: 哪里出现编译报错了, 如何修改&#xff1f; class A { public:const int get1() const{a1 10;return a1;}private: int a1 0; }; int main() {A a;a.get1();return 0; }当时以为是a是一个非const对象&#xff0c;调用了const成员函数导致编译错误…

关于guacamole项目中的一点感悟与理解

关于guacamole项目中的一点想法 前言一、guacd模块启动相关二、一些感悟与理解参考 前言 Guacamole 是基于 Web 的 VNC 客户端&#xff0c;使用它可以通过web浏览器访问远程服务器终端并进行操作。它的基本架构如下图所示。 巧合之下&#xff0c;前段时间了解了项目中guacd模块…

构建大数据环境:Hadoop、MySQL、Hive、Scala和Spark的安装与配置

前言 在当今的数据驱动时代&#xff0c;构建一个强大的大数据环境对于企业和组织来说至关重要。本文将介绍如何安装和配置Hadoop、MySQL、Hive、Scala和Spark&#xff0c;以搭建一个完整的大数据环境。 简介 安装Hadoop 首先&#xff0c;从Apache Hadoop的官方网站下载所需的…

测试(一)

1.用户需求 可以简单理解为甲方提出的需求&#xff0c;如果没有甲方&#xff0c;那么就是终端用户使用产品时必须要完成的任务。该需求一般比较简略。 2.软件需求 或者叫功能需求&#xff0c;该需求会详细描述开发人员必须实现的软件功能(所谓的测试文档)。 大多数公司在进行…

05- c语言函数 (C语言)

一 函数的概念 1、在程序设计过程中&#xff0c;为了实现某个功能需要编写多行代码&#xff0c;例如求一个二维数组中的最大值&#xff0c;如果 该功能需要被多次使用&#xff0c;我们可以在每次使用时将原来的代码重复编写&#xff0c;但是这样未免有“凑代码”的嫌疑&#x…