架构师训练营第一期 - 第八周学习总结
机械硬盘读写数据是通过磁头/臂移动(寻找对应磁道)和磁盘旋转(寻找对应扇区)来寻找到对应的数据存储位置读取数据,磁盘的旋转速度非常快(5400/7200),但是磁头的移动很慢是毫秒级的。如果读取的数据是离散的分布在不同的磁道上,那就需要磁头不断地移动来寻找对应的磁道,而如果是连续的存储在同一个磁道上,只需要磁盘旋转就能完成。因此随机读写是非常慢的,顺序读写是非常快的。
固态硬盘是由是由电子芯片及电路板组成,是通过主控芯片来控制将数据存储到对应的闪存颗粒单元里。其读写数据的性能都比机械硬盘高很多,但是它在进行随机读写时候也比进行顺序读写要慢很多。
硬盘随机读写慢顺序读写快的这种特性也会影响到软件的设计,数据库采用 B+树这种数据结构来来尽量避免随机读写,将索引通过 B+树来存储,然后通过索引去找到对应的记录。这极大的降低了随机查找数据的次数,但依然需要几十毫秒才能找到数据,性能还是比较慢。因此,使用 LSM 树作为存储索引对数据进行顺序写入提高数据写入性能。
LSM 进行数据存储时,数据先写到内存缓存(也就是 memtable)中,memtable 使用树结构来保持 key 的有序,在大部分的实现中,memtable 会通过写 WAL 的方式备份到磁盘,用来恢复数据,防止数据丢失。当 memtable 数据达到一定规模时会被刷新到磁盘上的一个新文件,重要的是系统只做了顺序磁盘读写,因为没有文件被编辑,新的内容或者修改只用简单的生成新的文件。所以越多的数据存储到系统中,就会有越多的不可修改的,顺序的 sstable 文件被创建,它们代表了小的,按时间顺序的修改。因为比较旧的文件不会被更新,重复的纪录只会通过创建新的纪录来覆盖,这也就产生了一些冗余的数据。所以系统会周期的执行合并操作(compaction)。 合并操作选择一些文件,并把他们合并到一起,移除重复的更新或者删除纪录,同时也会删除上述的冗余。更重要的是,通过减少文件个数的增长,保证读操作的性能。因为 sstable 文件都是有序结构的,所以合并操作也是非常高效的。
文件系统将硬盘空间以块为单位进行划分,每个文件占据若干个块,然后再通过一个文件控制块 FCB 也就是 inode 来记录每个文件占据的硬盘数据块。Linux 文件系统会为每个文件分配两个数据结构:索引节点(index node)和目录项(directory entry),它们主要用来记录文件的元信息和目录层次结构。索引节点,也就是 inode,用来记录文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等。索引节点是文件的唯一标识,它们之间一一对应,也同样都会被存储在硬盘中,所以索引节点同样占用磁盘空间。目录项,也就是 dentry,用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系。多个目录项关联起来,就会形成目录结构,但它与索引节点不同的是,
目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存。inode 是固定结构的,能够记录的硬盘地址索引数也是固定的,只有 15 个索引。因此采用了多级(三级)inode 索引的方式,这样每个 inode 最多可以存储 12+256+256256+256256*256 个数据块,如果每个数据块的大小为 4k,也就是单个文件最大不超过 70G。
单个硬盘的读写速度是有限的,通过 RAID(独立磁盘冗余阵列)的方式将多个硬盘组合起来提供读写服务。RAID 有 RAID0 RAID1 RAID10 RAID5 RAID6 几种常见的实现方式。
RAID 这种方式只能是在单台服务器上面提供数据分片能力,最大的速度提升也就是磁盘数目的倍数。要实现更高的数据读写性能提升,就需要使用分布式文件系统用多台服务器来提供数据读写能力。分布式文件系统和 RAID 的实现思路是类似的,都是将数据进行分片存储,RAID 是以磁盘为单位进行数据分片存储,而分布式文件系统则是以服务器为单位进行数据分片存储。
先总结第一节内容,剩下的找时间再补充。。。
评论