kafka入门
一、背景
最近需要使用kafka信息队列,这里记录一篇学习笔记,第一手资料就是kafka的官方文档,
以下内容是对官方文档的一个搬运,也是加深一下自己的理解。
kafka官网地址
kafka介绍:
官网首先介绍了一个流式平台需要有三个关键的能力:
- 发布和订阅消息,类似与我们常见的消息队列或者企业级的消息系统;
- 以容错的方式存储消息流;
- 在消息流发生时进行处理的操作。
kafka的使用的两种情况:
- 在系统和应用之间建造一个实时的数据流管道,可靠的获取他们之间的消息;
- 构建实时的数据流对应用之间的数据进行转换和反应处理。
要了解kafka是如何做到上述的事情时,我们需要了解和探讨以下几个概念
首先几个概念:
1、kafka作为一个集群的模式运行在一台或者多台服务器上;
2、kafka集群存储消息是以topic为类别存储的;
3、每一条消息包含一个key,一个value和一个时间戳。
kafka有四个核心的api
1、生产者api:它允许一个应用程序生产消息记录到一个或者多个topic上;
2、消费者api:它运行一个应用程序订阅一个或者多个topic并且可以处理上面的数据;
3、流式api:允许一个应用扮演一个流失处理器的角色,从一个或者多个topic上消费一个输出流,并且产生一个输入流到一个或者多个topic,有效的一个输出输入流的转化;
4、连接api:允许一个应用或系统创建并且运行一个可用的生产者或者消费者来连接kafka的topic,比如,一个关系型数据库的连接可能可以捕获任何一次数据变化对于表来说。
kafka在客户端和服务器之间建立通讯是依靠一个简单,高可用,和语言无关的TCP protocol,这个协议兼容了以往的版本,并且提供了java客户端,但是其他客户端也是支持的。many languages.
首先了解一下kafka的基本术语:
1、topic:kafka将消息按类别分类,每一个类别为一个topic,我们也可以理解为主题;
2、Producer:我们称为生产者对象,顾名思义就是发布消息到topic的对象;
3、Consumer:我们称为消费者,就是消费并处理topic消息的对象;
主题和日志(Topics and logs)
对于每一个topic,kafka集群都维护一个分区域的日志,如下图所示:
Anatomy of a topic
每一个分区都是有序的,不变的一个消息队列,并且可以进行添加操作,每一条消息在一个分区中都被标记了一个唯一的序列号,称之为offset(偏移量),并且在每个分区都是唯一的。
kafka集群持久的存储每一条发布过的消息,直到它们过期,不管它是否被消费,例如,一个过期时间被设置为2天,然后消息发布后的两天类可以被消费,过则不候,会被删除并且释放空间。
image.png
如上图所示:
实际上,消费者保存的元数据就只有这个offset在日志中,这个offset是由消费者控制的,正常情况下一个消费者会预先的线性的读取offset在它读取数据的时候,但是,实际上自从这个offset被消费者控制,它就可以无所欲为的随机消费按消费者喜欢的顺序,举例,一个消费者可重置一个offset来重新处理以前的数据,也可以跳过目前的数据直接处理现在的数据,这个特性意味着kafka的消费者很轻量级,它来去自如对集群和其他消费者没有什么影响,举例,你可以使用类似于tail的命令来查看任何topic中的内容并不需要更改任何的其他消费这消费的内容。kafka使用分区有几个目的,一是可以处理更多的消息,不受单台服务器的限制。Topic拥有多个分区意味着它可以不受限的处理更多的数据。第二,分区可以作为并行处理的单元。
分布式(Distribution)
日志分区被分布到kafka集群中的各个服务器上,每个服务器维护分到的分区,根据每个分区还可以复制到其他服务器上作为容错的备份,每一个分区有一个服务作为leader,0个或者多个作为followers,leader掌管着这个分区的读写,followers被动的复制数据,当leader宕机,其中的一个follower自动的变成leader,达到一个很好的平衡。
生产者(Producer)
生产者负责对topic上发送信息,生产者也负责选择发送信息到topic的哪个分区,它可以使用轮询分区列表的算法,也可以使用权重的方式进行选择。
消费者(Consumer)
消费者使用消费者组来标记自己,并且当消息被发布时,订阅过信息的消费者组得会得到通知。消费者实例会被分配到不同的机器上。
如果消费者实例都在同一个消费组,就可以理解为队列模型,如果消费者实例有不同的消费组,消息就会以广播的方式告知所有的消费者。
官方文档中给出了一个图示来便于我们更好的理解:
image.png
如图所示,一个由两个kafka服务,4个分区组成的kafka集群,消费组A和B分别有2个或4个消费实例。
kafka中的消费方式的实现是通过划分日志中的分区,以便于每个实例在任何都是分区的公平共享者,kafka通过动态协议处理了组内每个实例的关系,如果有一个新的实例加入,它会立刻的复制其他成员的分区数据,如果一个实例死掉,它的分区将会被分发到存活的实例上。
正像传统的消息系统一样,Kafka保证消息的顺序不变。传统的队列模型保持消息,并且保证它们的先后顺序不变。但是, 尽管服务器保证了消息的顺序,消息还是异步的发送给各个消费者,消费者收到消息的先后顺序不能保证了。这也意味着并行消费将不能保证消息的先后顺序。用过传统的消息系统的同学肯定清楚,消息的顺序处理很让人头痛。如果只让一个消费者处理消息,又违背了并行处理的初衷。 在这一点上Kafka做的更好,尽管并没有完全解决上述问题。 Kafka采用了一种分而治之的策略:分区。 因为Topic分区中消息只能由消费者组中的唯一一个消费者处理,所以消息肯定是按照先后顺序进行处理的。但是它也仅仅是保证Topic的一个分区顺序处理,不能保证跨分区的消息先后处理顺序。 所以,如果你想要顺序的处理Topic的所有消息,那就只提供一个分区。
kafka的保证(Guarantees)
高可用的kafka有如下几点保证:
1、消息被生产者发送到一个特定的topic中的一个分区,展现的顺序是和发送的顺序一致的;
2、一个消费者实例看到的消息和日志中存储的消息顺序一致;
3、如果一个Topic配置了复制因子(replication factor)为N, 那么可以允许N-1服务器宕机而不丢失任何已经提交(committed)的消息。
kafka作为一个消息系统:
kafka和传统的消息系统的异同:
传统的消息系统有两种模式,队列模式和发布订阅模式,在队列模式中,服务中的数据会被消费者池中的消费者瓜分,在发布订阅模式中消息会被广播到每一个消费者中,两种模式个有利弊,队列模式下,允许消息被多个消费者实例瓜分,但是队列模式不支持一个多订阅者,一个消息被消费以后就没了。发布订阅模式下运行你广播给多个处理者,但是由于每个订阅者都收到了消息,就no way of scaling processing since every message goes to every subscriber.
这句话不是很理解。
kafka有比传统的消息系统更强的顺序保证。
传统的消息系统按顺序保存数据,如果多个消费者从队列消费,则服务器按存储的顺序发送消息,但是,尽管服务器按顺序发送,消息异步传递到消费者,因此消息可能乱序到达消费者。这意味着消息存在并行消费的情况,顺序就无法保证。消息系统常常通过仅设1个消费者来解决这个问题,但是这意味着没用到并行处理。
kafka做的更好。通过并行topic的parition —— kafka提供了顺序保证和负载均衡。每个partition仅由同一个消费者组中的一个消费者消费到。并确保消费者是该partition的唯一消费者,并按顺序消费数据。每个topic有多个分区,则需要对多个消费者做负载均衡,但请注意,相同的消费者组中不能有比分区更多的消费者,否则多出的消费者一直处于空等待,不会收到消息。
kafka作为一个存储系统
所有发布消息到消息队列和消费分离的系统,实际上都充当了一个存储系统(发布的消息先存储起来)。Kafka比别的系统的优势是它是一个非常高性能的存储系统。
写入到kafka的数据将写到磁盘并复制到集群中保证容错性。并允许生产者等待消息应答,直到消息完全写入。
kafka的磁盘结构 - 无论你服务器上有50KB或50TB,执行是相同的。
client来控制读取数据的位置。你还可以认为kafka是一种专用于高性能,低延迟,提交日志存储,复制,和传播特殊用途的分布式文件系统。
kafka的流处理
仅仅读,写和存储是不够的,kafka的目标是实时的流处理。
在kafka中,流处理持续获取输入topic的数据,进行处理加工,然后写入输出topic。例如,一个零售APP,接收销售和出货的输入流,统计数量或调整价格后输出。
可以直接使用producer和consumer API进行简单的处理。对于复杂的转换,Kafka提供了更强大的Streams API。可构建聚合计算或连接流到一起的复杂应用程序。
助于解决此类应用面临的硬性问题:处理无序的数据,代码更改的再处理,执行状态计算等。
Sterams API在Kafka中的核心:使用producer和consumer API作为输入,利用Kafka做状态存储,使用相同的组机制在stream处理器实例之间进行容错保障。
拼在一起
消息传递,存储和流处理的组合看似反常,但对于Kafka作为流式处理平台的作用至关重要。
像HDFS这样的分布式文件系统允许存储静态文件来进行批处理。这样系统可以有效地存储和处理来自过去的历史数据。
传统企业的消息系统允许在你订阅之后处理未来的消息:在未来数据到达时处理它。
Kafka结合了这两种能力,这种组合对于kafka作为流处理应用和流数据管道平台是至关重要的。
批处理以及消息驱动应用程序的流处理的概念:通过组合存储和低延迟订阅,流处理应用可以用相同的方式对待过去和未来的数据。它是一个单一的应用程序,它可以处理历史的存储数据,当它处理到最后一个消息时,它进入等待未来的数据到达,而不是结束。
同样,对于流数据管道(pipeline),订阅实时事件的组合使得可以将Kafka用于非常低延迟的管道;但是,可靠地存储数据的能力使得它可以将其用于必须保证传递的关键数据,或与仅定期加载数据或长时间维护的离线系统集成在一起。流处理可以在数据到达时转换它。