初论磁盘存储利用率

对磁盘或者存储和性能造成挑战有两点:

1.      大数据存储

2.      数据分布不均。

1.浪费磁盘,2读取写入的性能较低。

目前的存储服务器管理磁盘的方法通常具有以下方法:

1.      Hash桶挂接固定块大小的块, 分配的块都是固定大小,linux内核也是采用这种方法。很多的管理算法都是在这一方法上的变体,改进等。

2.      Hash桶方法,按照不同的规格固定大小的块,具有块合并,回收系统,glibc采用的方法。

首先遇到的问题:

1.      固定块,块大小如何选择?

扫描二维码关注公众号,回复: 5526135 查看本文章

如何使得即具有高性能,又不造成空间的浪费。这里的一般选择是4K大小的块,因为linux的磁盘读写驱动是以4k为大小为单位进行读写的,磁盘也是以4k为大小为基准单位进行划分的。每次读写4k的块,系统的读写的性能很高。

如果数据大小平均为1k呢?这时如果选择4k大小的存储块,就会有75%的空间浪费,这个如何取舍呢?需要采用不同的规格的数据块的机制来补充。

定长的数据块组织图:

J83YH3G~}1QXC`([}]Z~]4U

               首先每个块都是分配在一个统计的管理链条中,首先是每个块必然存在于双向LRU中,这是最经典的淘汰策略了,每次淘汰就可以时间最久的那个淘汰。对于每个hash桶上挂载的一个存储块,也组成一个双向链表。对于每个hash桶上的记录也需要组成LRU链。还有一种方法就是把每个存储管理在堆中,但是这种数据结构要复杂一些,不易掌控,因此目前实际应用中很少采用这种实现。

    对于数据的key来说,只有一个节点,但是对于其数据库来说,就不止一个块了。因此将key的数据库挂载到hash桶中,但是真正每个key的数据库却保存另一个系统中。

U5N%G]0`H``82W[%KKC1{[U

每个key都对应了一些数据保存在数据块管理单元中。对于数据单元的实现最重要,是数据组织的核心。这部分的管理涉及到空间的利用和磁盘的读写性能。

2.      如果采用不同规格的数据块大小,则性能将受到很大影响。

采用不同规格的数据库的大小的实现方案,大多都是基于glibc风格实现的。实现的方式如下:

采用64 字节128字节,256,512,768,1024,4096作为几种规格,实际中的规格不是这么大,因为考虑到一些数据结构的消耗,因此不同的规格的数字大小有所变化。

         这种风格相当于管理了多个数据块组成的单元。这种方式更复杂,性能更高,能够做到高效率的利用存储空间。通常内存是比较短缺的资源,因此glibc为了高效的使用内存,因此采用这种方式分配内存。

         对于保存数据的存储块来说,每个记录都有一个基本块和溢出块,基本块内部存储了很记录。当基本块使用完后,就要使用溢出块,当溢出块使用完后,无法在写入数据,必须分裂数据,这种机制会有一个问题:

         如果每个记录的大小不一致,分布不均的话,就有可能导致某些桶上的存储块快速用满,当这些桶节点用满后,性能开始下降,因为分配不到存储空间。这时就需要迁移数据,而整体的数据库的使用率还很小。有时存储空间的利用率只有30%。因此这种模式有待改进。

U(B43N370U@8Z8]U4~$I7$S

         原来的分配的机制最明显的特性是,没有考虑到数据大小的分布,所有的桶的分配存储空间是固定,是平均分配的思想。这也是问题的根源。因此要将平均分配改成按需分配。数据大的桶多分配,数据小的少分配。因此采用如下机制:

         每个桶分配相同的基本块,将溢出块作为一个整体放在一个溢出池中,如果有基本块用完了的话,就从一个溢出池获取中。这样避免了基本库使用完了,溢出块也可以合理使用。

UL7MP4MZ1RQVRTYHJ`1$AG4

         当存储记录不均匀时,记录较大的如果基本块用完,其使用较多的溢出块。这样就解决了当记录很大时,导致需要分裂,扩容,迁移等运维操作。


猜你喜欢

转载自blog.csdn.net/kingsleer/article/details/7657533
今日推荐