理论教育 Scala语言基础与开发实战-消息存储与缓存设计

Scala语言基础与开发实战-消息存储与缓存设计

时间:2023-11-24 理论教育 版权反馈
【摘要】:对消息进行存储和缓存时,Kafka依赖于文件系统。随着计算机的快速发展,硬盘的吞吐量与磁盘的寻道时间严重不匹配,用磁盘进行数据持久化结构设计时,人们对这种结构设计的性能抱有很大的怀疑,始终认为“磁盘比较慢”。实际上,实验表明这主要取决于磁盘的使用方式,设计较好的磁盘结构往往可以和网络一样快。所以现代的操作系统都会乐于将所有空闲内存转做磁盘缓存,但在需要回收这些内存的情况下,会付出一些性能方面的代价。

Scala语言基础与开发实战-消息存储与缓存设计

对消息进行存储和缓存时,Kafka依赖于文件系统。随着计算机的快速发展,硬盘吞吐量与磁盘的寻道时间严重不匹配,用磁盘进行数据持久化结构设计时,人们对这种结构设计的性能抱有很大的怀疑,始终认为“磁盘比较慢”。实际上,实验表明这主要取决于磁盘的使用方式,设计较好的磁盘结构往往可以和网络一样快。

比如,在一个由6个7200rpm的SATA硬盘组成的RAID-5磁盘阵列上,线性写入(Linear Write)的速度大约是300 MB/s。但随机写入却只有50 kB/s,其中的差别接近10000倍。实际上,在某些情况下,顺序磁盘访问比随机内存访问还要快!所以现代的操作系统都会乐于将所有空闲内存转做磁盘缓存,但在需要回收这些内存的情况下,会付出一些性能方面的代价。再看看基于JVM的基础开发的系统,在内存的使用上要注意两点,第一,Java对象的内存开销(overhead)非常大,往往是对象中存储数据所占内存的两倍(或更糟);第二,Java中的内存垃圾回收会随着堆内数据不断增长而变得越来越不明确,回收所花费的代价也会越来越大。(www.daowen.com)

由于这些因素,使用文件系统并依赖于页面缓存要优于自己在内存中维护一个缓存结构,这就让人联想到一个非常简单的设计方案:不是在内存中保存尽可能多的数据,在需要时将这些数据刷新(Flush)到文件系统,而是要做完全相反的事情。所有数据都要立即写入文件系统的持久化日志中,但不进行刷新数据的任何调用。在实际中这么做,意味着数据被传输到OS内核的页面缓存中了,OS随后会将这些数据刷新到磁盘中。此外这里添加了一条基于配置的刷新策略,允许用户控制把数据刷新到物理磁盘的频率(每当接收到N条消息或者每过M秒),从而可以在系统硬件崩溃时,对“处于危险之中”的数据在量上加个上限。因此,如果大家使用磁盘的方式更倾向于线性读取操作,那么随着每次磁盘的读取操作,预读就非常高效地将使用之后定能用得着的数据填充缓存。这也就是offset的递增顺序读取,能够大量提高读取I/O的性能。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈