kafka简介
kafka简介
翻译自Kafka官网 Introduction:http://kafka.apache.org/intro
kafka是一个分布式流平台(distributed streaming platform)
既然是流平台就具有三大特性:
- 发布和订阅记录流,类似于消息队列或企业消息传递系统。
- 以容错的持久方式存储记录流。
- 处理记录流。
kafka通常用于两大类应用程序:
- 建立实时流数据管道,就能可靠地在系统或应用程序之间获取数据
- 构建实时流应用程序来转换或响应数据流
首先几个概念:
- Kafka在一个或多个可以跨越多个数据中心的服务器上作为集群运行。
- Kafka集群将记录流存储在称为topic的类别中。
- 每个记录由一个键,一个值和一个时间戳组成。
Kafka具有四个核心API:
-
.Producer API:允许应用程序发布的记录流给一个或多个kafka的topic。
-
Consumer API :允许应用程序订阅一个或多个topic,并处理对他们产生的记录流。
-
Streams API :允许一个应用程序作为一个流处理器,消费来自一个或者多个topic的输入流,并且生产一个输出流给一个或者多个输出主题,能有效地将输入流转换为输出流。
-
Connector API :允许构建和运行可重复使用的生产者或消费者以现有的应用程序或数据库连接kafka topic。例如,关系数据库的连接器可能会捕获任何对表的修改。
在Kafka中,客户端和服务器之间的通信通过TCP完成的,为Kafka提供了Java客户端,但是客户端支持多种语言。
Topic and Logs(主题和日志)
一个主题是那些被发布记录的类别或者订阅源名称。kafka中的topic始终是多订阅者的,也就是说,一个topic可以有0个,一个或是更多的消费者来订阅那些写入该topic的数据。kafka集群对每个topic都保持一个分区日志,如下图所示:
如图2所示,每个分区都是排好序的且不变的记录序列,这些记录连续地附加到—结构化的提交日志。分区中的每一个记录都标识了一个顺序ID号(被称为偏移),它作为分区中每个记录的唯一标识。
kafka集群使用一个可配置的保留期限去持久化所有已经发布的记录(无论他们有没有被消费)。例如,将保留(期限)策略设置为2天,那么在该记录发布后的2天内,是可以被消费的,期限过后该记录就会被丢弃并释放空间。对于数据的大小来说,kafka的性能是恒定的,所以长时间存储数据不是问题。
如上图所示,实际上,基于每个消费者保留的唯一元数据是该消费者在日志中的偏移量或位置。该偏移量由消费者控制:一般来说,一个消费者在读数据时会线性偏移,但是事实上,偏移量由消费者控制,他可以以任意顺序消费记录。例如,一个消费者可以重置到一个旧的偏移量去重新处理过去的数据或者跳过/跳到最近的记录并且从"现在"开始消费。
这些功能的组合意味着Kafka的消费者非常便宜—它们来来回回对集群或者其他的消费者没有多大的影响。例如,你可以使用命令行工具“跟踪(tail)”任何主题的内容,而不用改变任何现有消费者所消费的主题内容。
日志中的分区有多种用途。首先,它们允许日志扩展到超出单个服务器所能容纳的大小。每个单独的分区都必须适合托管它的服务器,但是一个主题可能有很多分区,因此它可以处理任意数量的数据。其次,它们充当并行性的单元——稍有更多。
Distribution(分配)
分区日志分布在Kafka集群的服务器上,每个服务器处理数据并且要求共享分区。为了容错性,每个分区都在可配置数量的服务器之间复制。
每个分区都有一个充当“leader”的服务器和零个或多个充当“followers”的服务器。领导者处理对分区的所有读写请求,而跟随者则被动地复制领导者。如果领导者失败了,则其中一个跟随者将自动成为新领导者。每个服务器充当这些中某个分区的领导者,并且充当其他分区的跟随者,因此群集中的负载得到了很好平衡。
Geo-Replication(地理复制)
Kafka MirrorMaker为您的集群提供地理复制支持。通过MirrorMaker,可以在多个数据中心或云区域之间复制消息。您可以在主动/被动方案中使用它进行备份和恢复;或在主动/主动方案中将数据放置在离您的用户更近的位置,或支持数据本地化要求。
Producers(生产者)
生产者将数据发布到他们选择的主题。生产者负责选择将哪个记录分配给主题中的哪个分区。可以以循环方式完成此操作,仅是为了负载均衡,也可以根据某些语义分区函数(例如基于记录中的某些键)进行此操作。一秒钟就可以了解更多有关分区的信息!
Consumers(消费者)
消费者使用消费者组名称标记自己,并且发布到主题的每条记录都会被传递到每个订阅消费者组中的一个消费者实例。消费者实例可以在单独的进程中或在单独的机器上。
如果所有消费者实例都具有相同的消费者组,那么这些记录将在这些使用者实例上有效地负载平衡。
如果所有消费者实例具有不同的消费者组,则每条记录将广播到所有消费者进程。
上图4包含两台服务器的Kafka集群,它拥有四个带有两个消费者组的分区(P0-P3)。消费者组A有两个消费者实例,消费者组B有四个。
然而,显而易见,我们发现主题具有少量的消费者组,每个“逻辑订阅者”一个。每个组由许多消费者实例组成,以实现可伸缩性和容错性。这无非就是发布-订阅的含义,其中订阅者是一个消费者的集群而不是单一的进程。
在Kafka中实现消耗的方式是通过在消费者实例上划分日志中的分区,以至于每个实例在任何时间点都是分区的“公平共享”的独有消费者。维护组中成员身份的过程是通过Kafka协议动态处理的。如果新实例加入该组,它们将着手该组其他成员的某些分区;如果某个实例死亡,则其分区将分配给其余存活的实例。
Kafka只提供了记录总数中的一个分区,而不在主题中的不同分区之间。对于大多数应用程序,结合分区排序以及按键对数据进行分区的能力就足够了。但是,如果您需要记录总数,则可以通过只有一个分区的主题来实现,尽管这将意味着每个使用者组只有一个消费者进程。
Multi-tenancy(多租户)
您可以将Kafka部署为多租户解决方案。通过配置哪些主题可以产生或使用数据来启用多租户。为配额也有运营支持。管理员可以对请求定义和实施配额以控制客户端使用的代理资源。了解更多信息,请参阅安全性文档。
Guarantees(保证金)
Kafka在高级别上,提供以下保证:
生产者发送到消息特定主题分区将按其发送的顺序追加。也就是说,如果一条记录M1是由与记录M2相同的生产者发送的,并且M1首先发送的,则M1的偏移量将小于M2,并在日志中更早地出现。
一个使用者实例按记录在日志中的存储顺序查看记录。
对于复制因子为N的主题,我们将最多可以允许N-1个服务器故障,而保证不会丢失提交给日志的任何记录。
有关这些保证的更多详细信息提供在文档的设计部分中了。
Kafka as a Messaging System(kafka作为消息传递系统)
Kafka的流概念与传统的企业消息传递系统相比如何?
传统上,消息传递具有两种模型:排队和发布-订阅。在队列中,一组使用者可以从服务器读取数据,并且每条记录都进入其中一个;在发布-订阅记录中广播给所有消费者。这两个模型中各自都有优缺点。排队的优势在于,它允许您将数据处理划分到多个使用者实例上,这使您可以扩展你的处理进程。不幸的是,队列不是多订阅者的,一旦一个进程读取了这个数据,它就没有了。发布-订阅允许您将数据广播到多个进程,但是由于每条消息都传递给每个订阅者,因此无法扩展处理。
Kafka的消费群体概念概括了这两个概念。与队列一样,使用者组允许您将处理划分为一组进程(消费者组的成员)。与发布订阅一样,Kafka允许您将消息广播到多个消费者组。
Kafka模型的优势在于每个主题都具有这些属性——它可以扩展处理,并且是多订阅者——无需选择其中的某一个。
Kafka相比与传统的消息传递系统,还具有更强的订购保证。
传统队列将记录按顺序保留在服务器上,如果多个使用者从队列中消费,则服务器将按记录的存储顺序分发记录。但是,尽管服务器按顺序分发记录,但是这些记录是异步传递给使用者的,因此它们可能会在不同的消费者上是无序到达的。实际上这意味着记录的顺序在并行消费的情况下会丢失。消息传递系统通常通过具有“专有消费者”的概念来解决此问题,该概念仅允许一个进程从队列中去消费,但是,这当然意味着在处理中没有并行性。
Kafka这方面做得更好。通过在主题内具有并行性的概念(即分区),Kafka能够在消费者进程池中提供排序保证和负载均衡。这是通过将主题中的分区分配给消费者组中的消费者来实现的,以便每个分区都由组中的一个消费者完全消费。通过这样做,我们确保使用者是该分区的唯一读取器,并按顺序使用数据。由于存在许多分区,因此仍然可以平衡许多使用者实例上的负载。但是请注意,使用者组中的使用者实例不能超过分区。
Kafka as a Storage System(kafka作为存储系统)
任何允许发布与使用无关的消息发布的消息队列都有效地充当了运行中消息的存储系统。Kafka的不同之处在于它是一个非常好的存储系统。
写入Kafka的数据将写入磁盘并进行复制以实现容错功能。Kafka允许生产者等待确认,以便直到完全复制并确保即使写入失败的服务器也可以保留写入,写入才被认为是完整的。
Kafka的磁盘结构可以很好地扩展使用——无论服务器上有50 KB还是50 TB的持久数据,Kafka的性能都一样。
认真对待存储并允许客户端控制其读取位置的结果是,您可以将Kafka视为一种专用于高性能,低延迟提交日志存储,复制和传播的专用分布式文件系统。
有关Kafka的提交日志存储和复制设计的详细信息,请阅读此页面。
Kafka for Stream Processing(kafka用作流处理)
仅读取,写入和存储数据流是不够的,目的是实现对流的实时处理。
在Kafka中,流处理器是指从输入主题中获取连续数据流,对该输入进行一些处理并生成连续数据流以输出主题的任何东西。
例如,零售应用程序可以接受销售和发货的输入流,并输出根据此数据计算出的重新订购和价格调整流。
可以直接使用生产者和消费者API进行简单处理。但是,对于更复杂的转换,Kafka提供了完全集成的Streams API。这允许构建执行非平凡处理的应用程序,这些应用程序计算流的聚合或将流连接在一起。
该功能有助于解决此类应用程序所面临的难题:处理无序数据,在代码更改时重新处理输入,执行状态计算等。
流API建立在Kafka提供的核心原语之上:它使用生产者和使用者API作为输入,使用Kafka进行状态存储,并使用相同的组机制来实现流处理器实例之间的容错。
Putting the pieces Together(拼凑在一起)
消息传递,存储和流处理的这种组合看似不寻常,但这对于Kafka作为流平台的角色而言至关重要。
像HDFS这样的分布式文件系统允许存储静态文件以进行批处理。实际上,像这样的系统可以存储和处理过去的历史数据。
传统的企业消息传递系统允许处理将来的消息,这些消息将在您订阅后到达。以这种方式构建的应用程序会在将来的数据到达时对其进行处理。
Kafka结合了这两项功能,对于将Kafka用作流应用程序平台和流数据管道平台而言,这种结合至关重要。
通过结合存储和低延迟订阅,流应用程序可以以相同的方式处理过去和将来的数据。那是一个单一的应用程序可以处理历史记录中存储的数据,而不是在到达最后一条记录时结束,而是可以在将来的数据到达时继续进行处理。这是流处理的通用概念,它包含批处理以及消息驱动的应用程序。
同样,对于流数据管道,对实时事件的订阅组合使得可以将Kafka用于非常低延迟的管道。但是可靠地存储数据的能力使其可以用于必须保证数据传输的关键数据,或与仅定期加载数据或可能停机很长时间进行维护的脱机系统集成。流处理设备使数据到达时可以进行转换。
有关Kafka提供的担保,API和功能的更多信息,请参阅本文档的其余部分。