搞透Kafka的存储架构,看这篇就够了

本文详细探讨了Apache Kafka的存储架构设计,从Kafka的诞生背景、存储场景需求、存储选型到最终的存储实现方案。文章指出,Kafka采用顺序追加写日志和稀疏索引来满足高并发、高可用的需求。Kafka存储基于日志分段、索引和磁盘数据存储策略,如PageCache和零拷贝技术,以实现高性能。文章还介绍了Kafka的日志格式演进,从V0到V2版本,以及日志清理机制,包括日志删除和日志压缩策略。
摘要由CSDN通过智能技术生成

今天我就来聊聊 kafka 的存储系统架构设计, 说到存储系统,大家可能对 MySQL 比较熟悉,也知道 MySQL 是基于 B+ tree 来作为它的索引数据结构。

Kafka 又是基于什么机制来存储?为什么要设计成这样?它解决了什么问题?又是如何解决的?里面又用到了哪些高大上的技术?  

      带着这些疑问,我们就来和你聊一聊 Kafka 存储架构设计背后的深度思考和实现原理。

           

   认真读完这篇文章,我相信你会对 Kafka 存储架构,有更加深刻的理解。也能有思路来触类旁通其他存储系统的架构。

             

图1: kafka 存储架构大纲

1

kafka 存储场景剖析

在讲解 Kafka 的存储方案之前 ,我们 先来看看 Kafka 官网给的定义:

   Apache Kafka is an open-source distributed event streaming platform used by thousands of companies for high-performance data pipelines, streaming analytics, data integration, and mission-critical applications. 

翻译成中文如下:

Apache kafka 是一个开源的分布式事件流处理平台,由成千上万的公司用于高性能的数据管道流分析、数据集成和关键任务的应用程序。

了解  Kafka 的老司机都知道它是从 Linkedin 内部孵化的项目, 从一开始,Kafka 就是为了解决大数据的实时日志流而生的, 每天要处理的日志量级在千亿规模 。 对于日志流的特点主要包括 1)、数据实时产生 2)、海量数据存储与处理, 所以它必然要面临分布式系统遇到的 高并发、高可用、高性能 等三高挑战。

通过上面的背景可以得出: 一切脱离业务场景谈架构设计都是耍流氓

综上我们看对于 Kafka 的存储需求来说,要保证以下几点:

1. 存储的主要是消息流(可以是简单的文本格式也可以是其他格式,对于 Broker 存储来说,它并不关心数据本身)
 
2. 要支持海量数据的高效存储、高持久化(保证重启后数据不丢失)
 
3. 要支持海量数据的高效检索(消费的时候可以通过offset或者时间戳高效查询并处理)
 
4. 要保证数据的安全性和稳定性、故障转移容错性
 

2

kafka 存储选型

有了上面的场景需求分析后, 我们接下来分析看看 Kafka 到底基于什么机制来存储的,能否直接用现有我们了解到的关系型数据库来实现呢?我们接着继续深度分析。

1

存储基本知识

我们先来了解下存储的基本知识或者常识, 在我们的认知中, 对于各个存储介质的速度大体同下图所示的,层级越高代表速度越快。很显然,磁盘处于一个比较尴尬的位置, 然而,事实上磁盘可以比我们预想的要快,也可能比我们预想的要慢,这完全取决于我们如何使用它。

             

图2: 各存储介质对比分布(来自网络)

关于磁盘和内存的 IO 速度, 我们可以从下图性能测试的结果看出普通机械磁盘的顺序I/O性能指标是53.2M values/s,而内存的随机I/O性能指标是36.7M values/s。由此似乎可以得出结论: 磁盘的顺序I/O性能要强于内存的随机I/O性能。

图3:磁盘和内存的 IO 速度对比(来自网络)

另外从整个数据读写性能方面,有不同的实现方式,要么提高读速度,要么提高写速度。

1. 提高读速度:利用索引,来提高查询速度,但是有了索引,大量写操作都会维护索引,那么会降低写入效率。常见的如关系型数据库:mysql等
 
2. 提高写速度:这种一般是采用日志存储, 通过顺序追加写的方式来提高写入速度,因为没有索引,无法快速查询,最严重的只能一行行遍历读取。常见的如大数据相关领域的基本都基于此方式来实现。
 

2

Kafka 存储方案剖析

上面从存储基础知识,以及存储介质 IO 速度、读写性能方面剖析了存储类系统的实现方式,那么我们来看看 Kafka 的存储到底该采用哪种方式来实现呢?

对于 Kafka 来说, 它主要用来处理海量数据流,这个场景的特点主要包括:

1. 写操作:写并发要求非常高,基本得达到百万级 TPS,顺序追加写日志即可,无需考虑更新操作

2. 读操作:相对写操作来说,比较简单,只要能按照一定规则高效查询即可(offset或者时间戳)

根据上面两点分析,对于写操作来说,直接采用 顺序追加写日志 的方式就可以满足 Kafka 对于百万TPS写入效率要求。但是如何解决高效查询这些日志呢? 直接采用 MySQL 的 B+ tree 数据结构存储是否可以?我们来逐一分析下:

如果采用 B+ tree 索引结构来进行存储,那么每次写都要维护索引,还需要有额外空间来存储索引、更会出现关系型数据库中经常出现的“数据页分裂”等操作, 对于 Kafka 这种高并发的系统来说,这些设计都太重了,所以并不适合用。

但是在数据库索引中,似乎有一种索引看起来非常适合此场景,即: 哈希索引【底层基于Hash Table 实现】 ,为了提高读速度, 我们只需要 在内存中维护一个映射关系 即可,每次根据 Offset 查询消息的时候, 从哈希表中得到偏移量,再去读文件就可以快速定位到要读的数据位置。但是哈希索引通常是需要常驻内存的,对于Ka

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值