Skip to content

Commit 5e845be

Browse files
committed
feat: kafka-cli
1 parent b0f325f commit 5e845be

File tree

7 files changed

+386
-17
lines changed

7 files changed

+386
-17
lines changed

docs/.vitepress/config.mts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export default defineConfig({
3939
'/notes/fluss/': [
4040
{
4141
text: 'Fluss学习笔记',
42+
link: '/notes/fluss/fluss-category',
43+
collapsed: true,
4244
items: [
4345
{ text: '01-搭建Fluss本地开发环境', link: '/notes/fluss/01-development-env-setup' },
4446
{ text: '02-Fluss Catalog', link: '/notes/fluss/02-fluss-catalog' },
@@ -49,14 +51,19 @@ export default defineConfig({
4951
'/notes/kafka/': [
5052
{
5153
text: 'Kafka学习笔记',
54+
link: '/notes/kafka/kafka-category',
55+
collapsed: true,
5256
items: [
5357
{ text: '01-kafka简介', link: '/notes/kafka/01-intro' },
58+
{ text: '02-kafka命令合集', link: '/notes/kafka/02-kafka-cli' },
5459
]
5560
}
5661
],
5762
'/notes/flink/': [
5863
{
5964
text: 'Flink学习笔记',
65+
link: '/notes/flink/flink-category',
66+
collapsed: true,
6067
items: [
6168
{ text: 'Flink源码 - 从Kafka Connector看Source接口重构', link: '/notes/flink/flink-connector-kafka' }
6269
]

docs/notes/flink/flink-connector-kafka.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
title: Flink源码 - 从Kafka Connector看Source接口重构
33
tags: flink
4+
outline: deep
45
---
56

67
# **Flink源码 - 从Kafka Connector看Source接口重构**
@@ -85,7 +86,7 @@ Split分配流程由`KafkaSourceEnumerator`实现, 它是`SplitEnumerator`的实
8586

8687
可以看到`KafkaSourceEnumerator`的Partition分配流程还是比较复杂的, 不过在把握整体流程之后再阅读各个函数的代码, 其实也不难理解.
8788

88-
## 数据读取流程
89+
### 数据读取流程
8990

9091
`KafkaSourceReader`接收到来自`KafkaSourceEnumerator`分配的Partition之后, 就会开始真正进行数据读取了. 数据读取的整体流程还是比较简单的, `KafkaSourceReader`运行在Task主线程中, 非阻塞地从`FutureCompletingBlockingQueue`中获取数据, 如果有数据就使用`KafkaRecordEmitter`向下游发送数据. `SplitFetcher`是真正的IO线程, 通过`KafkaPartitionSplitReader`从Kafka读取数据后放入`FutureCompletingBlockingQueue`.
9192

@@ -106,7 +107,7 @@ Split分配流程由`KafkaSourceEnumerator`实现, 它是`SplitEnumerator`的实
106107
![kafka-source-reader-io-3.png](./img/flink-connector-kafka/kafka-source-reader-io-3.png)
107108

108109

109-
## **SplitFetcher生命周期**
110+
### **SplitFetcher生命周期**
110111

111112
通过上文的分析我们已经知道, `SplitFetcher`是真正从数据源读取数据的任务, 它继承自`Runnable`并运行在`SplitFetcherManager`的线程池中. `SplitFetcher`任务的状态在运行过程中会不断发生变化, 笔者将`SplitFetcher`的生命周期总结为以下四个状态(**需要注意的是这几个状态是笔者总结的逻辑上的状态, 并不与Java线程的状态完全对应**):
112113

@@ -138,7 +139,7 @@ Split分配流程由`KafkaSourceEnumerator`实现, 它是`SplitEnumerator`的实
138139

139140
`SpliteFetcher`是真正实现数据读取的任务, 理解它的生命周期和执行流程是理解新版Source接口的核心之一.
140141

141-
## **Watermark对齐流程**
142+
### **Watermark对齐流程**
142143

143144
新Source接口中一个十分重要的特性就是Watermark对齐, 用于解决[Event Time倾斜问题](https://liebing.org.cn/flink-watermark.html#Event-Time%E5%80%BE%E6%96%9C%E7%9A%84%E9%97%AE%E9%A2%98). 在Flink 1.15及之后的版本中可以通过如下方式指定对齐参数.
144145

@@ -233,7 +234,7 @@ public class SourceOperator<OUT, SplitT extends SourceSplit> extends AbstractStr
233234

234235
Split级别的Watermark对齐在`checkSplitWatermarkAlignment()`中实现, 其调用链较长, 如上图所示. 最终的实现在`KafkaPartitionSplitReader.pauseOrResumeSplits()`中, 通过`KafkaConsumer`提供的`pause()``resume()`两个方法分别用于停止和继续读取相应的Partition. 此外, 对于Multi-split Multi-threaded模式的实现, 由于一个`SplitFetcher`仅读取一个Split, 在需要对齐时可直接在`SplitFetcherManager.pauseOrResumeSplits()`通过`SplitFetcher.pause()``SplitFetcher.resume()`将指定的`SplitFetcher`暂停或唤醒.
235236

236-
## Checkpoint和Failover流程
237+
### Checkpoint和Failover流程
237238

238239
除了Split分配和数据读取流程, 在生产环境中还需要关注的是Checkpoint流程和Failover流程.
239240

docs/notes/fluss/01-development-env-setup.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
title: 搭建Fluss本地开发环境
33
tags: fluss
4+
outline: deep
45
---
56

67
# **搭建Fluss本地开发环境**

docs/notes/fluss/02-fluss-catalog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
title: Fluss Catalog
33
tags: fluss
4+
outline: deep
45
---
56

67
# Fluss Catalog

docs/notes/kafka/01-intro.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
---
22
title: Kafka简介
33
tags: Kafka
4+
outline: deep
45
---
56

67
# Kafka简介
78

8-
### 1. 概述
9+
## 1. 概述
910

1011
Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。
1112

@@ -19,56 +20,56 @@ Kafka主要设计目标如下:
1920
- 同时支持离线数据处理和实时数据处理。
2021
- Scale out:支持在线水平扩展
2122

22-
### 2. 消息系统
23+
## 2. 消息系统
2324

2425
一个消息系统负责将数据从一个应用传递到另外一个应用,应用只需关注于数据,无需关注数据在两个或多个应用间是如何传递的。分布式消息传递基于可靠的消息队列,在客户端应用和消息系统之间异步传递消息。有两种主要的消息传递模式:**点对点传递模式、发布-订阅模式**。大部分的消息系统选用发布-订阅模式。**Kafka就是一种发布-订阅模式**
2526

26-
#### 2.1 点对点消息传递模式
27+
### 2.1 点对点消息传递模式
2728

2829
在点对点消息系统中,消息持久化到一个队列中。此时,将有一个或多个消费者消费队列中的数据。但是一条消息只能被消费一次。当一个消费者消费了队列中的某条数据之后,该条数据则从消息队列中删除。该模式即使有多个消费者同时消费数据,也能保证数据处理的顺序。这种架构描述示意图如下:
2930

3031
![点对点模式](img/01/point-to-point.png "点对点模式")
3132

3233
**生产者发送一条消息到queue,只有一个消费者能收到**
3334

34-
#### 2.2 发布-订阅消息传递模式
35+
### 2.2 发布-订阅消息传递模式
3536

3637
在发布-订阅消息系统中,消息被持久化到一个topic中。与点对点消息系统不同的是,消费者可以订阅一个或多个topic,消费者可以消费该topic中所有的数据,同一条数据可以被多个消费者消费,数据被消费后不会立马删除。在发布-订阅消息系统中,消息的生产者称为发布者,消费者称为订阅者。该模式的示例图如下:
3738

3839
![点发布-订阅模式](img/01/publisher-subscriber.png "发布-订阅模式")
3940

4041
**发布者发送到topic的消息,只有订阅了topic的订阅者才会收到消息**
4142

42-
### 3. Kafka的优点
43+
## 3. Kafka的优点
4344

44-
#### 3.1 解耦
45+
### 3.1 解耦
4546

4647
在项目启动之初来预测将来项目会碰到什么需求,是极其困难的。消息系统在处理过程中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。这允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
4748

48-
#### 3.2 冗余
49+
### 3.2 冗余
4950

5051
有些情况下,处理数据的过程会失败。除非数据被持久化,否则将造成丢失。消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的"插入-获取-删除"范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。
5152

52-
#### 3.3 扩展性
53+
### 3.3 扩展性
5354

5455
因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。不需要改变代码、不需要调节参数。扩展就像调大电力按钮一样简单。
5556

56-
#### 3.4 灵活性&峰值处理能力
57+
### 3.4 灵活性&峰值处理能力
5758

5859
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见;如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
5960

60-
#### 3.5 可恢复性
61+
### 3.5 可恢复性
6162

6263
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
6364

64-
#### 3.6 顺序保证
65+
### 3.6 顺序保证
6566

6667
在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。Kafka保证一个Partition内的消息的有序性。
6768

68-
#### 3.7 缓冲
69+
### 3.7 缓冲
6970

7071
在任何重要的系统中,都会有需要不同的处理时间的元素。例如,加载一张图片比应用过滤器花费更少的时间。消息队列通过一个缓冲层来帮助任务最高效率的执行———写入队列的处理会尽可能的快速。该缓冲有助于控制和优化数据流经过系统的速度。
7172

72-
#### 3.8 异步通信
73+
### 3.8 异步通信
7374

7475
很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。

0 commit comments

Comments
 (0)