Kafka笔记(一)Kafka介绍


本文翻译至Kafka - Introduction

Apache Kafka是一个开源流处理平台!
一个流处理平台必须有三大核心功能:

  • 发布和订阅记录流(stream of records),类似消息队列或企业消息系统
  • 以容错的持久方式存储记录流
  • 当记录流发生时处理它

kafka通常用于两大类型的应用:

  • 构建可在系统或应用程序之间可靠获取数据的实时流数据管道
  • 构建转换或响应数据流的实时流应用程序

首先几个概念:

  • Kafka以集群的方式运行在一个或多个服务器上,它可以横跨多个数据中心
  • Kafka集群的记录流(stream of records)以topic的方式分类存储(以topic区别不同的record)
  • 每一个记录(record)由key、value和timestamp组成

Kafka有四个核心的API:

  • Producer API允许程序发布记录流至一个或多个topic
  • Consumer API允许程序订阅一个或多个topic,并处理生成的记录流
  • Streams API允许程序作为一个流处理器,从一个或多个topic中消费一个输入记录流,然后生成一个或多个输出topic的输出流;将输入流转换成输出流。
  • Connector API允许构建和运行将Kafka的主题连接到现有程序或数据系统的可重用的生产者或消费者

在Kafka中,服务端与客户端之间的通信是由一个简单、高性能、语言无关的TCP协议实现的。此协议已版本化并保持向后兼容。

Kafka中的几个关键词:Log、Record、Topic、Partition、Producer、Consumer、Offset、Group

  • Log 日志,指Kafka内全部的记录(Record)集合
  • Record 记录,是Kafka的存储单元,由key、value和timestamp组成
  • Topic 主题,是Log的分类,一个Record只属于一个Topic
  • Partition 分区,是Topic内Log的一个分区,一个Topic的Log可以划分成1或多个Partition;一个Partition同一时间最多只能有一个Consumer可以消费;一个Partition里的记录是永久有序的;Partition和Group构成了Kafka负载均衡的基础
  • Producer 是Record的生成者,负责发送数据至Kafka中指定的Topic内的某一Partition
  • Consumer 是Record的消费者,一个Consumer订阅多个Topic,并可以分配至多个Partition;当Consumer从Partition读取一条数据后,与该Partition-Consumer关联的Offset将会+1,直至到达该Partition的尾部
  • Offset 偏移,是记录Consumer在Partition消费的起始位置,Offset可以由Consumer设置为Partition的任意位置
  • Group 是Consumer的分组,在一个Group内Consumer个数不应多余订阅的Topic的Partition数;Topic内的一个Record最多只能被Group内的一个Consumer消费;多个Group之间无影响

Topic和Log

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分区有多个目的:

  • 第一,允许log扩展而不受单机服务器的大小的限制。每一个独立的分区必须适合它所在的服务器,但是一个topic可以有多个分区,所以Kafka可以处理任意数量的数据。
  • 第二,它们充当了并行的单元。

(英文中的handle真是不好翻译,估计只有“搞”这个词可以与之对应了)

Distribution(分布)

log的partition分布在Kakfa集群中的服务器上,每一个服务器都可以处理数据并共享partition。每个partition可以配置备份数量以实现容错(partition备份数不应超过服务器数量)。

每个partition会有一个leader和0个或多个followers。leader处理该partition所有的读写请求,follower被动的复制leader。如果leader挂了,其中一个follower会自动地成为新的leader。Kafka中地每一个服务器都充当部分partition的leader和部分partition的follower,所以集群负载非常均衡。

Kafka使用replication实现容错。

Geo-Replication(异地备份/灾备)

Kafka的MirroMaker提供了集群的异地备份支持。通过MirroMaker可以实现message跨多个数据中心和云的备份。你可以在主动-被动场景下备份和恢复数据;或者在主动-主动场景下,将数据放置在离用户更近的位置,或支持数据位置要求。

Producers(生产者)

producer用于发布数据到它指定的topic。producer负责确定record分配到指定topic的哪个partition。这样可以使用轮询方式实现一个很简单的负载均衡,它也可以使用语义分区函数实现负载均衡(根据record中的一些关键词key来实现发送至某一分区)。

record分配到哪个partition是由producer指定的,一般以轮询和设置key的方式指定partition。

Consumers(消费者)

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。

Multi-tenancy

你可以发布以多租户方式发布Kafka。

Gurantees

在高级别Kafka提供以下保证:

  • producer发送的消息(message)将会按发送顺序附加至指定topic的partition。如果M1和M2由相同的producer发送,M1先发送,那M1的offset将会比M2小(发送到同一个partition的情况),并且会比M2更早的添加到log。
  • consumer是安装record存储在log中的顺序消费的。
  • 如果一个topic的备份数设置为N,则Kafka允许最多N-1个服务器失效而不会丢失commit到log的record。

Kafka保证record的读写顺序和服务容灾!

Kafka作为一个消息系统

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,从而无法读取数据)。

Kafka作为一个存储系统

任何消息队列都允许发布与消费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还可以实现实时的流处理。

在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是一个具有存储和流处理功能的消息系统。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值