kafka基本概念

本文详细介绍了Kafka的基本概念,包括Topic、Partition、Consumer Group和Broker。重点讨论了消费者之间的关系,强调了消费者组内分区分配的规则,并探讨了在多消费者场景下的互锁问题。同时,文章还提到了生产者面临的问题,如未收到Broker响应可能导致的重复数据,以及为确保消息幂等性提出的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

kafka?

kafka示例代码

生产者:

const { Kafka, Partitioners } = require("kafkajs");

(async () => {
	const kafka = new Kafka({
		clientId: "test-app",
		brokers: ['1.14.217.220:9094'],
	});

	const producer = kafka.producer({
		createPartitioner: Partitioners.LegacyPartitioner,
	});

	await producer.connect();

	for (let i = 0; i < 10; i++) {
		await producer.send({
			topic: "test-topic",
			messages: [{ value: "test msg" + i }],
		});
		console.log('发送:', "test msg" + i);
	}

	await producer.disconnect();
})();

消费者

const { Kafka } = require("kafkajs");

(async () => {
	const kafka = new Kafka({
		clientId: "test-app",
		brokers: ['1.14.217.220:9094'],
	});

	const consumer = kafka.consumer({ groupId: "test-group1" });

	await consumer.connect();
	await consumer.subscribe({ topic: "test-topic", fromBeginning: true });

	await consumer.run({
		eachMessage: async ({ topic, partition, message }) => {
			console.log({
				value: message.value.toString(),
			});
		},
	});
})();

kafka中消费者之间的关系

消费者有一个group的概念,用创建消费者时的groupId参数区分。同一个group中的消费者消费来自同一个topic的消息时取决于broker中分区的数量,具体规则如下。

  1. 当分区数大于消费者数量时,每一个消费者会被分配来自一个以上的分区的消息,以保证所有分区的消息都有地方消费
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MoumZCLx-1661006356982)(/api/project/10755416/files/28624151/imagePreview)]
  2. 当分区数量等于消费者数量时,一个消费者对应一个分区
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3vEoQX3I-1661006356982)(/api/project/10755416/files/28624154/imagePreview)]
  3. 当分区数量小于消费者数量时,可能有消费者会被闲置。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cbdYWhGx-1661006356982)(/api/project/10755416/files/28624164/imagePreview)]

总之就是确保每一个分区的消息都有消费者消费,但是不保证每一个消费者都有活干。
并且kafka有一个机制,每当有新的消费者加入既有的group时,就会分配一个leader。由leader来按照上述规则分配哪个消费者对应哪个分区。
我们目前搭建的kafka只有一个分区,并且目前采取的是点到点的形式,所以编写代码的时候一个话题只需要一个消费者就好了,消费者多了也会闲置掉。

关于更多的消费者的信息可以看看这两篇文章


杂项

订阅模式解决项目

消费者自身队列

使用队列解决

多消费者互锁

用一个读写锁给version,然后消费者看某条数据的读写锁,锁住了就跳过;没锁就加锁,然后查看version是不是比获取的时候新,如果是也跳过;若version保持一致就更新version,然后再跟broke声明已消费该条数据,解锁,继续往下一topic塞

生产者生产问题

未收到broke响应产生重复数据

尚未有实际思路,考虑消费重复消息后,最终的结果是一样的。(即冥等)

如何保证消息发送的幂等性
produce – > broke
每个producer会分配一个唯一 的PID,发往同一个broker的消息会附带一个Sequence Number,broker端会对<PID,partitionId,Sequence Number>做一个缓存,当具有相同主键的消息提交时,Kafka只会持久化一条。
注意:PID 会随着生产者重启而发生变化,并且不同的partition对应的partitionId也不相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值