赞
踩
本文翻译至Kafka - Introduction
Apache Kafka是一个开源流处理平台!
一个流处理平台必须有三大核心功能:
kafka通常用于两大类型的应用:
首先几个概念:
Kafka有四个核心的API:
在Kafka中,服务端与客户端之间的通信是由一个简单、高性能、语言无关的TCP协议实现的。此协议已版本化并保持向后兼容。
Kafka中的几个关键词:Log、Record、Topic、Partition、Producer、Consumer、Offset、Group
Kafka记录中一个核心的抽象就是topic。
topic就是publisher发布record的类别和consumer订阅源的名称。
一个topic可以被0个、1个或多个消费者订阅。
在Kafka集群中的每一个topic都维护了一个被切分的log,topic内的log被切分成多个partition。
每一个partition都是有序、不变的record顺序组成的,并且持续在末端附加新的record。在partition中的每一个record都被分配了一个被称为offset的顺序id号,用于唯一确定record在partition中的位置(topic + partition id + offset可以确定一个唯一的record)。
Kafka集群可以被配置永久存储所有发布的record,不管它们有没有被消费。例如,如果保留策略(retention policy)设置为2天,则在record发布的两天内它是可被消费者使用的,之后将会被丢弃然后释放空间。Kafka的性能是恒定的,与存储数据的多少无关,所以长时间存储数据是没问题的。
Kafka’s performance is effectively constant with respect to data size so storing data for a long time is not a problem.
事实上,每一个消费者(consumer)唯一保留的元数据是该消费者在log中的offset。消费者的offset是由消费者自己控制的,通常offset会随着消费者消费(consume)record而线性增大。但实际上,因为offset由消费者自己控制,所以它可以在任意位置消费record。例如,消费者可以重置offset到已经消费过的位置重新消费;也可以跳过未消费的record到partition的末端开始消费。
Kafka的消费者消费记录和重置offset对集群和其他消费者没有太大影响。
为log分区有多个目的:
(英文中的handle真是不好翻译,估计只有“搞”这个词可以与之对应了)
log的partition分布在Kakfa集群中的服务器上,每一个服务器都可以处理数据并共享partition。每个partition可以配置备份数量以实现容错(partition备份数不应超过服务器数量)。
每个partition会有一个leader和0个或多个followers。leader处理该partition所有的读写请求,follower被动的复制leader。如果leader挂了,其中一个follower会自动地成为新的leader。Kafka中地每一个服务器都充当部分partition的leader和部分partition的follower,所以集群负载非常均衡。
Kafka使用replication实现容错。
Kafka的MirroMaker提供了集群的异地备份支持。通过MirroMaker可以实现message跨多个数据中心和云的备份。你可以在主动-被动场景下备份和恢复数据;或者在主动-主动场景下,将数据放置在离用户更近的位置,或支持数据位置要求。
producer用于发布数据到它指定的topic。producer负责确定record分配到指定topic的哪个partition。这样可以使用轮询方式实现一个很简单的负载均衡,它也可以使用语义分区函数实现负载均衡(根据record中的一些关键词key来实现发送至某一分区)。
record分配到哪个partition是由producer指定的,一般以轮询和设置key的方式指定partition。
consumer使用group来归类。每一个发布到topic的record会被传递至每一个订阅该topic的group中的一个consumer。
如果所有的consumer都在同一个group中,record将会在consumer中进行负载均衡(根据负载均衡策略发送至指定partition,只有分配到该partition的consumer才能读取该partition的数据)。
如果所有的consumer都在不同的group中,每一个record都将会广播至所有的consumer。
通常情况下,topic只有少量的消费者group,每一个都是逻辑订阅者。每一个group都有多个consumer组成,用于弹性扩展和容错。订阅者是消费者集群而不是单个进程。
在Kafka中实现消费的方式是给consumer分配log的partition,所以每一个consumer在任何时间点都是公平的分配。
由Kafka动态维护group成员。如果有新的consumer加入group,它将从group内的其他成员上接管部分partition;如果一个consumer无效了,它的partition将会被分配给group内其他的consumer。
Kafka只能提供partition内的record是有序的,并能保证topic不同partition之间数据有序。对于大多数应用而言,partition有序结合按key区分数据的能力就足够了。然而,如果你需要record完全有序,可以通过只设置一个partition实现,这就意味着每个group内只能有一个consumer。
你可以发布以多租户方式发布Kafka。
在高级别Kafka提供以下保证:
Kafka保证record的读写顺序和服务容灾!
Kafka的流概念与传统的企业消息系统有什么区别?
Messaging通常由两种模式:消息队列(queuing)和发布-订阅(publish-subscribe)。在队列中,一个consumer池可能从一个server上读取数据,每个record只能到其中一个consumer。在发布-订阅模式下,record会广播至所有consumer。这两者都有自身的优点和缺点。队列的优点是它允许在多个consumer中划分数据处理,可以使你弹性扩展处理程序。不幸的是,消息队列没有多订阅,一旦数据被读取就没有了。发布-订阅允许你广播数据至多个处理程序,但是没有方法弹性扩展处理程序,因为每一条消息都会发送至所有订阅者。
Kafka的消费者分组(consumer group)同时实现了这两个概念。想消息队列一样,在group内允许划分数据处理。与发布-订阅类似,Kafka允许将message广播至所有的group。
Kafka模式的优点是每一个topic都有两个属性:它可以弹性扩展处理程序,它也允许多订阅。
与传统的消息系统相比,Kafka有很强的顺序保证。
传统的消息队列在服务器上都是顺序保存record,如果有多个consumer从队列中消费数据时,则服务器按照存储的顺序分发数据。然而,虽然服务器按顺序分发数据,但是数据是异步传递至consumer,所以可能到达不同的消费者中的数据是无序的。这意味着在并行消费时存在会丢失record顺序的可能。消息系统解决这个问题的方法通常是只允许一个进程从队列中消费,但是这意味着不能并行处理数据。
Kafka很好的解决了这个问题。通过topic的parition实现并行概念。Kafka可以为consumer的处理程序提供顺序保证和负载均衡。这是通过分配topic的partition到group中的consumer实现的,所以每一个partition会被一个topic内特定的consumer消费。为了实现这个,我们必须确保该partition只有这个consumer唯一可读,并且顺序消费数据。虽然有很多partition,但是这仍然可以实现多个consumer的负载均衡。但请注意,在一个group中consumer的个数不能超过partition的数量(因为超过将有consumer不能分配partition,从而无法读取数据)。
任何消息队列都允许发布与消费message分离,这实际为in-flight(未被消费)的message充当了存储系统。Kafka的不同之处在于它是一个非常优秀的存储系统。
写入Kafka的数据会写入磁盘并复制以实现容错。Kafka允许producer等待确认,所以一次写入不被认为完成直到它完全备份,并且即使写入的服务器失败也保证写入仍然存在。
磁盘存储数据使得Kafka有很好的扩展性。不管在服务器上保存50KB还是50TB数据,Kafka的性能都是一样的。
The disk structures Kafka uses scale well—Kafka will perform the same whether you have 50 KB or 50 TB of persistent data on the server.
有严谨的存储和允许客户端控制读取的位置,你可以认为Kafka是一种专用于高性能、低延迟提交log存储、备份和传播的特殊分布式文件系统。
As a result of taking storage seriously and allowing the clients to control their read position, you can think of Kafka as a kind of special purpose distributed filesystem dedicated to high-performance, low-latency commit log storage, replication, and propagation.
仅用于读、写和存储数据是不够的,Kafka还可以实现实时的流处理。
在Kafka中,流处理器可以是从输入topic中读取连续数据流的任何东西,在它的输入中执行一些处理,然后产生持续的流数据到输出topic。
使用producer和consumer API直接执行处理是可能的。然后,更多的一些复杂的转换Kafka提供了一个完全集成的Streams API。它允许构建非平凡处理的应用程序,这些应用程序可以计算流的聚合或将流连接在一起。
Streams API可以帮助解决此类应用程序面临的难题:处理无序的数据、在代码更改时重新处理输入、执行有状态的计算等等。
Streams API基于Kafka提供的核心原语构建:它使用producer和consumer API进行输入,使用Kafka进行有状态存储,在流处理器实例之间使用相同的group实现容错。
消息系统、存储和流处理的组合可能看起来很不寻常,但是对Kafka作为一个流处理平台来说是至关重要的。
像HDFS这样的分布式文件系统允许存储静态文件以进行批处理。像Kafka这样的系统允许存储和处理过去的历史数据。
传统的企业消息系统允许处理订阅后到达的message。使用Kafka构建的应用程序也是一样的。
Kafka结合了这两个功能,这两个功能结合对于Kafka被用作为流处理应用平台和流管道非常重要。
由于结合了存储和低延迟订阅,流应用可以以相同的方式对待过去和未来的数据。也就是说,单个应用程序可以处理历史存储的数据,而不是当它到达最后一条记录时结束,它可以继续处理未来到达的数据。这就是一般的包含批处理和消息驱动程序的流处理概念。
同样的,结合了实时事件订阅的流处理管道使其有可能使用Kafka实现非常低延迟的管道;但是,可靠的数据存储能力使其可用于保证关键数据传递,或用于与仅定期加载数据的离线系统集成,或可停机一段时间维护。流处理功能使它可在数据到达时对其进行转换。
Kafka是一个具有存储和流处理功能的消息系统。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。