@@ -11,7 +11,7 @@ Kafka 是一个分布式流式处理平台。这到底是什么意思呢?
11
11
流平台具有三个关键功能:
12
12
13
13
1 . ** 消息队列** :发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。
14
- 2 . ** 容错的持久方式存储记录消息流** : Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险· 。
14
+ 2 . ** 容错的持久方式存储记录消息流** : Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险。
15
15
3 . ** 流式处理平台:** 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库。
16
16
17
17
Kafka 主要有两大应用场景:
@@ -21,7 +21,7 @@ Kafka 主要有两大应用场景:
21
21
22
22
### 和其他消息队列相比,Kafka的优势在哪里?
23
23
24
- 我们现在经常提到 Kafka 的时候就已经默认它是一个非常优秀的消息队列了,我们也会经常拿它给 RocketMQ、RabbitMQ 对比。我觉得 Kafka 相比其他消息队列主要的优势如下:
24
+ 我们现在经常提到 Kafka 的时候就已经默认它是一个非常优秀的消息队列了,我们也会经常拿它跟 RocketMQ、RabbitMQ 对比。我觉得 Kafka 相比其他消息队列主要的优势如下:
25
25
26
26
1 . ** 极致的性能** :基于 Scala 和 Java 语言开发,设计中大量使用了批量处理和异步的思想,最高可以每秒处理千万级别的消息。
27
27
2 . ** 生态系统兼容性无可匹敌** :Kafka 与周边生态系统的兼容性是最好的没有之一,尤其在大数据和流计算领域。
@@ -42,7 +42,7 @@ Kafka 主要有两大应用场景:
42
42
43
43
** 队列模型存在的问题:**
44
44
45
- 假如我们存在这样一种情况:我们需要将生产者产生的消息分发给多个消费者,并且每个消费者都能接收到完成的消息内容 。
45
+ 假如我们存在这样一种情况:我们需要将生产者产生的消息分发给多个消费者,并且每个消费者都能接收到完整的消息内容 。
46
46
47
47
这种情况,队列模型就不好解决了。很多比较杠精的人就说:我们可以为每个消费者创建一个单独的队列,让生产者发送多份。这是一种非常愚蠢的做法,浪费资源不说,还违背了使用消息队列的目的。
48
48
@@ -104,7 +104,7 @@ ZooKeeper 主要为 Kafka 提供元数据的管理的功能。
104
104
105
105
从图中我们可以看出,Zookeeper 主要为 Kafka 做了下面这些事情:
106
106
107
- 1 . ** Broker 注册** :在 Zookeeper 上会有一个专门** 用来进行 Broker 服务器列表记录** 的节点。每个 Broker 在启动时,都会到 Zookeeper 上进行注册,即到/brokers/ids 下创建属于自己的节点。每个 Broker 就会将自己的 IP 地址和端口等信息记录到该节点中去
107
+ 1 . ** Broker 注册** :在 Zookeeper 上会有一个专门** 用来进行 Broker 服务器列表记录** 的节点。每个 Broker 在启动时,都会到 Zookeeper 上进行注册,即到 ` /brokers/ids ` 下创建属于自己的节点。每个 Broker 就会将自己的 IP 地址和端口等信息记录到该节点中去
108
108
2 . ** Topic 注册** : 在 Kafka 中,同一个** Topic 的消息会被分成多个分区** 并将其分布在多个 Broker 上,** 这些分区信息及与 Broker 的对应关系** 也都是由 Zookeeper 在维护。比如我创建了一个名字为 my-topic 的主题并且它有两个分区,对应到 zookeeper 中会创建这些文件夹:` /brokers/topics/my-topic/Partitions/0 ` 、` /brokers/topics/my-topic/Partitions/1 `
109
109
3 . ** 负载均衡** :上面也说过了 Kafka 通过给特定 Topic 指定多个 Partition, 而各个 Partition 可以分布在不同的 Broker 上, 这样便能提供比较好的并发能力。 对于同一个 Topic 的不同 Partition,Kafka 会尽力将这些 Partition 分布到不同的 Broker 服务器上。当生产者产生消息后也会尽量投递到不同 Broker 的 Partition 里面。当 Consumer 消费的时候,Zookeeper 可以根据当前的 Partition 数量以及 Consumer 数量来实现动态负载均衡。
110
110
4 . ......
@@ -138,7 +138,7 @@ Kafka 中发送 1 条消息的时候,可以指定 topic, partition, key,data
138
138
139
139
生产者(Producer) 调用` send ` 方法发送消息之后,消息可能因为网络问题并没有发送过去。
140
140
141
- 所以,我们不能默认在调用` send ` 方法发送消息之后消息消息发送成功了 。为了确定消息是发送成功,我们要判断消息发送的结果。但是要注意的是 Kafka 生产者(Producer) 使用 ` send ` 方法发送消息实际上是异步的操作,我们可以通过 ` get() ` 方法获取调用结果,但是这样也让它变为了同步操作,示例代码如下:
141
+ 所以,我们不能默认在调用` send ` 方法发送消息之后消息发送成功了 。为了确定消息是发送成功,我们要判断消息发送的结果。但是要注意的是 Kafka 生产者(Producer) 使用 ` send ` 方法发送消息实际上是异步的操作,我们可以通过 ` get() ` 方法获取调用结果,但是这样也让它变为了同步操作,示例代码如下:
142
142
143
143
> ** 详细代码见我的这篇文章:[ Kafka系列第三篇!10 分钟学会如何在 Spring Boot 程序中使用 Kafka 作为消息队列?] ( https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247486269&idx=2&sn=ec00417ad641dd8c3d145d74cafa09ce&chksm=cea244f6f9d5cde0c8eb233fcc4cf82e11acd06446719a7af55230649863a3ddd95f78d111de&token=1633957262&lang=zh_CN#rd ) **
144
144
@@ -170,7 +170,7 @@ if (sendResult.getRecordMetadata() != null) {
170
170
171
171
当消费者拉取到了分区的某个消息之后,消费者会自动提交了 offset。自动提交的话会有一个问题,试想一下,当消费者刚拿到这个消息准备进行真正消费的时候,突然挂掉了,消息实际上并没有被消费,但是 offset 却被自动提交了。
172
172
173
- ** 解决办法也比较粗暴,我们手动关闭自动提交 offset,每次在真正消费完消息之后之后再自己手动提交 offset 。** 但是,细心的朋友一定会发现,这样会带来消息被重新消费的问题。比如你刚刚消费完消息之后,还没提交 offset,结果自己挂掉了,那么这个消息理论上就会被消费两次。
173
+ ** 解决办法也比较粗暴,我们手动关闭自动提交 offset,每次在真正消费完消息之后再自己手动提交 offset 。** 但是,细心的朋友一定会发现,这样会带来消息被重新消费的问题。比如你刚刚消费完消息之后,还没提交 offset,结果自己挂掉了,那么这个消息理论上就会被消费两次。
174
174
175
175
#### Kafka 弄丢了消息
176
176
0 commit comments