Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。也可以把它当作是分布式提交日志的发布-订阅消息,事实上Kafka官网上也是这么说明的。
关于Kafk你必须知道的几个关键术语
topics:Kafka接收的各种各样的消息
producers:发送消息到Kafka
consumers:从Kafka接收消息的订阅者
broker:一个或多个服务器组成的Kakfa集群
下图是一个生产者通过kafka集群发送给消费者的示例
Topics和Logs
一个Topic就是将发布的消息归类的过程,对于每一个topic,Kafka集群都会维护一个分区日志,如下图
每个分区都是有编号的,而且每个分区的消息也会根据提交的日志进行编号。分区中的消息会被分配一个唯一的编号,这个术语叫做offset,用以识别分区中的消息。
Kafka集群会保存所有的发布消息,无论这些消息在固定的时间内是否被消费者所消费。比如,消息日志设置的保存期间是2天,在消息发布的2天内,消费者可以消费,然后丢弃该条消息来释放空间。Kafka的性能跟数据空间无关,因此保存大量数据对于Kafka来说不是问题。
实际上,在日志中保存每个消费者位置的元数据才是“offset”。offset是由消费者控制的:一般来说,当消费者一行行读取消息时,offset才起作用。但实际上,消费者可以以任意他们想要的方式读取消息,因为消费者可以重置已存在的offset。
这种机制表明Kafka消费者是非常容易处理的-消息的处理对于集群或其它消费者来说几乎没有什么影响。比如,我们可以在命令行工具中使用“tail”topic来处理消息而不用改变已经存在的消费者。
日志分区有几种不同的目的。首先,能够避免一台服务器上的日志文件过大。每个独立的分区肯定位于同一台服务器上,并且在同一台服务器上处理,但是一个topic可能有多个分区,这样能够保证处理大量的数据。其次,分区可以作为并行处理的单元。
分布式
日志分布在Kafka集群中的不同分区上,每个服务器处理数据并请求共享分区。每个分区都是可以通过配置服务器的容错机制进行复制的。
每个分区都有一个服务器作为“leader(主节点)”,有0个或多个服务器作为“followers(从节点)”,主节点可以从分区中读写数据,但是从节点只能复制主节点的消息。如果主节点宕机,其中的一个从服务器会自动成为新的主服务器。主服务器处理一些分区的数据,从服务器处理其它服务器的数据,这样保存集群的平衡。
生产者(Producers)
生产者可以决定将消息发送到哪些topic,而且生产者可以选择将topic内的消息发送到哪个分区。这种简单的循环负载均衡方式能够在语义分区时完成。这种分区通常在1秒内完成。
消费者(Consumers)
传统的消息队列有两种处理方式:顺序处理和发布/订阅处理。在顺序处理方式时,消费者是按照消息进入消息队列的顺序进行读取的。发布/订阅方式则是将消息广播给所有的消费者。Kafka提供了一种抽象的方式-消费者分组(consumer group)来满足消息的以上两种处理方式。
每个消费者都有一个组名,只有订阅的消费者在对应的组中时,发布到topic中的消息才会传递给消费者对象。消费者对象可以在不同的进程或主机中存在。
如果所有的消费者对象的组名都相同,这就好比是传统的顺序队列,消费者平均分配这些消息。
如果所有的消费者对象的组名都不相同,这就好比是发布/订阅模式,消费者只接受订阅的消息。
通常来说,订阅某一主题(topic)的消费者在同一组的有多个,这是为了系统的稳定和容错。下图是一个具体的示例。
Kafka比传统的消息队列拥有更高的排序可靠性。