Kafka基本理解
一、Kafka定义
Kafka是一个分布式、分区、多副本、多订阅者、基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常用于web/nginx日志、访问日志,消息服务等等场景。简单点来说就是一个分布式的基于分布/订阅模式的消息队列(Message Queue), 主要应用于大数据实时处理领域。
主要应用场景是:日志收集系统和消息系统。
Kafka主要设计目标如下:
- 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能。
- 高吞吐率,即使在非常廉价的商用机器上
也能做到单机支持每秒100K条消息的传输。
- 支持Kafka Server间的消息分区,及分布式消费,同时保证每个partition内的消息顺序传输。
- 同时支持离线数据处理和实时数据处理。
这里顺便介绍一下使用消息队列的好处:
-解耦:允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
-可恢复性:系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列的消息仍然可以在系统恢复后被处理。
-缓冲:有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。
-灵活性 & 峰值处理能力:在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全奔溃。
-异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制。允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后再需要的时候再去处理它们。
二、Kafka消费模式
Kafka采用的消费模式是发布/订阅模式。摘取一段外文解释:
Publish-subscribe messaging means that the system that is generating the piece of data (a producer or publisher) is not sending the data directly to a receiver (a consumer or subscriber), but instead is sending the data to a Kafka (called a broker).
Decoupling the publishing and consuming steps allows a publisher to make its data available without needing to know how it will be used (consumed) by others. For example, a publisher could publish a stream of data that represents changes to a booking system. Immediately, a consumer could subscribe and use that information to update records in a second booking system. Later, another consumer could subscribe to the same data and use that information to provide alerts to customers without needing to have any further interaction with the publisher.
简单翻译一下:
发布/订阅模式表示由一个生产者(或发布者)进行生产数据,但并不会直接发送给消费者(或订阅者),而是先发送给Kafka,称为broker。
这样做的好处是将生产和消费步骤进行解耦合了。生产者无需了解数据怎么被消费者消费,只需要往broker中推送数据即可。而且在这里说明一下,生产者往broker中推送的数据,放入了broker中的消息队列当中,并且是按照topic进行分类,而消费者需要轮询去询问broker是否有需要消费者消费的数据,因为不同的消费者消费不一样的数据。
现在可能有点懵懵的,那么接下来,介绍介绍Kafka的结构,逐渐慢慢了解Kafka。
三、Kafka结构
先放一张结构图,大致感受一下。
Kafka专业用语:
1、Broker:消息中间件处理结点,一个Kafka节点就是一个Broker,多个Broker可以组成一个Kafka集群。
2、Topic:一类消息,Kafka集群能够同时负责多个topic的分发。
3、Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。
4、Segment:partition物理上由多个segment组成。
5、offset :每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的序列号叫做offset,用于partition唯一标识一条消息。
6、Producer :负责发布消息到Kafka broker。
7、Consumer :消息消费者,向Kafka broker读取消息的客户端。
8、Consumer Group :每个Consumer属于一个特定的Consumer Group。
OK,有了这些基本的概念之后,接下来简单介绍一下这个基本的架构,顺便说说一些简单的流程。
首先,由生产者生产数据,根据不同的topic进行分类,且相同的topic若数据量过大,则进行分区。然后push到broker节点当中,并且为了保证高容错性,会在多个broker当中进行存储副本,其中选取一个leader,其余都是副本,每一个分区基本上都会存在副本。
接下来,不同的消费者具有不同的消费速度,并且可能存在消费者群,这些消费者或消费者群根据topic向broker进行拉取数据。同一Topic的一条消息只能被同一个Consumer Group内的一个Consumer消费,但多个Consumer Group可同时消费这一消息。
最后,在0.9的版本之前,分区数据的offset是交由zookeeper来存储管理的,防止某个节点宕机之后出现offset丢失。0.9版本之后分区数据的offset存储在了该节点的本地磁盘内,由自身去管理,因为消费者读取数据具有低延迟、高吞吐的特点,所以需要与zookeeper经常交互,保证offset的更新,为了减少了broker与zookeeper之间的交互,所以改为存储在了本地磁盘。
由于读写流程以及副本策略等等原理太多,放在一起篇幅过长,会尽快出系列文章,专门讲讲各种原理以及流程。
参考
https://www.iteblog.com/archives/2227.html
https://developer.ibm.com/articles/an-introduction-to-apache-kafka/
https://www.bilibili.com/video/BV1a4411B7V9?p=11