惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
V
V2EX
G
Google Developers Blog
F
Full Disclosure
Martin Fowler
Martin Fowler
宝玉的分享
宝玉的分享
H
Hacker News: Front Page
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
NISL@THU
NISL@THU
G
GRAHAM CLULEY
V
Vulnerabilities – Threatpost
Hacker News - Newest:
Hacker News - Newest: "LLM"
A
About on SuperTechFans
The Cloudflare Blog
C
Cisco Blogs
D
DataBreaches.Net
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Vercel News
Vercel News
P
Privacy International News Feed
Microsoft Security Blog
Microsoft Security Blog
Help Net Security
Help Net Security
Recorded Future
Recorded Future
PCI Perspectives
PCI Perspectives
S
Schneier on Security
AI
AI
N
News | PayPal Newsroom
雷峰网
雷峰网
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Proofpoint News Feed
The Last Watchdog
The Last Watchdog
L
LINUX DO - 最新话题
Hugging Face - Blog
Hugging Face - Blog
Apple Machine Learning Research
Apple Machine Learning Research
Schneier on Security
Schneier on Security
S
Securelist
云风的 BLOG
云风的 BLOG
Stack Overflow Blog
Stack Overflow Blog
博客园_首页
AWS News Blog
AWS News Blog
TaoSecurity Blog
TaoSecurity Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Commits to openclaw:main
Recent Commits to openclaw:main
博客园 - 三生石上(FineUI控件)
C
CXSECURITY Database RSS Feed - CXSecurity.com
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Cloudbric
Cloudbric
C
Cybersecurity and Infrastructure Security Agency CISA
Project Zero
Project Zero
C
Check Point Blog
S
Security Affairs

祈雨的笔记

安全多方计算MPC spark原理解析 kueue执行源码分析 spark on k8s执行源码分析 spark-operator源码解析 系统压测遇到的缓存击穿问题 我的世界PC与安卓联机 蚂蚁金服流量投放平台的AIG改造 G1大对象致Old区占用率高 日志打印导致接口响应率下跌分析 Groovy加载类导致OOM分析 ERROR日志打印导致CPU满载 记OceanBase死锁超时 应用发版期间服务响应超时 Ark Serverless初探 系统优化复盘一二三 The user specified as a definer does not exist Kong网关初探 API网关选型调研 CPU火焰图常用工具 配置中心选型调研 root操作Nginx导致用户组错误 基于Proxifier使用代理 FastJSON字段智能匹配踩坑 Nacos初探 记一次Nginx服务器CPU满荷载故障 基于券系统分库分表的思考 limit不参与SQL成本计算致索引失效 Linux常用性能监控命令 golang低版本http2偶现400 hostname in certificate didn't match 常见对称加密原理以及应用 tcp_tw_recycle引起的TCP握手失败 记一次mysql执行DDL导致锁表 mysql磁盘占用查看 mysql对text字段update致磁盘增长 elasticsearch报错index read-only TIME_WAIT与Http的Keep-Alive 记一次TIME_WAIT导致连接数报警 记一次生产事故OOM问题排查 redis分布式锁RedissonLock的实现细节 webservice复杂加密签名(2)java调用 webservice复杂加密签名(1)SoapUI mysql延时关联 利用中间人拦截实现APP内H5窜改 MySQL表字符集不同导致关联查询索引失效 通过SSH隧道远程办公 数据落盘方案 BeanDefinitionRegistryPostProcessor扩展 mysql空间索引 HTTPS攻击 spring循环依赖过程解析 elasticsearch性能优化 mysql IS NULL 使用索引 mysql字符集utf8mb4失效踩坑 常用加密算法 xml与javaBean转换 初探InnoDB MVCC源码实现 mysql索引原理 redis之list源码分析 redis之key过期源码分析 redis之string源码分析 redis之hash源码分析 线程池之ThreadPoolExecutor mysql数据页结构 Using temporary与Using filesort mysql回表致索引失效 springboot(28)HTTP连接池 定时任务之ScheduledThreadPoolExecutor elasticsearch常用script聚合 elasticsearch实现like查询 elasticsearch实现乐观锁 elasticsearch准实时原理 springboot(27)自定义缓存读写机制CachingConfigurerSupport optimizer tracing arthas常用命令 HTTP和HTTPS详解 redis集群选举机制 kafka消息重试 一点压力测试的经验 explain分析sql语句字段的解释 JVM问题分析处理手册 logstash过滤器(2)date logstash过滤器(3)dissect logstash编码器(1)json logstash编码器(2)multiline logstash表达式 logstash输入(1)通用选项 logstash输入(3)file logstash过滤器(1)通用选项 logstash输入(2)stdin logstash安装 记一次前端vConsole导致JSON序列化错误排查 解决多个异步操作嵌套问题 fastjson反序列化失败autoType is not support RTMP串流服务 POI自动调整列宽错误 Nginx+Lua实现动态黑名单 使用curl命令模拟POST和GET请求 ResponseEntity下载文件
kafka架构概念
祈雨的笔记 · 2019-01-27 · via 祈雨的笔记

Broker

每一个kafka的服务都是一个Broker,一个集群由多个Broker组成。Broker与topic的副本的关系是一个Broker可能存在多个topic的副本,一个topic的副本可能存在于多个Broker上。

如下图:Topic-0通过--replication-factor参数创建了4个副本保存在4个Broker上,Topic-1通过--replication-factor参数创建了3个副本保存在3个Broker上。

image

Topic

Topic就是数据主题,是数据记录发布的地方,可以用来区分业务系统。Kafka中的Topics总是多订阅者模式,一个topic可以拥有一个或者多个消费者来订阅它的数据。

topic是物理层面的概念,在路径/tmp/kafka-logs(配置文件server.propertieslog.dirs值)下可以看到每个topic对应至少一个文件夹。如下,名为test的topic对应文件夹test-0,名为test-topic的topic对应文件夹test-topic-0test-topic-1test-topic-2

1
2
3
4
drwxr-xr-x. 2 root root  178 Jan 26 22:43 test-0
drwxr-xr-x. 2 root root 141 Jan 26 23:11 test-topic-0
drwxr-xr-x. 2 root root 141 Jan 26 23:11 test-topic-1
drwxr-xr-x. 2 root root 141 Jan 26 23:11 test-topic-2

创建topic时可以通过--replication-factor设置副本数量。当topic有多个副本时,则有多个Broker拥有该topic的副本,这些Broker会有1个leader负责读写数据,其他的Broker均为folllower负责从leader同步数据。当leader所在Broker宕机后,剩余的follower选取出一个Broker作为新的leader负责读写数据,保证kafka机器的高可用。

__consumer_offsets

__consumer_offsets是一个kafka的内部topic,存放了Consumer group组元数据消息和Consumer group的offset位移消息。

用户感知不到该topic的存在。但是可以在路径/tmp/kafka-logs(配置文件server.propertieslog.dirs值)下看到该topic的存在,如下:

1
2
3
4
5
6
7
drwxr-xr-x. 2 root root  141 Jan 26 22:43 __consumer_offsets-0
drwxr-xr-x. 2 root root 141 Jan 26 22:43 __consumer_offsets-1
drwxr-xr-x. 2 root root 141 Jan 26 22:43 __consumer_offsets-10
drwxr-xr-x. 2 root root 141 Jan 26 22:43 __consumer_offsets-11
drwxr-xr-x. 2 root root 141 Jan 26 22:43 __consumer_offsets-12
drwxr-xr-x. 2 root root 141 Jan 26 22:43 __consumer_offsets-13
...

配置文件server.properties__consumer_offsets的副本数量默认为1,这会导致一个问题:即使用户使用的topic通过--replication-factor参数设置了多个副本,当__consumer_offsets当前副本所在的broker宕机,由于__consumer_offsets只有一份副本,那么消费者就无法读取和写入topic的offset位移信息,从而导致生产者可以发送消息但消费者不可用。

因此在kafka集群中offsets.topic.replication.factor务必设置大于1。

1
2
3
4
5
6
############################# Internal Topic Settings  #############################
# The replication factor for the group metadata internal topics "__consumer_offsets" and "__transaction_state"
# For anything other than development testing, a value greater than 1 is recommended for to ensure availability such as 3.
offsets.topic.replication.factor=1
transaction.state.log.replication.factor=1
transaction.state.log.min.isr=1

Partition

对于每一个topic拥有至少一个partition,如下所示:

image

partition同样也是是物理层面的概念,一个topic分成一个或多个partition,每个partition有多个副本分布在不同的broker中。如下,名为test的topic对应文件夹test-0即该topic拥有1一个partition;名为test-topic的topic对应文件夹test-topic-0test-topic-1test-topic-2即该topic拥有3个partition。

1
2
3
4
drwxr-xr-x. 2 root root  178 Jan 26 22:43 test-0
drwxr-xr-x. 2 root root 141 Jan 26 23:11 test-topic-0
drwxr-xr-x. 2 root root 141 Jan 26 23:11 test-topic-1
drwxr-xr-x. 2 root root 141 Jan 26 23:11 test-topic-2

生产者向topic的partition发送数据后,数据会按顺序追加到该partition末尾。因此,当消费者消息从topic消费数据时,对于同一个partition的数据消费是绝对有序的,但不保证一个topic的整体(多个partition间)的数据消费顺序。

Offset

Kafka的topic被分割成了一组完全有序的partition,其中每一个partition在任意给定的时间内只能被每个订阅了这个topic的consumer组中的一个consumer消费。这意味着partition中每一个consumer的位置仅仅是一个数字,即下一条要消费的消息的offset。这使得被消费的消息的状态信息相当少,每个partition只需要一个数字。这个状态信息还可以作为周期性的checkpoint。这以非常低的代价实现了和消息确认机制等同的效果。

image

这种方式还有一个附加的好处。consumer 可以回退到之前的offset 来再次消费之前的数据,这个操作违反了队列的基本原则,但事实证明对大多数 consumer 来说这是一个必不可少的特性。

例如,如果 consumer的代码有bug,并且在bug被发现前已经有一部分数据被消费了,那么 consumer 可以在 bug 修复后通过回退到之前的 offset来再次消费这些数据。

Producer

Producer为生产者,负责将消息发送到kafka的指定topic的指定partition中。如果发送的消息存在key值,则生产者使用partition数量对key值取模后发送到对应的partition中;如果发送的消息不存在key值,则生产者向消息投放到随机的partition中。

如下java客户端的实现org.apache.kafka.clients.producer.internals.DefaultPartitioner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
int numPartitions = partitions.size();
if (keyBytes == null) {
int nextValue = nextValue(topic);
List<PartitionInfo> availablePartitions = cluster.availablePartitionsForTopic(topic);
if (availablePartitions.size() > 0) {

int part = Utils.toPositive(nextValue) % availablePartitions.size();
return availablePartitions.get(part).partition();
} else {

return Utils.toPositive(nextValue) % numPartitions;
}
} else {

return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
}
}

Consumer

Kafka采取拉取模型(poll),由消费者控制消费速度,以及消费的进度,消费者可以按照任意的偏移量进行消费。比如消费者可以消费已经消费过的消息进行重新处理,或者消费最近的消息等等。

消费者与partition的关系是一个partition同时只能被每个订阅了这个topic的consumer组中的一个consumer消费。当partition的数量不小于消费者数量时,消费者与partition关系图如下:

image

当partition的数量小于消费者数量时,消费者与partition关系图如下。由于一个partition同时只能由消费组中的一个消费者消费数据,这种情况下会导致其他消费者闲置,无法从kafka消费到数据。因此在创建topic时一定要确定好partition数量(partition不小于消费者数量)。

image

ConsumerGroup

每个consumer属于一个特定的ConsumerGroup,可为每个consumer指定ConsumerGroup,若不指定,则属于默认的group。一条消息可以发送到不同的ConsumerGroup,但一个ConsumerGroup中只能有一个consumer能消费这条消息。

这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播(发给任意一个consumer)的方法。