wangying 2020-06-28
现在,每个公司都在互联网系统中使用Kafka。 Kafka似乎是解决分布式并提高系统吞吐量的最佳松耦合解决方案之一。
我大约6年前开始使用Kafka。 当时,我在Aerohive工作。 为了解决企业wifi设备带来的大量日志,传统的消息传递系统RabbitMQ和ActiveMQ已经不堪重负。
此时,Kafka诞生了(2012年),并提供了一个完美的解决方案。
重要要点:
什么是消息系统?
在了解Kafka之前,如果您不知道什么是Message Queue,则需要添加它。 如果您已经知道,则可以跳到下一段。
> Morden Distributed System
如上图所述,Message Queue是一个在两个系统之间传输和存储消息的中间件。 其外观具有以下优点:
同时,我认为最大的缺点是复杂性,其优点完全可以忽略不计。
Kafka如何运作?
对于Kafka而言,从独立的角度来看,其中包括生产者,消费者和经纪人。
> Kafka components
如图所示,不同的生产者可以将消息发送到多个主题的多个分区,而消费者也可以从各种主题中消费。
生产者和消费者完全孤立。
在此设计中,它充分体现了去耦,灵活性和峰值处理能力,订单保证和异步通信。
Kafka如何在分布式环境中工作?
1. 集群
多个代理和副本。
Kafka如何保证冗余,可恢复性和高可用性?
即使某些节点发生故障,复制也可以提供高可用性:
基于仲裁的复制可以使用筏和Paxos等算法,例如Zookeeper,Google Spanner等。在2n +1个节点的情况下,最多可以容忍n个节点故障。
仅在成功接收到消息后,基于主数据库的复制以及其他主数据库和备份的写入操作才能成功。 对于n个节点,最多可以容忍n-1个节点故障,例如Microsoft的PacifiaA。
这两种方法各有优缺点。
Kafka采用第二种方法,即主从模式,该方法主要基于容错能力,并且在两个节点的情况下也可以提供高可用性。
如果节点很慢怎么办?
首先,这种情况很少发生。 如果发生这种情况,您可以设置超时参数来处理这种情况。
Kafka的复制适用于分区。
例如,在上图中,有四个代理,一个主题和两个分区。 复制因子是三。 当生产者发送消息时,它将选择一个分区,例如topic1-part1分区,将消息发送到该分区的领导者,broker2,broker3将拉出消息,消息被拉出后,从属将发送ack到 主机,这次主机仅提交此日志。
在此过程中,生产者有两种选择:
在第一个中,您可以确保在异常情况下不会丢失消息,但是延迟会减少。 后者的等待时间已大大改善,但是一旦出现异常情况,从属服务器将无法在领导挂起之前提取最新消息。 在这种情况下,可能会丢失该消息。
2. 客户群
消费者使用消费者组名称标记自己,并且发布到主题的每条记录都会传递到每个订阅消费者组中的一个消费者实例。 使用者实例可以在单独的进程中或在单独的机器上。
如果所有使用者实例都具有相同的使用者组,那么将在这些使用者实例上有效地平衡记录。
如果所有使用者实例具有不同的使用者组,则每条记录将广播到所有使用者进程形成正式文件
简而言之,消费者群体是Kafka生态系统中的真正消费者。
3. 控制者
上图是2015年Kafka Controller的设计图。 Controller和ZK共同构建了Kafka的高层架构,该架构主要完成以下任务:
为什么Kafka这么快?
Kafka中有一个过程,其中大量网络数据被持久保存到磁盘(生产者到代理),并且磁盘文件通过网络发送(经纪人到消费者)。
此过程的性能直接影响Kafka的整体吞吐量。
1. 零复制
上图的左侧是传统的四个副本和四个上下文切换。
在上图的右侧,Kafka使用Linux 2.4+内核sendfile系统调用来实现零复制。
因为sendfile调用完成了整个文件读取网络的传输,所以整个过程只有两个上下文切换,因此性能大大提高了。
准确地说,Kafka的数据传输是通过TransportLayer完成的,其子类PlaintextTransportLayer通过Java NIO的FileChannel的transferTo和transferFrom方法实现了零复制。
2. 顺序访问
> Compare
上图显示,即使顺序读取磁盘,顺序访问的巨大优势也比基于内存的随机访问要好。
Kafka中的每条消息都会被追加,并且不会从中间写入或删除消息,以确保顺序访问磁盘。
即使是顺序读取和写入,过多的小型IO操作也会导致磁盘瓶颈,并且这次变成了随机读取和写入。
Kafka的策略是汇总消息并分批发送,以最大程度地减少对磁盘的访问。 因此,Kafka的主题和分区的数量不应过多。
通常,经过64个主题/分区之后,Kafka的性能将急剧下降。
3. 段日志
这种分区分割和索引设计不仅提高了数据读取的效率,而且还提高了数据操作的并行性。
4. 高性能Broker
Kafka在Broker中的设计也是其如此之快的原因之一。
首先,客户端发送的所有请求都将发送到接受器。 代理中将默认有三个线程。 这三个线程称为处理器。
接受者将不会对客户的请求进行任何处理,而是直接对其进行封装。 将socketChannel发送到这些处理器以形成队列。
发送的方法是轮询,即先发送到第一个处理器,然后再发送到第二个,第三个处理器,然后再返回到第一个处理器。 当使用者线程使用这些socketChannel时,它将获取请求请求,并且数据将伴随这些请求请求。
默认情况下,线程池中有八个线程。 这些线程用于处理请求和解析请求。 如果请求是书面请求,则将其写入磁盘。 如果读取,则返回结果。 处理器将从响应中读取响应数据,然后将其返回给客户端。
这是Kafka的三层网络架构。
因此,如果我们需要增强和调整Kafka,增加处理器并增加线程池中的处理线程,则可以达到效果。 考虑到处理器生成请求的速度过快,并且线程数量不足以及时处理请求,因此请求和响应实际上是一种缓存效果。
总结
我希望本文对您了解和初步了解Kafka,它具有的组件以及为什么可以实现如此高的性能有所帮助。
Kafka在现代高并发系统体系结构中扮演着至关重要的角色,并且仍在快速发展,例如流媒体。
本文仅从概念和简单设计原理方面说明Kafka。 仅仅掌握它是不够的。