Kafka 入门

kafka 动态扩容现有 topic 的分区数和副本数 之前的 topic 是 1 副本,12 分区,按照之前的 5-1-0-3-2-4 的顺序来分配第一个副本,然后按照 4-3-2-0-1-5 的顺序来分配第二个副本,我这里的 json 文件就命名为:add_rep_test_topic_update.json,大家可以以自己实际来命名。但是观察消费者组的情况,显示的是都消费了,看起来,应该是和 topic 加入新消费者组的情况一样,不展示,但实际消费数据了(这块是个人的理解,具体的原理需要有兴趣的大佬深究一下,希望能赐教带我飞)通过命令查看消费者组的情况。 阅读详情

一、简介

Kafka 是最初由 Linkedin 公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于 zookeeper 协调和发布/订阅模式的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于 hadoop 的批处理系统、低延迟的实时系统、storm/Spark 流式处理引擎,web/nginx 日志、访问日志,消息服务等等,用 scala 语言编写,Linkedin 于2010年贡献给了 Apache 基金会并成为顶级开源项目。

1、Kafka 的特性

kafka 是一个分布式的基于发布订阅模式的消息队列,主要应用于大数据实时处理领域。(kafka 是消费者主动拉取生产者的信息)

1)高吞吐量、低延迟:kafka 每秒可以处理几十万条消息,它的延迟最低只有几毫秒,每个 topic 可以分多个 partition,consumer group 对 partition 进行 consume 操作。

2)可扩展性:kafka 集群支持热扩展。

3)持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失。

4)容错性:允许集群中节点失败(若副本数量为n,则允许 n-1 个节点失败)。

5)高并发:支持数千个客户端同时读写。

2、Kafka 的使用场景

1)日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等。

2)消息系统:解耦和生产者和消费者、缓存消息等。

3)用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。

4)运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。

5)流式处理:比如spark streaming和storm

6)事件源

3、Kafka 的消息

(1)message 状态

在 Kafka 中,消息的状态被保存在 consumer 中,broker 不会关心哪个消息被消费了被谁消费了,只记录一个offset值(指向partition中下一个要被消费的消息位置),这就意味着如果 consumer 处理不好的话,broker 上的一个消息可能会被消费多次。

(2)message 持久化

Kafka 中会把消息持久化到本地文件系统中,并且保持极高的效率。我们众所周知 IO 读取是非常耗资源的性能也是最慢的,这就是为了数据库的瓶颈经常在 IO 上,需要换 SSD 硬盘的原因。但是 Kafka 作为吞吐量极高的 MQ,却可以非常高效的 message 持久化到文件。这是因为 Kafka 是顺序写入o(1)的时间复杂度,速度非常快。也是高吞吐量的原因。由于 message 的写入持久化是顺序写入的,因此 message 在被消费的时候也是按顺序被消费的。一般的机器,单机每秒100k条数据。

(3)message 有效期

Kafka 会长久保留其中的消息,以便 consumer 可以多次消费,当然其中很多细节是可配置的。

4、负载均衡

kafka 集群中的任何一个 broker,都可以向 producer 提供 metadata 信息,这些 metadata 中包含"集群中存活的 servers 列表"/“partitions leader 列表"等信息(请参看zookeeper中的节点信息)。当 producer 获取到 metadata 信息之后,producer 将会和 Topic 下所有 partition leader 保持 socket 连接,消息由 producer 直接通过 socket 发送到 broker,中间不会经过任何"路由层”。

异步发送,将多条消息暂且在客户端 buffer 起来,并将他们批量发送到 broker;小数据IO太多,会拖慢整体的网络延迟,批量延迟发送事实上提升了网络效率;不过这也有一定的隐患,比如当 producer 失效时,那些尚未发送的消息将会丢失。

5、log

每个 log entry 格式为"4个字节的数字N表示消息的长度" + “N个字节的消息内容”,每个日志都有一个 offset 来唯一的标记一条消息,offset 的值为8个字节的数字,表示此消息在此 partition 中所处的起始位置。每个 partition 在物理存储层面,由多个 log file 组成(称为segment)。segment file 的命名为"最小 offset".kafka,例如"00000000000.kafka",其中"最小 offset"表示此 segment 中起始消息的 offset。

获取消息时,需要指定 offset 和最大 chunk 尺寸,offset 用来表示消息的起始位置,chunk size 用来表示最大获取消息的总长度(间接的表示消息的条数)。根据 offset,可以找到此消息所在 segment 文件,然后根据 segment 的最小 offset 取差值,得到它在 file 中的相对位置。直接读取输出即可。
在这里插入图片描述

6、分布式

kafka 使用 zookeeper 来存储一些 meta 信息,并使用了 zookeeper watch 机制来发现 meta 信息的变更并作出相应的动作(比如 consumer 失效,触发负载均衡等)。

1)Broker node registry:当一个 kafka broker 启动后,首先会向 zookeeper 注册自己的节点信息(临时znode),同时当 broker 和 zookeeper 断开连接时,此 znode 也会被删除。

2) Broker Topic Registry:当一个 broker 启动时,会向 zookeeper 注册自己持有的 topic 和 partitions 信息,仍然是一个临时znode。

3) Consumer and Consumer group:每个 consumer 客户端被创建时,会向 zookeeper 注册自己的信息,此作用主要是为了"负载均衡"。一个 group 中的多个 consumer 可以交错的消费一个 topic 的所有 partitions,简而言之,保证此 topic 的所有 partitions 都能被此 group 所消费,且消费时为了性能考虑,让 partition 相对均衡的分散到每个 consumer 上。

4) Consumer id Registry: 每个consumer都有一个唯一的ID(host:uuid,可以通过配置文件指定,也可以由系统生成),此id用来标记消费者信息。

4) Consumer offset Tracking:用来跟踪每个 consumer 目前所消费的 partition 中最大的offset。此 znode 为持久节点,可以看出 offset 跟 group_id 有关,以表明当 group 中一个消费者失效,其他 consumer 可以继续消费。

5) Partition Owner registry:用来标记 partition 正在被哪个 consumer 消费。临时 znode,此节点表达了"一个partition"只能被 group 下一个 consumer 消费,同时当group下某个consumer失效,那么将会触发负载均衡(即:让partitions在多个consumer间均衡消费,接管那些"游离"的partitions)

当 consumer 启动时,所触发的操作:

A) 首先进行"Consumer id Registry";

B) 然后在"Consumer id Registry"节点下注册一个watch用来监听当前group中其他consumer的"leave"和"join";只要此 znode path 下节点列表变更,都会触发此group下consumer的负载均衡(比如一个consumer失效,那么其他consumer接管partitions)。

C) 在"Broker id registry"节点下,注册一个watch用来监听broker的存活情况;如果broker列表变更,将会触发所有的groups下的consumer重新balance。

总结:

(1)Producer 端使用 zookeeper 用来"发现" broker 列表,以及和 Topic 下每个 partition leader建立socket连接并发送消息.

(2)Broker 端使用 zookeeper 用来注册 broker 信息,已经监测partition leader存活性。

(3) Consumer 端使用 zookeeper 用来注册 consumer 信息,其中包括 consumer 消费的 partition 列表等,同时也用来发现 broker 列表,并和 partition leader 建立 socket 连接,并获取消息。

二、Kafka 架构

在这里插入图片描述
上图中一个 topic 配置了 3 个 partition。Partition1 有两个 offset:0和1。Partition2 有 4 个offset。Partition3 有 1 个 offset。副本的 id 和副本所在的机器的 id 恰好相同。
如果一个 topic 的副本数为 3,那么Kafka将在集群中为每个 partition 创建 3 个相同的副本。集群中的每个 broker 存储一个或多个 partition。多个 producer 和 consumer 可同时生产和消费数据。

Kafka 拓扑结构如下:
在这里插入图片描述

分区原因:

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

1、主题 Topic

一个 Topic 可以认为是一类消息,每个 topic 将被分成多个 partition(区),每个 partition 在存储层面是 append log 文件。任何发布到此 partition 的消息都会被直接追加到 log 文件的尾部,每条消息在文件中的位置称为 offset(偏移量),offset 为一个 long 型数字,它是唯一标记一条消息。kafka 并没有提供其他额外的索引机制来存储 offset,因为在 kafka 中几乎不允许对消息进行“随机读写”。

一个主题就是消息的类别或名称。对每个主题,Kafka 集群都管理着一个被分区的日志,如下:
在这里插入图片描述
每个分区就是一个提交日志:每个分区上保存着不断被追加的消息,这些消息是有序的且顺序不可改变;分区上的每个消息都被分配了一个序列号 offset,offset 唯一标识了分区上的消息。

在 kafka 中,即使消息被消费,消息仍然不会被立即删除。日志文件将会根据 broker 中的配置要求,保留一定的时间之后删除。比如 log 文件保留2 天,那么两天后,文件会被清除,无论其中的消息是否被消费。kafka 通过这种简单的手段,来释放磁盘空间,以及减少消息消费之后对文件内容改动的磁盘 IO 开支。

对于 consumer 而言,它需要保存消费消息的 offset,对于 offset 的保存和使用, 由consumer 来控制;当 consumer 正常消费消息时,offset 将会"线性"的向前驱动,即消息将依次顺序被消费。事实上consumer 可以使用任意顺序消费消息,它只需要将 offset 重置为任意值。(offset 将会保存在zookeeper 中)

kafka 集群几乎不需要维护任何 consumer 和 producer 状态信息,这些信息由 zookeeper 保存;因此 producer 和 consumer 的客户端实现非常轻量级,它们可以随意离开,而不会对集群造成额外的影响。partitions的设计目的有多个,最根本原因是 kafka 基于文件存储。通过分区,可以将日志内容分散到多个 server 上,来避免文件尺寸达到单机磁盘的上限,每个 partiton 都会被当前 server(kafka实例)保存;可以将一个topic 切分多任意多个 partitions 来保存消息。此外越多的 partitions 意味着可以容纳更多的 consumer,有效提升并发消费的能力。(具体原理参见下文)。这些特性表明,Kafka 的消费者是非常廉价的,一个消费者的创建、销毁不会对集群或其他消费者产生多大的影响。

对日志进行分区有几个目的:

1)扩容,一个主题可以有多个分区,这使得可以保存比一个机器保存的多的多的数据。

2)并行。

2、Partition

topic 中的数据分割为一个或多个 partition。每个 topic 至少有一个 partition。每个 partition 中的数据使用多个 segment 文件存储。partition 中的数据是有序的,不同 partition 间的数据丢失了数据的顺序。如果 topic 有多个 partition,消费数据时就不能保证数据的顺序。在需要严格保证消息的消费顺序的场景下,需要将 partition 数目设为1。

3、broker

Kafka 集群包含一个或多个服务器,服务器节点称为 broker。
broker 存储 topic 的数据。如果某 topic 有 N 个 partition,集群有 N 个 broker,那么每个 broker 存储该 topic 的一个 partition。
如果某 topic 有 N 个 partition,集群有 (N+M) 个 broker,那么其中有 N 个 broker 存储该 topic 的一个 partition,剩下的 M 个 broker 不存储该 topic 的 partition 数据。
如果某 topic 有 N 个 partition,集群中 broker 数目少于 N 个,那么一个 broker 存储该 topic 的一个或多个 partition。在实际生产环境中,尽量避免这种情况的发生,这种情况容易导致 Kafka 集群数据不均衡。

4、Leader 与 Follower

一个 Topic 的多个 partitions,被分布在 kafka 集群中的多个 server 上,每个 server(kafka 实例)负责 partitions 中消息的读写操作。此外 kafka 还可以配置 partitions 需要备份的个数(replicas),每个 partition 将会被备份到多台机器上,以提高可用性。

基于 replicated(冗余) 方案,那么就意味着需要对多个备份进行调度。每个 partition 都有一个机器为"leader",零个或多个机器作为 follower。如果 leader 失效,那么将会有其他 follower 来接管(成为新的leader)。leader 负责所有的读写操作,follower 执行 leader 的指令。作为 leader 的 server 承载了全部的请求压力,follower 只是单调的和 leader 跟进,同步消息即可。Follower 跟随 Leader,所有写请求都通过 Leader 路由,数据变更会广播给所有 Follower,Follower 与 Leader 保持数据同步。如果 Leader 失效,则从 Follower 中选举出一个新的 Leader。当 Follower 与 Leader 挂掉、卡住或者同步太慢,leader 会把这个 follower 从“in sync replicas”(ISR)列表中删除,重新创建一个 Follower。 从集群的整体考虑,有多少个 partitions 就意味着有多少个"leader",kafka 会将"leader"均衡的分散在每个实例上,来确保整体的性能稳定。

Kakfa Broker Leader的选举:Kakfa Broker集群受Zookeeper管理。所有的Kafka Broker节点一起去Zookeeper上注册一个临时节点,因为只有一个Kafka Broker会注册成功,其他的都会失败,所以这个成功在Zookeeper上注册临时节点的这个Kafka Broker会成为Kafka Broker Controller,其他的Kafka broker叫Kafka Broker follower。(这个过程叫Controller在ZooKeeper注册Watch)。这个Controller会监听其他的Kafka Broker的所有信息,如果这个kafka broker controller宕机了,在zookeeper上面的那个临时节点就会消失,此时所有的kafka broker又会一起去Zookeeper上注册一个临时节点,因为只有一个Kafka Broker会注册成功,其他的都会失败,所以这个成功在Zookeeper上注册临时节点的这个Kafka Broker会成为Kafka Broker Controller,其他的Kafka broker叫Kafka Broker follower。例如:一旦有一个broker宕机了,这个kafka broker controller会读取该宕机broker上所有的partition在zookeeper上的状态,并选取ISR列表中的一个replica作为partition leader(如果ISR列表中的replica全挂,选一个幸存的replica作为leader; 如果该partition的所有的replica都宕机了,则将新的leader设置为-1,等待恢复,等待ISR中的任一个Replica“活”过来,并且选它作为Leader;或选择第一个“活”过来的Replica(不一定是ISR中的)作为Leader),这个broker宕机的事情,kafka controller也会通知zookeeper,zookeeper就会通知其他的kafka broker。

5、Producer

生产者即数据的发布者,该角色将消息发布到 Kafka 的 topic 中。broker 接收到生产者发送的消息后,broker 将该消息追加到当前用于追加数据的 segment 文件中。生产者发送的消息,存储到一个 partition 中,生产者也可以指定数据存储的 partition,这可以通过简单的循环的方式来实现,或者使用一些分区方法(比如根据消息的key来分区)。

6、Consumer 与 Consumer group

在这里插入图片描述
多个consumer(consumer 线程)可以组成一个组(Consumer group ),partition 中的每个 message 只能被组(Consumer group )中的一个consumer(consumer 线程)消费,如果一个message可以被多个consumer(consumer 线程)消费的话,那么这些consumer必须在不同的组。Kafka 不支持一个 partition 中的 message 由两个或两个以上的同一个 consumer group 下的consumer thread来处理,除非再启动一个新的consumer group。所以如果想同时对一个 topic 做消费的话,启动多个consumer group就可以了,但是要注意的是,这里的多个 consumer 的消费都必须是顺序读取 partition 里面的 message,新启动的 consumer 默认从 partition 队列最头端最新的地方开始阻塞的读 message。它不能像 AMQ 那样可以多个 BET 作为 consumer 去互斥的(for update悲观锁)并发处理 message,这是因为多个 BET 去消费一个 Queue 中的数据的时候,由于要保证不能多个线程拿同一条 message,所以就需要行级别悲观锁(for update),这就导致了consume 的性能下降,吞吐量不够。而 kafka 为了保证吞吐量,只允许同一个 consumer group 下的一个 consumer 线程去访问一个 partition。如果觉得效率不高的时候,可以加 partition 的数量来横向扩展,那么再加新的 consumer thread 去消费。如果想多个不同的业务都需要这个 topic 的数据,起多个 consumer group 就好了,大家都是顺序的读取 message,offsite 的值互不影响。这样没有锁竞争,充分发挥了横向的扩展性,吞吐量极高。这也就形成了分布式消费的概念。

当启动一个 consumer group 去消费一个 topic 的时候,无论 topic 里面有多少个 partition,无论我们 consumer group 里面配置了多少个 consumer thread,这个 consumer group 下面的所有 consumer thread 一定会消费全部的 partition;即便这个 consumer group 下只有一个 consumer thread,那么这个 consumer thread 也会去消费所有的 partition。因此,最优的设计就是,consumer group 下的 consumer thread 的数量等于 partition 数量,这样效率是最高的。
一个 consumer group 下,无论有多少个 consumer,这个 consumer group 一定会把这个 topic 下所有的 partition 都消费了。当 consumer group 里面的 consumer 数量小于这个 topic 下的 partition 数量的时候,就会出现一个 conusmer thread 消费多个 partition 的情况,总之是这个 topic 下的 partition 都会被消费。如果 consumer group 里面的 consumer 数量等于这个 topic 下的 partition 数量的时候,此时效率是最高的,每个 partition 都有一个 consumer thread 去消费。当consumer group里面的consumer数量大于这个topic下的partition数量的时候,就会有一个consumer thread空闲。因此,我们在设定 consumer group 的时候,只需要指明里面有几个 consumer 数量即可,无需指定对应的消费 partition 序号,consumer 会自动进行 rebalance。

Consumer Rebalance的触发条件:(1)Consumer增加或删除会触发 Consumer Group的Rebalance(2)Broker的增加或者减少都会触发 Consumer Rebalance

多个 Consumer Group 下的 consumer 可以消费同一条 message,所以一定会重复消费这批 message 的。

如果 producer 的流量增大,为了保证 topic 的 parition 数量 = consumer 数量,这时候的应对方式就是扩展:增加 topic 下的 partition,同时增加这个 consumer group 下的consumer。

三、Kafka 文件存储

1、基本概念

(1)Broker:消息中间件处理结点,一个Kafka节点就是一个 broker,多个 broker 能够组成一个Kafka集群。

(2)Topic:一类消息,比如 page view 日志、click日志等都能够以topic的形式存在。Kafka集群能够同一时候负责多个topic的分发。

(3)Partition:topic物理上的分组。一个topic能够分为多个partition,每一个partition是一个有序的队列。

(4)Segment:partition物理上由多个segment组成。以下有具体说明。

(5)offset:每一个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每一个消息都有一个连续的序列号叫做offset,用于partition中唯一标识的这条消息。

2、topic 中 partition 存储分布

如果实验环境中 Kafka 集群仅仅有一个 broker。xxx/message-folder 为数据文件存储根文件夹。
在 Kafka broker 中的 server.properties 进行文件配置(參数 log.dirs=xxx/message-folder)。比如创建 2 个 topic 名称分别为 report_push、launch_info,partitions 数量都为 partitions=4。

存储路径和文件夹规则为:xxx/message-folder

partiton 中文件存储方式:
在这里插入图片描述
在 Kafka 文件存储中,同一个 topic 下有多个不同 partition,每一个 partition 为一个文件夹,partiton 命名规则为 topic 名称+有序序号,第一个 partiton 序号从0開始,序号最大值为 partitions 数量减1。

如果是多broker分布情况,请參考kafka集群partition分布原理分析

3、partiton中文件存储方式

partition中文件存储方式:
在这里插入图片描述
每一个 partion(文件夹)相当于一个巨型文件被平均分配到多个大小相等 segment (段)数据文件里。
但每一个段 segment file 消息数量不一定相等,这样的特性方便 old segment file 高速被删除(默认情况下每一个文件大小为1G)。
每一个 partiton 仅仅须要支持顺序读写即可了。
segment 文件生命周期由服务端配置參数决定。比如它在默认情况下,每满500兆就会创建新的 segment 段(segment file),每满7天就会清理之前的数据。
这样做的优点就是能高速删除无用文件,有效提高磁盘利用率。

为防止 log 文件过大导致数据定位效率低下,kafka 采取了分片和索引机制,将每个分区分为多个片段(segment),每个 segment 对应两个文件 —— .index 和 .log 文件。

4、partiton 中 segment 文件存储结构

segment file 组成:由2大部分组成,分别为 index file 和 data file,此2个文件一一相应,成对出现,后缀 ”.index” 和 “.log” 分别表示为 segment 索引文件、数据文件。

segment 文件命名规则:partion 全局的第一个 segment 从0开始,每一个 segment 文件名称为上一个 segment 文件最后一条消息的 offset 值。

索引文件(index文件)中存储大量的元数据,而数据文件(log文件)中存储大量的消息。索引文件(index文件)中的元数据指向对应的数据文件(log文件)中消息的物理偏移地址。
在这里插入图片描述

上图的左半部分是索引文件,里面存储的是一对一对的 key-value,其中 key 是消息在数据文件(对应的log文件)中的编号,比如“1,3,6,8……”,分别表示在log文件中的第1条消息、第3条消息、第6条消息、第8条消息……,那么为什么在 index 文件中这些编号不是连续的呢?这是因为 index 文件中并没有为数据文件中的每条消息都建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引,这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。但缺点是没有建立索引的Message也不能一次定位到其在数据文件的位置,从而需要做一次顺序扫描,但是这次顺序扫描的范围就很小了。
其中以索引文件中元数据3,497为例,其中3代表在右边log数据文件中从上到下第3个消息(在全局partiton表示第368772个消息),其中497表示该消息的物理偏移地址(位置)为497。

5、在 partition 中通过 offset 查找 message

比如读取 offset=368776的message,须要通过以下 2 个步骤查找。

(1)第一步查找 segment file
在这里插入图片描述

以上图为例,当中 00000000000000000000.index 表示最还开始的文件,起始偏移量(offset)为0,第二个文件 00000000000000368769.index 的消息量起始偏移量为 368770 = 368769 + 1. 相同,第三个文件 00000000000000737337.index 的起始偏移量为737338=737337 + 1,其它文件依次类推。以起始偏移量命名并排序这些文件,仅仅要依据 offset 二分查找文件列表,就能够高速定位到具体文件。 当 offset=368776 时定位到 00000000000000368769.index|log。

(2)第二步通过 segment file 查找 message

通过第一步定位到 segment file,当 offset=368776 时。依次定位到00000000000000368769.index 的元数据物理位置和 00000000000000368769.log 的物理偏移地址,然后再通过 00000000000000368769.log 顺序查找直到 offset=368776 为止。

segment index file 采取稀疏索引存储方式,它降低索引文件大小。通过 mmap 能够直接内存操作,稀疏索引为数据文件的每一个相应 message 设置一个元数据指针,它比稠密索引节省了很多其它的存储空间,但查找起来须要消耗很多其它的时间。

总结

Kafka高效文件存储设计特点:

(1) Kafka把topic中一个parition大文件分成多个小文件段。通过多个小文件段,就easy定期清除或删除已经消费完文件,降低磁盘占用。

(2)通过索引信息能够高速定位message和确定response的最大大小。

(3)通过index元数据所有映射到memory,能够避免segment file的IO磁盘操作。

(4)通过索引文件稀疏存储,能够大幅降低index文件元数据占用空间大小。

四、Kafka 的可靠性、一致性与幂等性

1、kafka 数据可靠性保证(不丢数据)

为保证 producer 发送的数据,能可靠的发送到指定的 topic,topic 的每个分区收到 producer 发送的数据之后,都需要向 producer 发送acks(acknowledgement 确认收到),如果 producer 没有收到acks,将会重新发送数据,否者进行下一轮发送。

kafka 采用所有副本同步完成之后,才发送acks(这样做延迟高,但是重新选举 leader 时,容忍 n 台节点的故障,只需要 n+1 个副本就可以了)。但是可能出现 leader 收到数据,所有 follower 都开始同步数据,但有一个 follower 因为某种故障,迟迟不能与 leader 通信, leader 将会一直等下去,为了解决这个问题,leader 维护了一个动态的 ISR,表示和 leader保持同步的 follower 集合。当 ISR 中的 follower 完成数据同步之后,leader 就会给 producer 发送 acks,当 ISR 中的 follower 超过 replica.lag.time.max.ms 设置的时间,为没有向 leader 同步数据,则将该 follower 剔除。leader 发生故障后,就会从 ISR 中重新选举leader。

对于某些不太重要的参数,可以容忍数据的少量丢失,所以没必要等到 ISR 中的所有 follower 同步成功。

ack 参数配置:

1) 0:producer 不等待 acks,延迟低,当 broker 出现故障可能丢失数据;

2) 1:producer 等待acks,分区的 leader 写入磁盘成功后返回 acks(只等 leader 写完,不管 follower),若在 follower 同步成功之前 leader 故障,将会丢数据;

3) -1:producer 等待 acks,分区的 leader 和 ISR 中的 follower 全部写入成功才返回 acks,若 follower 同步完成后,broker 发送 acks 之前,leader 故障,将会造成数据重复。

2、kafka 数据一致性(消费者消费和 kafka 存储)

(LEO:指的是每个副本最大的 offset(偏移量),HW:指的是 ISR 队列中最小的 offset,也就是消费者能见到的最大的 offset)

(1)follower 故障:follower 发生故障后会被踢出 ISR 队列,等 follower 恢复后,follower 会读取本地磁盘记录的挂掉之前的 HW,并将 log 文件高于 HW 的截掉,然后从 HW 的位置开始向 leader 同步,等该 follower 的 LED 大于等于该分区的 HW,即 follower 追上 leader 之后,就可以重新加入 ISR 队列了。

(2)leader 故障:leader 发生故障之后,会从 ISR 中选出新的 leader,然后其余的 follower 会先将各自 log 文件高于 HW 的部分截掉,接着从新的 leader 同步数据。

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

3、kafka 的幂等性

kafka 的幂等性指的是无论 producer 发送多少次,broker 只会存储一次。
kafka 中设置 enable.idempotence 设置为 true 时,即可保证幂等性,此时 acks 默认是 -1 。开启幂等性之后,producer 会在初始化的时候分配一个 PID,发往同一个分区的信息会携带一个 seqNumber,而 broker 端会对 <PID, Partiton, SeqNumber> 做缓存,当具有相同的 SeqNumber 消息时,broker 之后保存一条。但是 PID 每次重启都会变化,不同的分区也具有 不同的主键,所有幂等性无法保证跨分区会话的幂等性。

《Kafka系列》Kafka详细教程入门 kafka是分布式的基于消息的发布-订阅的消息队列。LinkedIn(领英),Scala编写的​ kafka消费者在消费数据的时候,一般都是分组的。这个分组叫做消费者组。不同组的消费相互之间不影响。相同组内的消费,同组内的偏移量相互影响;但是需要注意的是,如果你的分区是3个,那么你的消费者组内的消费者最优是3个,因为再多也没有用了,因为组内的消费者,一个消费者消费一个主题的分区。 阅读详情

相关推荐

Kafka从入门到精通

一. MQ基础知识 1. 常见的MQ Kafka, ActiveMQ, RabbitMQ, RocketMQ 在大数据场景下,主要使用Kafka,在javaee中主要采用ActiveMQ, RabbitMQ, RocketMQ 2. MQ作用 (1)削峰 (2)解耦 (3)异步 3. 消息队列的模式 (1)点对点模式 (2)发布订阅模式 二. Kafka基础架构 1. 在同一个消费者组中(每条消息只能被该组中的一个消费者消费),每个分区只能由一个固定消费者进行处理,否则后续很..

JOHN 3705

kafka topic消息分配partition规则

我们知道Kafka 的消息通过topic进行分类。topic可以被分为若干个partition来存储消息。消息以追加的方式写入partition,然后以先入先出的顺序读取。 下面是topic和partition的关系图: 我们一般会在server.conf中通过num.partitions参数指定创建topic时包含多少个partition。默认是num.partitions=1。 既然一个to...

qq_45292079的博客 1703

Kafka快速入门

消息队列(message queue)简称MQ,是一种以“先进先出”的数据结构为基础的消息服务器。消息:两个系统间要传输的数据作用:实现消息的传递原始的数据传递方式:传输效率较低。基于MQ实现消息的传输,如下图所示:上述的数据的传输方式属于异步传输【作为调用方法不用等待被调用方执行完毕就可以接续传递消息】,数据传输的效率较高。services:zookeeper:ports:volumes:services:定义 Docker Compose 文件中的服务。zookeeper。

m0_61925586的博客 9000

kafka分区知识点

概念 topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队;在磁盘上以文件夹的形式存在;消息最终以文件形式保存在partition文件夹下面,分段存储。 segment文件: 对于一个partition(在Broker中以文件夹的形式存在),里面又有很多大小相等的segment数据文件(这个文件的具体大小可以在config/server.properties中log.segment.bytes=XXX属性设置),这种特性可以方便old segment

Markble 4764

unity游戏开发日志(一)将mmd模型导入unity,并解决材质丢失的问题

unity音乐游戏开发,导入角色模型并解决材质问题

yizhigou1的博客 1761

用Matlab和CVX搞定原子范数最小化:一个信号处理小白的避坑实践

本文详细介绍了如何使用Matlab和CVX实现原子范数最小化(Atomic norm minimization),特别适合信号处理初学者。从CVX安装配置、核心代码解析到实战中的典型问题与解决方案,提供了全面的避坑指南。通过具体案例展示了原子范数在频率估计和DOA估计中的优势,并给出性能优化策略和可视化方法。

weixin_28731231的博客 232

Kafka分区机制介绍与示例

原文链接:http://lxw1234.com/archives/2015/10/538.htm Kafka中可以将Topic从物理上划分成一个或多个分区(Partition),每个分区在物理上对应一个文件夹,以”topicName_partitionIndex”的命名方式命名,该文件夹下存储这个分区的所有消息(.log)和索引文件(.index),这使得Kafka的吞吐率可以水

liuxiangke0210的专栏 8385

wps js宏获取工作簿、工作表、单元格的值、链接转图片、单元格区域数据转二维数组、保存工作簿的常用Excel操作

wps js宏入门看这里,我写了常用的js操作Excel的方法:获取工作簿对象、获取工作表对象、获取单元格的值、链接转图片、生成条形码图片、单元格区域数据转二维数组方法、保存工作簿、弹出输入框、YesNo选择框,助你从VBA转战JS。

huaermeier的博客 3万+

kafka(六)——存储策略

kafka通过topic作为主题缓存数据,一个topic主题可以包括多个partition,每个partition是一个有序的队列,同一个topic的不同partiton可以分配在不同的broker(kafka服务器)。

www_dong的博客 2314

告别手动调参!PSCAD 4.2的Multiple-Run功能,5分钟搞定交流故障批量仿真

本文详细介绍了PSCAD 4.2的Multiple-Run功能如何高效处理交流故障批量仿真,告别传统手动调参的低效模式。通过五步配置法,工程师可在5分钟内完成数百次参数组合的仿真,显著提升电力系统分析效率。文章还包含工业级应用案例和高级调试技巧,助力实现故障仿真的自动化与智能化。

weixin_42552716的博客 274

SigFit实战:从FEA到光学仿真的热力耦合分析全流程解析

在光机系统与芯片封装等精密工程领域,热与力的耦合效应是影响产品性能与可靠性的核心物理问题。有限元分析(FEA)是预测结构在热、力载荷下变形与应力的基础工具,但其结果通常无法直接用于评估光学性能。这需要一座桥梁,将物理场数据转化为光学设计语言。其核心原理在于数据映射与面形表征技术,例如通过泽尼克多项式拟合,将离散的节点位移分解为离焦、像散等标准光学像差。这项技术的工程价值在于,它实现了多物理场仿真的闭环,使工程师能在设计阶段精准预测热变形或应力对波前误差、调制传递函数等关键光学指标的影响。其典型应用场景包括高

weixin_28630185的博客 334

Kafka入门实例

摘要:本文主要讲了Kafka的一个简单入门实例

Evankaka的专栏 1万+

Mac上IDEA的PlantUML插件报错‘找不到Graphviz’?手把手教你用Homebrew搞定(附阿里云镜像避坑)

本文详细解决了Mac上IDEA的PlantUML插件报错‘找不到Graphviz’的问题,通过Homebrew安装Graphviz并配置阿里云镜像源,特别针对Apple Silicon芯片用户提供了优化方案。文章还涵盖了IDEA中PlantUML插件的正确配置和常见问题排查,帮助开发者高效使用PlantUML进行UML图表设计。

weixin_42619742的博客 467

Kafka02 - Kafka快速入门

Kafka02 - Kafka快速入门

qq_43350524的博客 1027

电容式麦克风:从原理到实际电路波形解析

本文深入解析电容式麦克风的工作原理,从核心的振膜与背板结构、电荷锁定机制到场效应管放大器的作用。通过实物拆解与等效电路分析,阐明声音振动如何转换为电压信号,并指导如何用示波器实测波形,直观展现声电转换过程,适合电子爱好者和音频技术学习者。

Black的专栏 1078

SQL基础:HQL之常用的行列转换应用总结

行列转换是数据开发者的基本技能,也是面试重点,在数据开发中处处可见,本文对常见的几种情况进行了总结,包括了多行转多列,多行转单列,多列转多行,单列转多行的几种情况,并给出了解决思路和方法,读者可根据本文给出的思路灵活应对业务中遇到的问题。

石榴姐yyds 1799

Kafka入门

Kafka是一个分布式系统,由通过高性能TCP网络协议进行通信的服务器和客户端组成。它可以部署在本地和云环境的裸机硬件、虚拟机和容器上。 服务器:Kafka作为一个或多个服务器的集群运行,可以跨越多个数据中心或云区域。其中一些服务器形成存储层,称为代理。其他服务器运行Kafka Connect以将数据作为事件流持续导入和导出,以及将Kafka与现有的系统(例如关系数据库以及其他kafka集群)集成。为了实现关键任务用例,Kafka集群具有高度可扩展性和容错性:如果其中任何一个服务器出现故障,其他服务器将

qq_45039852的博客 1万+

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Kafka简单入门

介绍什么是事件流式处理以及kafka中的概念、术语和能力

qq_46863837的博客 1477

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

kafka入门学习

消息接收保证成功一次:原子操作加反馈消息接收保证不重复:不保证消息消费保证成功一次:原子操作加反馈消息消费保证不重复:交给redis或mysql。

hsnsnusjs的博客 3423

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

kafka扫盲-入门

Kafka入门指南摘要 Kafka是一款分布式消息引擎与流处理平台,广泛应用于企业消息总线、实时数据管道等场景。该指南从四个方面介绍Kafka:1)基础架构与术语,包括生产者、消费者、Broker等核心组件;2)高吞吐的消息发送机制,详解异步发送、批量处理和重试机制;3)高可用副本机制,阐述ISR集合和Unclean选举原理;4)集群控制器,说明基于Zookeeper的选举过程。文章还包含Kafka的分布式特性、持久化存储等优势分析,以及参数配置建议,为初学者提供了全面的入门知识。

小谷的博客 1429

Kafka入门篇

Kafka入门

小颖同学 1288

头歌educoder-kafka入门篇

头歌educoder-kafka入门篇 第一关kafka-初体验 #!/bin/bash #1.创建一个名为demo的Topic kafka-topics.sh -create --zookeeper 127.0.0.1:2181 --replication-factor 1 --partitions 3 --topic demo #2.查看所有Topic kafka-topics.sh --list --zookeeper 127.0.0.1:2181 #3.查看名为demo的Topic的详情信息 ka

qq_52313093的博客 6042

Kafka 入门学习

Kafka是一个消息中间件,可以降低数据之间的耦合性。常见的消息中间件有:ActiveMQ、RabbitMQ、RocketMQ和Kafka。

weixin_44361163的博客 972
上一篇: Bert 模型学习
下一篇: Java 基础——线程的创建与使用
IT__learning
博客等级 码龄7年 1107粉丝 148原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值