Kafka-2 Kafka的特点
Kafka-1 详解Kafka为什么快
- 常见的消息中间件
- 常见消息中间件之间的细微区别
- 1. 性能与吞吐量:
- 2. 消息分区与负载均衡:
- 3. 延迟队列与死信队列
- 二、为什么在高性能与高吞吐量的时候我们需要选择Kafka
- 1. 批量发送:
- 2.异步发送
- 3.消息压缩:
- 4.并行发送:
- 消息存储
- 1. 采用了零拷贝技术
- 2. 磁盘顺序写入
- 3.稀疏索引
- 4.分区与副本
- 消费者
- 1. 消费者群组
- 2. 并行消费
- 3. 批量拉去
常见的消息中间件
Kafka,ActiveMQ,RabbitMQ,RocketMQ都是常见的消息中间件,主要的用途是一致的,但是他们之间也是有着一些细小的区别
常见消息中间件之间的细微区别
1. 性能与吞吐量:
Kafka在数据处理与数据分发方面表现相比于其余几个更为出色,如果我们在处理大量数据时,需要较高的性能与吞吐量的时候,我们可以选用Kafka。
2. 消息分区与负载均衡:
Kafka将消息划分为多个分区,并且分布在多个服务器上来实现负载均衡与高可用。虽然其他消息中间件也支持消息分区与负载均衡,但是他们之间的实现方式并不相同。
3. 延迟队列与死信队列
- Kafka并不支持延迟队列与死信队列,但是他可以通过Redis有序集合实现精确延迟来实现延迟队列。
public class RedisDelayedQueue {private static final String REDIS_KEY = "delayed_queue";private final Jedis jedis;public RedisDelayedQueue(String host) {this.jedis = new Jedis(host);}// 添加延迟消息public void addMessage(String message, long delaySeconds) {double score = Instant.now().getEpochSecond() + delaySeconds;jedis.zadd(REDIS_KEY, score, message);}// 处理到期消息public void processMessages() {while (true) {long now = Instant.now().getEpochSecond();// 获取所有已到期的消息jedis.zrangeByScore(REDIS_KEY, 0, now).forEach(msg -> {System.out.println("Processing: " + msg);jedis.zrem(REDIS_KEY, msg); // 移除已处理消息});try {Thread.sleep(1000); // 每秒检查一次} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}
}
- RocketMQ则直接支持延迟队列,可以通过设定消息的延迟时间来实现。
- RabbitMQ也支持延时队列。可以通过插件或者消息TTL和死信队列交换来实现。
具体需要选择那个消息中间件还是需要取决于自己的业务需求以及系统架构,选择合适的消息中间件
二、为什么在高性能与高吞吐量的时候我们需要选择Kafka
Kafka通过以下三个方面的优化,来实现的更高性能与更高吞吐量
1. 批量发送:
Kafka可以通过将多个消息打包成一个批次,减少网络传输与磁盘写入的次数。
2.异步发送
生产者可以发送异步消息,无需等待每个消息的确认,这在一定程度上大幅度提高了吞吐量。
3.消息压缩:
- 生产者支持对于消息进行压缩,从而减少每次网络传输的数据量。
- 何为压缩?
压缩,是用时间换取空间的经典思想,具体来说,就是用CPU时间来换取磁盘空间或者网络I/O传输量,用较少的CPU开销带来更少的磁盘占用或者更少的网络I/O传输。 - 何时压缩?
压缩可能发生的地方在生产者段、broker段。
在生产者段可以通过配置 props.put(“conmpression.type”, “gzip”) 就可以开启gzip压缩。 - 何时解压?
解压通常发生在消费者,在一般情况下,我们会将压缩算法封装到消息集合中,消费者通过压缩算法进行解压。 - 因为带宽比CPU更为稀缺一些,当CPU资源充足,但是环境宽带有限时,更比较推荐开启压缩算法。
4.并行发送:
通过负载均衡将数据分布在不同的分区中,生产者可以并行发送消息。
- 有了topic为什么还需要分区(partition)?
最主要的原因:实现系统的高伸缩性,不同的分区可以放在不同节点的机器上,我们可以通过增加机器来增加整个系统的吞吐量。 - 分区策略:
Kafka的分区策略一般 为轮询、随机、按Key、自定义分区策略。
消息存储
1. 采用了零拷贝技术
通过采用零拷贝技术来避免数据的拷贝操作,降低内存和CPU的使用率。零拷贝这一个技术在很多地方都有所应用,在后期会单独写一篇来讲述何为零拷贝。
2. 磁盘顺序写入
Kafka把消息存储在磁盘上,且以顺序的方式写入数据。顺序写入可以减少磁头寻道时间,避免随机读写带来的性能损耗。
- Kafka如何实现顺序消费的
Kafka在一个topic下只有一个partition时,由于写入时是按照顺序写入的,所以在消费时可以实现顺序消费;当一个topic下有多个partition时,我们可以将需要保证需要顺序消费的消息都放在一个指定的partition中,这样我们也可以保证做到顺序消费。
3.稀疏索引
通过每隔一定的消息来建立一个索引,这样构建成了稀疏索引,从而减少了索引的大小,提高了查找特定消息的效率。
4.分区与副本
Kafka采用了分区与副本的机制,可以将数据分散到多个节点上进行处理。
- 在集群中,每个分区(partition)中都可以有多个副本,这些副本中包含了yigeLeader副本和多个Follower副本,只有Leader副本才能处理生产者和消费者的请求,而Follower副本只是Leader副本的备份,用于提供数据的冗余备份和容错能力,当Leader发生故障,Kafka集群会自动将某个Follower副本提升为新的Leader副本,从而实现高可用与高容错。
消费者
1. 消费者群组
通过消费者群组可以实现消息的负载均衡和容错处理
2. 并行消费
不同的消费者可以独立消费不同的分区,实现消费的并行处理
3. 批量拉去
Kafka支持批量拉取消息,可以一次性拉取多个消息进行消费,减少网络消耗。
