Kafka持久化机制

Kafka持久化机制,第1张

Kakfa 依赖文件系统来存储和缓存消息。对于硬盘的传统观念是硬盘总是很慢,基于文件系统的架构能否提供优异的性能?实际上硬盘的快慢完全取决于使用方式。

为了提高性能,现代 *** 作系统往往使用内存作为磁盘的缓存,所有的磁盘读写 *** 作都会经过这个缓存,所以如果程序在线程中缓存了一份数据,实际在 *** 作系统的缓存中还有一份,这等于存了两份数据。

同时 Kafka 基于 JVM 内存有以下缺点:

实际上磁盘线性写入的性能远远大于任意位置写的性能,线性读写由 *** 作系统进行了大量优化(read-ahead、write-behind 等技术),甚至比随机的内存读写更快。所以与常见的数据缓存在内存中然后刷到硬盘的设计不同,Kafka 直接将数据写到了文件系统的日志中:

这样实现的好处:

一个 Topic 被分成多 Partition,每个 Partition 在存储层面是一个 append-only 日志文件,属于一个 Partition 的消息都会被直接追加到日志文件的尾部,每条消息在文件中的位置称为 offset(偏移量)。

日志文件由“日志条目(log entries)”序列组成,每一个日志条目包含一个4字节整型数(值为N),其后跟N个字节的消息体。每条消息都有一个当前 Partition 下唯一的64字节的 offset,标识这条消息的起始位置。消息格式如下:

Kafka 持久化日志视图

日志文件允许串行附加,并且总是附加到最后一个文件。当文件达到配置指定的大小( log.segment.bytes = 1073741824 (bytes))时,就会被滚动到一个新文件中(每个文件称为一个 segment file)。日志有两个配置参数:M,强制 *** 作系统将文件刷新到磁盘之前写入的消息数;S,强制 *** 作系统将文件刷新到磁盘之前的时间(秒)。在系统崩溃的情况下,最多会丢失M条消息或S秒的数据。

通过给出消息的偏移量(offset)和最大块大小(S)来读取数据。返回一个缓冲区为S大小的消息迭代器,S应该大于任何单个消息的大小,如果消息异常大,则可以多次重试读取,每次都将缓冲区大小加倍,直到成功读取消息为止。可以指定最大消息大小和缓冲区大小,以使服务器拒绝大于某个大小的消息。读取缓冲区可能以部分消息结束,这很容易被大小分隔检测到。

读取指定偏移量的数据时,需要首先找到存储数据的 segment file,由全局偏移量计算 segment file 中的偏移量,然后从此位置开始读取。

消息数据随着 segment file 一起被删除。Log manager 允许可插拔的删除策略来选择哪些文件符合删除条件。当前策略为删除修改时间超过 N 天前的任何日志,或者是保留最近的 N GB 的数据。

为了避免在删除时阻塞读 *** 作,采用了 copy-on-write 技术:删除 *** 作进行时,读取 *** 作的二分查找功能实际是在一个静态的快照副本上进行的。

上面提到日志文件非由一个文件构成,而是分成多个 segment(文件达到一定大小时进行滚动),每个 segment 名为该 segment 第一条消息的 offset 和 ".kafka" 组成。另外会有一个索引文件,标明了每个 segment 下包含的日志条目的 offset 范围。

有了索引文件,消费者可以从 Kafka 的任意可用偏移量位置开始读取消息。索引也被分成片段,所以在删除消息时,也可以删除相应的索引。Kafka 不维护索引的校验和,如果索引出现损坏,Kafka 会通过重新读取消息来重新生成索引。

一、kafka定义

二、kafka的优势

三、kafka的原理

四、kafka起源

一、Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于hadoop的批处理系统、低延迟的实时系统、storm/Spark流式处理引擎,web/nginx日志、访问日志,消息服务等等,用scala语言编写,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。

二、kafka的优势

高吞吐量、低延迟:kafka美妙之处是可以处理几十万条信息,它的延迟最低只有几毫秒,每个topic可以分多个partition,consumer

group对partition进行consume *** 作。

可扩展性:kafka集群支持热扩展

持久化、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失

容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)

高并发:支持数千个客户端同时读写

三、kafka的原理

kafka是如何实现以上所述这几点,我们逐一说明:

1.高吞吐量、低延迟

kafka在设计之初就是为了针对大数据量的传输处理,高吞吐量、低延迟最主要看的就是单位时间内所能读写的数据总量,我们先来看生产端。

kafka采取了一定量的批处理机制,即当生产数据达到一定数量或者达到时间窗口后,将所收集到的数据一批次的提交到服务器,我们假设处理一次数据的时间为1ms,那每秒钟能处理1000条,延时为1ms,如果此时将处理间隔变成9ms,即每10ms处理一批数据,假设这段时间接收到100条处理,那每秒则能处理10000条,但是延时变成了10ms。为了获得最大的吞吐量,需要牺牲一定的延迟,但是这样的牺牲是值得的。当确定了这种小批量方式之后,高速的写则取决于kafka自身写磁盘的速度了。而由于kafka本身对数据不做任何的处理,只管写入数据,保管数据,分发数据,因此会是一种批量顺序写入数据的情况,而磁盘的读写速度大量消耗在寻址上,也就是随机读写,但是对于顺序写入的速度是非常快的,甚至能媲美内存的随机写入速度。有人做过一个对比,普通磁盘顺序写入每秒能达到53.2M/s,SSD的顺序写入速度为42.2M/s,内存的顺序写入速度为358.2M/s。kafka正是利用了这个特性,顺序写入,速度相对较快。而kafka本身虽然也是写入磁盘持久化数据,但实际上kafka是将数据顺序写入页缓存中(page cache),然后由 *** 作系统自行决定何时写到磁盘上,因此kafka的写 *** 作能在每秒轻轻松松达到写入数十万条记录。并且基于kafka的动态扩展,这个数字还能不断增大。

kafka在消费端也有着高吞吐量,由于kafka是将数据写入到页缓存中,同时由于读写相间的间隔并不大,很大可能性会在缓存中命中,从而保证高吞吐量。另外kafka由于本身不对数据做任何的修改,完全使用零拷贝技术,大大提升数据的读取能力。

2.kafka每个节点叫做broker,而每一个broker都是独立运行的,可以随时加入kafka集群,集群的心跳管理是由zookeeper负责,新加入的broker只要broker id不与原有的冲突就能顺利的加入集群中,实现动态扩展。

3.kafka的持久化在上面已经提到,kafka绕过了java的堆处理数据,直接将数据写入页缓存,然后由 *** 作系统来管理页缓存写入磁盘,实现持久化。kafka每一个主题topic是一个业务数据,他可由多个partition组成,而每个partition可以有多个replica副本,用于保证数据的可靠性。replica分为两个角色,一个是leader,一个是追随者,同一时间,每一个partition只能有一个leader,其他都是追问随者,laeder负责接收数据并写入log,而追随者不能被用户写入数据,只是从leader角色的replica副本中同步log写入自己的log,保持数据同步。kafka中有一个概念,ISR,全称是in-sync

replica,即所有可用的replica副本,这里的ISR数量只要大于1,这个partition就能正常运作,因此容错性非常好,假设n个replica,那最多可以坏n-1个replica的情况下,还能保持系统正常运行。当replica迟滞到一定时间后,会被kafka从ISR中剔除,当再次同步后,可以再次加入ISR,如果这时候leader出现问题,会从ISR中重新选举一个leader,原先的leader再次同步成功后会重新加入ISR,成为一个flower。

4.上面提到了kafka的ISR机制,kafka的容错性就是由ISR的机制来保证的。

5.kafka集群可以动态扩展broker,多个partition同时写入消费数据,实现真正的高并发。

四、kafka的起源

kafka起源于LinkedIn公司,当时领英公司需要收集两大类数据,一是业务系统和应用程序的性能监控指标数据,而是用户的 *** 作行为数据。当时为了收集这两类数据,领英自研了两套相应的数据收集系统,但是这两套系统都存在一些弊端,无法实现实时交互、实时性差、维护成本高。因此领英的工程师希望找到一个统一的组件来收集分发消费这些大批量的数据,ActiveMQ由于扩展性不足,不能支撑大数据量而被抛弃,从而决定自研一套满足需求的系统组件,也就是kafka。

kafka的设计之初主要有三个目标:

1.为生产者和消费者提供一套简单的API

2.降低网络传输和磁盘存储开销

3.具有高伸缩性架构

目前kafka可以算是超额完成了目标。

kafka的名称由来也很有意思,因为kafka系统的写 *** 作性能特别强,因此想使用一个作家的名字来命名kafka,而Jay Kreps,kafka的三位作者之一,在上大学的时候很喜欢Franz Kafka,因此起来这样一个名字。

kafka在2010年开源,2011年7月正式进入Apache进行孵化,2012年10月顺利毕业,后成为Apache的顶级项目。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/10850922.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-11
下一篇 2023-05-11

发表评论

登录后才能评论

评论列表(0条)

保存