首页 > > > Kafka的原理介绍及实践
kafka是近年来关注度飞速上升并得到越来越广泛应用的一个产品,本文将介绍一下它的实现原理以及在我们邮箱服务中的应用。
根据官网的介绍,Kafka是一个提供统一的、高吞吐、低延迟的,用来处理实时数据的流式平台,它具备以下三特性:
1、流式记录的发布和订阅:类似于消息系统。
2、存储:在一个分布式、容错的集群中安全持久化地存储流式数据。
3、处理:编写流处理应用程序,对实时事件进行响应。
Kafka一般用在两大类应用中:
1、建立实时流数据管道,在系统或应用之间实时地传输数据。
2、构建对数据流进行转换和处理的实时流应用程序。
在邮箱服务中,我们主要将kafka作为消息系统,用于系统内部消息的传输。为什么要采用kafka呢?让我们先从kafka的设计原理说起。
kafka中是以Topic机制来对消息进行分类的,同一类消息属于同一个Topic,你可以将每个topic看成是一个消息队列。
生产者将消息发送到相应的Topic,而消费者通过从Topic拉取消息来消费,没错,在kafka中是要求消费者主动拉取消息消费的,它并不会主动推送消息,这是它的一个特点,为什么会这样设计呢?我们后面再说,先来看一下Topic的结构:
每个topic可以有多个分区,这是kafka为了提高并发量而设计的一种机制:一个topic下的多个分区可以并发接收消息,同样的也能供消费者并发拉取消息,即分区之间互不干扰,这样的话,有多少个分区就可以有多大的并发量。所以,如果要更准确的打比方,一个分区就是一个消息队列,只不过这些消息队列同属于一种消息分类。
在kafka服务器,分区是以目录形式存在的,每个分区目录中,Kafka会按配置大小或配置周期将分区拆分成多个段文件(LogSegment), 每个段由三部分组成:
其中*.log用于存储消息本身的数据内容,*.index存储消息在文件中的位置(包括消息的逻辑offset和物理存储offset),*.timeindex存储消息创建时间和对应逻辑地址的映射关系。
段文件结构图如下 :

将分区拆分成多个段是为了控制存储的文件大小,如果整个分区只保存为一个文件,那随着分区里消息的增多,文件也将越来越大,最后不可控制。而如果每个消息都保存为一个文件,那文件数量又将变得巨大,同样容易失去控制。所以kafka采用段这种方式,控制了每个文件的大小,也方便控制所有文件的数量。同时,这些文件因为大小适中,可以很方便地通过操作系统mmap机制映射到内存中,提高写入和读取效率。
这个设计的另一个好处是:当系统要清除过期数据时,可以直接将过期的段文件删除,非常简洁。
但是这里也会有一个问题:如果每个消息都要在index文件中保存位置信息,那么index文件也很容易变得很大,这样又会减弱上文所说的好处。所以在kafka中,index设计为稀疏索引来降低index的文件大小,这样,index文件存储的实际内容为:该段消息在消息队列中的相对offset和在log文件中的物理偏移量映射的稀疏记录。
那么多少条消息会在index中保存一条记录呢?这个可以通过系统配置来进行设置。索引记录固定为8个字节大小,分别为4个字节的相对offset(消息在partition中全局offset减去该segment的起始offset),4个字节的消息具体存储文件的物理偏移量。
index文件结构图如下:

Kafka不会在消费者拉取完消息后马上就清理消息,而是会保存段文件一段时间,直到其过期再标记为可清理,由后台程序定期进行清理。这种机制使得消费者可以重复消费消息,满足更灵活的需求。
上面说过,kafka虽然作为消息系统,但是消费消息并不是通过推送而是通过拉取来消费的,client需要通过offset和size参数主动去查询消息。
kafka收到客户端请求后,对消息的寻址会经过下面几个步骤:
1、查找具体的Log Segment,kafka将段信息缓存在跳跃表中,所以这个步骤将从跳跃表中获取段信息。
2、根据offset在index文件中进行定位,找到匹配范围的偏移量position,此时得到的是一个近似起始文件偏移量。
3、从Log文件的position位置处开始往后寻找,直到找到offset处的消息。
kafka读取示意图:

介绍了kafka的实现原理,我们再来对比一下同样作为消息队列服务的rabbitmq。mq的应用也很广泛,功能多而全,那么和mq相比,kafka有哪些优势呢?为什么我们会使用kafka而抛弃了rabbitmq呢?
rabbitmq流程图:

kafka消费位点示意图:

kafka还有传统解决方案无法满足的高伸缩能力等优势,这里就不一一介绍了。
正因为kafka有着以上介绍的能力和优势,我们的邮箱服务中采用了它作为消息系统,其中一个应用就是邮件系统的data bus。
邮件系统用户收发信流程伴随着大量的业务逻辑和子系统调用,如果将这些流程都强依附在主干枝上,将会对系统造成较大的压力,整个业务流程也将变得复杂而缓慢。所以通过数据总线将主次流程进行解耦,减轻收发信主流程的复杂度,使其可以以更快的速度完成,加快系统响应时间。主流程产生事件源,通过kafka的传输,触发多个次要流程,次要流程可以并发在系统后台完成,并且可以轻易的扩展多种多样的次要流程。
下图以简化后的进信流程为例:

邮件系统在完成收发信流程后,会生成当次流程相关的系统事件,比如新邮件事件。data bus将这些事件写入到kafka集群的相应topic中,下游的一系列子系统对topic进行消费。
如下图所示,应用消费能力能借助Kafka集群实现弹性扩容。

总结一下,kafka在邮件系统中的应用给我们带来的好处:
更多技术干货,欢迎关注vx公众号“网易智慧企业技术+”。系列课程免费看,精品礼物免费得,还可直接对话CTO。
听网易CTO讲述前沿观察,看最有价值技术干货,学网易最新实践经验。网易智慧企业技术+,陪你从思考者成长为技术专家。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69918097/viewspace-3133537/ ,如需转载,请注明出处,否则将追究法律责任。