Kafka创建背景
Kafka是一个消息系统,原本开发自LinkedIn,用作LinkedIn的活动流(Activity Stream)和运营数据处理管道(Pipeline)的基础。现在它已被作为多种类型的数据管道和消息系统使用。活动流数据是几乎所有站点在对其网站使用情况做报表时都要用到的数据中最常规的部分。活动数据包括页面访问量(Page View)、被查看内容方面的信息以及搜索情况等内容。这种数据通常的处理方式是先把各种活动以日志的形式写入某种文件,然后周期性地对这些文件进行统计分析。运营数据指的是服务器的性能数据(CPU、IO使用率、请求时间、服务日志等等数据)。kafka作为一个集群运行在一个或多个服务器上,kafka集群存储的消息是以topic为类别记录的,每个消息(也叫记录record,我习惯叫消息)是由一个key,一个value和时间戳构成。
核心组件
Producer
:发布消息到1个或多个topic(主题)。Comsumer
:来订阅一个或多个topic,并处理产生的消息。Streams
:充当一个流处理器,从1个或多个topic消费输入流,并生产一个输出流到1个或多个输出topic,有效地将输入流转换到输出流。Connector:
允许构建或运行可重复使用的生产者或消费者,将topic连接到现有的应用程序或数据系统。例如,一个关系数据库的连接器可捕获每一个变化。
基本术语
- Topic:Kafka将消息分类,每一类的消息称之为一个Topic.
- Producer:发布消息的对象称之为生产者
- Consumer:订阅Topic,并消费Topic中的消息
- Broker:已发布的消息保存在一组服务器中,称之为Kafka集群。集群中的每一个服务器都是一个代理(Broker). 消费者可以订阅一个或多个主题(topic),并从Broker拉数据,从而消费这些已发布的消息。
Topic和Log
Topic是生产者生产消息的类别,消息根据不同的Topic被存储到不同的Partition,一个Topic中的消息可以被存储到多个Partition,kafka为每一个分区都维护了一个log.
每一个分区都是一个有序的、不可变的消息队列, 并且可以持续的添加。分区中的消息都被分了一个序列号,称之为偏移量(offset),offset在每个分区中此偏移量都是唯一的。Kafka集群保持所有的消息,直到它们过期, 无论消息是否被消费了。 消费者所持有的仅有的元数据就是偏移量,也就是消费者在这个log中的位置。 这个偏移量由消费者控制:当消费者消费消息的时候,偏移量也会随着消息的消费不但增加。但消费者可以将偏移量重置为更老的一个偏移量,重新读取消息,并且多个消费者对于消息的消费互不影响。
Log的分区被分布到集群中的多个服务器上。每个服务器处理它分到的分区。 根据配置每个分区还可以复制到其它服务器作为备份容错。 每个分区有一个leader,零或多个follower。Leader处理此分区的所有的读写请求,而follower被动的复制数据。如果leader宕机,其它的一个follower会被推举为新的leader。 一台服务器可能同时是一个分区的leader,另一个分区的follower。 这样可以平衡负载,避免所有的请求都只让一台或者某几台服务器处理。生产者往某个Topic上发布消息。生产者也负责选择发布到Topic上的哪一个分区。最简单的方式从分区列表中轮流选择,也可以根据某种算法依照权重选择分区。开发者负责如何选择分区的算法。
通常来讲,消息系统的模型可以分为两种, 队列和发布-订阅式。 队列模型的处理方式是一组消费者从服务器读取消息,一条消息只有其中的一个消费者来处理;发布-订阅模型中,消息被广播给所有的消费者,接收到消息的消费者都可以处理此消息。kafka为了充分利用队列模型和发布-订阅模型的优点提出了consumer group概念。 消费者用一个消费者组名标识。 一个发布在Topic上消息被分发给此消费者组中的一个消费者。 如果的消费者都在一个消费者组中,就变成了queue模型;如果所有的消费者都在不同的组中,那么就完全变成了发布-订阅模型。消费者组作为逻辑上的订阅者,可以包含数目不等的消费者。 一个组内多个消费者可以用来扩展性能和容错,多个消费者组可以增强消息的并发处理能和扩展性。
如上图所示2个kafka集群托管4个分区(P0-P3),2个消费者组,消费组A有2个消费者实例,消费组B有4个。
传统的队列模型保持消息,并且保证它们的先后顺序不变。尽管服务器保证了消息的顺序,消息还是异步的发送给各个消费者,消费者收到消息的先后顺序不能保证了。这也意味着并行消费将不能保证消息的先后顺序,但是如果只让一个消费者处理消息,又违背了并行处理的初衷。 Kafka采用了一种分而治之的策略:分区。 因为Topic分区中消息只能由消费者组中的唯一一个消费者处理,所以消息肯定是按照先后顺序进行处理的。但是它也仅仅是保证Topic的一个分区顺序处理,不能保证跨分区的消息先后处理顺序。 所以,如果你想要顺序的处理Topic的所有消息,那就只提供一个分区。但是需要主要:相同消费者组中的消费者数量不能比分区的数量更多,否则多出的消费者将会处于等待状态,不处理消息。
传统的消息有两种模式:队列和发布订阅。 队列的优点是允许多个消费者并行处理数据,这样可以根据消息的生产速度增加和减少消费者数量,便于扩展。但是队列不像多个订阅者,一旦消息者进程读取后故障了,那么消息就丢了;发布-订阅模式将消息广播到多个消费者,由于每个订阅者都订阅和处理消息,所以没有办法做并行处理。
kafka中消费者组有两个概念:队列,消费者组(consumer group)允许同名的消费者组成员瓜分处理。发布订阅:允许你广播消息给多个消费者组(不同名)。kafka的每个topic都具有这两种模式。
所有发布消息到消息队列和消费分离的系统,实际上都充当了一个存储系统(发布的消息先存储起来)。Kafka比别的系统的优势是它是一个非常高性能的存储系统。写入到kafka的数据将写到磁盘并复制到集群中保证容错性。并允许生产者等待消息应答,直到消息完全写入。kafka的磁盘结构 - 无论你服务器上有50KB或50TB,执行效率是相同的。client来控制读取数据的位置。你还可以认为kafka是一种专用于高性能,低延迟,提交日志存储,复制,和传播特殊用途的分布式文件系统。