Kafka简介
Kafka用于构建实时数据管道和流应用程序。 它的特点是水平可伸缩性scalable,容错性,快速性,kafka在数千家公司中投入生产环境使用。比较知名的有Uber,netflix等等,都是利用kafka构建了其业务。
kafka有三个关键特性:
- 发布和订阅stream of records,类似于message queue和enterprise messaging system。
- 以可容错且持久的方式存储record stream。
- 按照流的顺序处理流。
Kafka通常用于两大类应用程序:
- 建立实时流数据管道,让我们可以可靠地在系统或应用程序之间获取数据
- 构建实时流应用程序,让我们可以转换或响应流中的数据
kafka的特点是
- Kafka在一个或多个可以跨越多个数据中心data center的服务器上作为集群运行。
- Kafka集群将stream of record存储在kafka topics中。
- 每个record由一个键key,一个值value和一个时间戳timestamp组成。
kafka提供了下面这些核心的API
- Producer API允许应用程序将记录流发布到一个或多个Kafka的topic当中。
- Consumer API允许应用程序订阅一个或多个topic并处理为其生成的记录流。
- Streams API允许应用程序充当流处理器,使用一个或多个topic的输入流,并生成一个或多个输出topic的输出流,从而有效地将输入流转换为输出流。
- Connector API允许构建和运行将Kafka topic连接到现有应用程序或数据系统的producer或consumer。 例如,关系数据库的connector 可以捕获对表的所有更改。
在Kafka中,客户端和服务器之间的通信是通过简单,高性能,与语言无关的TCP协议完成的。 该协议已版本化,并与旧版本保持向后兼容性。 我们为Kafka提供了Java客户端,但是客户端支持多种语言。
Topic 和log
首先,让我们深入探讨Kafka提供的流记录的核心抽象-topic。
topic是record发布到的一个抽象。 Kafka中的topic始终是支持多个subscriber的; 也就是说,一个topic可以有零个,一个或多个消consumer来subscribe写入该topic的数据。这一点与rabbitmq有本质区别,因为rabbitmq可以定义只能被consume一次的topic。
对于每个topic,Kafka集群都会维护一个分区日志 partitioned log ,如下图所示:
每个partition都是一个有序的ordered,不变immutable的记录序列sequence of records,这些record持续地加到一个structured的提交日志commit log中。 kafka为partition中的每一个record分配了一个sequential ID号,称为offset->偏移号,该ID号可以唯一标识单个partition中的每个record。
Kafka 集群持久地保存所有已发布的记录,无论它们是否已使用可配置的保留期使用。 例如,如果保留策略设置为两天,则在record publish后的两天内,它可以使用,然后在两天过去后将其discarded以释放空间。 Kafka 的性能在数据大小方面实际上是恒定的,这意味着长时间存储数据不是问题。
每个consumer保留的唯一元数据metadata 是该consumer在partion log中的offset。 这个偏移量是由consumer控制的。 通常,consumer在读取记录时会线性增加其offset,但是,因为offset由消费者控制,它可以以任何顺序消费record。 例如,消费者可以重置为较旧的offset以重新处理过去的数据或跳到最近的记录并从“现在”开始消费。
这种功能组合意味着 Kafka consumer可以自由的控制自己的消费行为,而不会对集群或其他消费者consumer产生影响。 例如,您可以使用命令行工具来“跟踪”tail任何topic的内容,而无需更改现有消费者使用的内容。
log的partition允许它扩展到超出单个服务器的大小。 每个单独的partition必须适合托管它的服务器,但一个topic可以有许多partition,因此它可以处理任意数量的数据。 partition也可以作为并行单元。
Distribution
日志的partition分布在Kafka群集中的服务器上,每台服务器处理数据并要求共享分区。 每个分区都跨可配置数量的服务器进行复制,以实现容错功能。
每个partition都有一个充当“leader”的服务器和零个或多个充当“follower”的服务器。 leader处理对partition的所有读写请求,而followe则被动地复制leader。 如果leader fail了,则followe之一将自动成为新leader。对于每个服务器而言,该服务器中的某些partition充当leader,而其他partition充当follower,因此群集中的负载得到了很好的平衡。也就是说实际情况中,当kafka server按集群部署时,有的topic的leader partition在server A,而有的topic的leader partition在server B。
Geo-Replication
Kafka MirrorMaker为集群提供地理复制支持。 使用MirrorMaker,可以在多个数据中心或云区域中复制消息。 可以在主动/被动方案中使用它进行备份和恢复。 或在主动/主动方案中将数据放置在离用户更近的位置,或支持数据位置要求。
Producer生产者
生产者将数据发布到他们选择的topic。 生产者负责选择将哪个记录分配给topic中的哪个分区。 可以以循环方式完成此操作,仅是为了平衡负载,也可以根据某些语义分区功能(例如基于记录中的某些键)进行此操作。
Consumer消费者
Consumers使用 consumer group 名称标记自己,并且发布到topic的每条记录都会传递到每个订阅消费者组中的一个消费者实例。 Consumer实例可以在单独的进程中或在单独的机器上。
如果所有Consumers实例都具有相同的使用者组,那么将在这些使用者实例上有效地平衡记录。
如果所有consumer 实例具有不同的使用者组,则每个记录将广播到所有使用者进程。
由两台服务器组成的Kafka群集,其中包含四个带有两个使用者组的分区(P0-P3)。消费者组A有两个消费者实例,组B有四个。
但是,更常见的是,我们发现主题具有少量的消费者组,每个“逻辑订户”一个。每个组均由许多使用者实例组成,以实现可伸缩性和容错能力。这无非就是发布-订阅语义,其中订阅者是消费者的集群而不是单个进程。
在Kafka中实现使用的方式是通过在使用方实例上划分日志中的分区,以便每个实例在任何时间点都是分区“公平份额”的排他使用方。 Kafka协议动态处理了维护组成员身份的过程。如果新实例加入该组,它们将接管该组其他成员的某些分区;如果实例死亡,则其分区将分配给其余实例。
Kafka仅提供分区中记录的总顺序,而不提供主题中不同分区之间的记录。对于大多数应用程序,按分区排序以及按键对数据进行分区的能力就足够了。但是,如果您需要记录的总订单量,则可以使用只有一个分区的主题来实现,尽管这将意味着每个使用者组只有一个使用者流程。
Kafka作为消息传递系统
传统上,消息传递有两种模型:queuing和发布-订阅。在队列中,一组使用者可以从服务器中读取内容,并且每条记录都将转到其中一个。在发布-订阅记录中广播给所有消费者。这两个模型中的每一个都有优点和缺点。排队的优势在于,它允许您将数据处理划分到多个使用者实例上,从而扩展处理量。不幸的是,队列不是多用户的—一次进程读取了丢失的数据。发布-订阅允许您将数据广播到多个进程,但是由于每条消息都传递给每个订阅者,因此无法扩展处理。
Kafka的消费者群体概念概括了这两个概念。与队列一样,使用者组允许您将处理划分为一组进程(使用者组的成员)。与发布订阅一样,Kafka允许您将消息广播到多个消费者组。
Kafka模型的优点在于,每个主题都具有这些属性-可以扩展处理范围,并且是多订阅者-无需选择其中一个。
与传统的消息传递系统相比,Kafka还具有更强的订购保证。
传统队列将记录按顺序保留在服务器上,如果多个使用者从队列中消费,则服务器将按记录的存储顺序分发记录。但是,尽管服务器按顺序分发记录,但是这些记录是异步传递给使用者的,因此它们可能在不同的使用者上乱序到达。这实际上意味着在并行使用的情况下会丢失记录的顺序。消息传递系统通常通过“专有使用者”的概念来解决此问题,该概念仅允许一个进程从队列中使用,但是,这当然意味着在处理中没有并行性。
Kafka做得更好。通过在主题内具有并行性(即分区)的概念,Kafka能够在用户进程池中提供排序保证和负载均衡。这是通过将主题中的分区分配给消费者组中的消费者来实现的,以便每个分区都由组中的一个消费者完全消费。通过这样做,我们确保使用者是该分区的唯一读取器,并按顺序使用数据。由于存在许多分区,因此仍然可以平衡许多使用者实例上的负载。但是请注意,使用者组中的使用者实例不能超过分区。
Use case
Messaging消息传递
Kafka可以很好地替代传统消息中间件message broker。 消息中间件的使用有多种原因(将处理与数据生产者分离,缓冲未处理的消息等)。 与大多数消息中间件相比,Kafka具有更好的吞吐量,内置的分区,复制和容错能力,这使其成为大规模消息中间件应用程序的理想解决方案。
根据经验,消息中间件的使用通常吞吐量较低,但是可能需要较低的端到端延迟,并且通常取决于Kafka提供的强大的持久性保证。
在此领域中,Kafka与ActiveMQ或RabbitMQ等传统消息中间件功能相当。
Website Activity Tracking网站活动跟踪
Kafka最初的用例是能够将用户活动跟踪管道重建为一组实时的发布-订阅供稿。 这意味着将网站活动(页面浏览,搜索或用户可能采取的其他操作)发布到中心主题,每种活动类型只有一个主题。 这些提要可用于一系列用例的订阅,包括实时处理,实时监控,以及加载到Hadoop或脱机数据仓库系统中以进行脱机处理和报告。
活动跟踪通常量很大,因为每个用户页面视图都会生成许多活动消息。
Metrics
Kafka通常用于记录操作的监控数据。 这涉及汇总来自分布式应用程序的统计信息,以生成集中的运行数据提要。
Log Aggregation日志聚合
许多人使用Kafka代替日志聚合解决方案。 日志聚合通常从服务器收集物理日志文件,并将它们放在中央位置(也许是文件服务器或HDFS)以进行处理。 Kafka提取文件的详细信息,并将日志或事件数据作为消息流进行更清晰的抽象。 这允许较低延迟的处理,并且更容易支持多个数据源和分布式数据消耗。 与以日志为中心的系统(如Scribe或Flume)相比,Kafka具有同样出色的性能,由于复制而提供的更强的耐用性保证以及更低的端到端延迟。
Stream Processing流处理
Kafka的许多用户在由多个阶段组成的处理管道中处理数据,其中原始输入数据从Kafka topic中使用,然后进行汇总,充实或以其他方式转换为新主题,以供进一步使用或后续处理。 例如,用于推荐新闻文章的处理管道可能会从RSS提要中检索文章内容,并将其发布到“文章”主题中。 进一步的处理可能会使该内容规范化或重复数据删除,并将清洗后的文章内容发布到新主题中; 最后的处理阶段可能会尝试向用户推荐此内容。 这样的处理管道基于各个主题创建实时数据流的图形。 从0.10.0.0开始,Apache Kafka中提供了一个轻量但功能强大的流处理库,称为Kafka Streams,可以执行上述数据处理。 除了Kafka Streams,其他开源流处理工具还包括Apache Storm和Apache Samza
Event Sourcing
事件源是一种应用程序设计样式,其中状态更改以时间顺序记录记录。 Kafka对大量存储的日志数据的支持使其成为使用这种样式构建的应用程序的绝佳后端。
Commit Log
Kafka可以用作分布式系统的一种外部提交日志。 该日志有助于在节点之间复制数据,并充当故障节点恢复其数据的重新同步机制。 Kafka中的日志压缩功能有助于支持此用法。 在这种用法中,Kafka与Apache BookKeeper项目相似。