关于前端:两招提升硬盘存储数据的写入效率

8次阅读

共计 1591 个字符,预计需要花费 4 分钟才能阅读完成。

现在存储数据的形式有很多,而硬盘因为价格和数据保护方面的劣势,是大部分用户的首选。然而,硬盘和内存相比在 IO 读写上慢了好几个数量级,那为什么会更偏好硬盘呢?

首先须要提到的是,操作磁盘之所以慢次要是因为对磁盘的读写耗时。读写次要有三局部耗时: 寻道工夫 + 旋转工夫 + 传输工夫 ,其中寻道工夫是最久的。因为寻道须要挪动磁头到对应的磁道上,通过马达驱动磁臂挪动,是一种机械运动因而耗时较长。同时咱们对磁盘的操作通常都是随机读写,也就须要频繁挪动磁头到对应的磁道,这就让耗时缩短了,显得性能比拟低。

这样看来如果要让磁盘读写速度变快,只有不应用随机读写,或者缩小随机的次数,就能够无效晋升磁盘读写速度了。那具体要如何操作呢?

程序读写

先来聊聊第一个办法,如何应用程序读写,而不是随机读写?下面提到寻道工夫是耗时最久的,所以最直观的思路就是省去这部分工夫,而程序 IO 正好能够满足需要。

追加写就是一种典型的程序 IO,应用这个思路优化的典型的产品就是音讯队列。以热门的 Kafka 为例,Kafka 为了实现高性能 IO,用了很多优化的办法,其中就应用了程序写这种优化办法。

Kafka 以工夫复杂度为 O(1) 的形式提供音讯长久化能力,即便对 TB 级以上数据也能保障常数工夫复杂度的拜访性能。对于每个分区,它把从 Producer 收到的音讯,程序地写入对应的 log 文件中,一个文件写满后,才开启一个新的文件。生产的时候,也是从某个全局的地位开始,也就是某一个 log 文件中的某个地位开始,按程序地读出音讯。

缩小随机次数

看完了程序形式,咱们再来看看缩小随机写次数的办法。在很多场景中,为了不便咱们后续对数据的读取和操作,咱们要求写入硬盘的数据是有序的。比方在 MySQL 中,索引在 InnoDB 引擎中是以 B+ 树形式来组织的,而 MySQL 主键是聚簇索引(一种索引类型,数据与索引数据放在一起),既然数据和索引数据放在一起,那么在数据插入或者更新的时候,咱们须要找到要插入的地位,再把数据写到特定的地位上,这就产生了随机的 IO。所以,如果咱们每次插入、更新数据都把数据写入至 .ibd 文件的话,而后磁盘也要找到对应的那条记录,而后再更新,整个过程 IO 老本、查找老本都很高,数据库的性能和效率都会大打折扣。

为了解决写入性能问题,InnoDB 引入了 WAL 机制,更确切的说,就是 redo log。上面我再简略介绍下 Redo Log。

InnoDB redo log 是一个程序写入的、大小固定的环形日志。次要作用有两个:

  • 进步 InnoDB 存储引擎写入数据的效率
  • 保障 crash-safe 能力

在这里咱们只关怀它是如何进步写入数据的效率的。下图是 redo log 的示意图。

从图中能够看出,red olog 的写入是程序写入的,不须要找到某一个具体的索引地位,而是简略地从 write-pos 指针地位追加。

其次当一个写事务或者更新事务执行时,InnoDB 首先取出对应的 Page,而后进行批改。当事务提交时,将位于内存中的 redo log buffer 强制刷新至硬盘中,如果不思考 binlog 的话,咱们能够认为事务执行能够返回胜利了,写入 DB 的操作由另外的线程异步进行。

再而后,可由 InnoDB 的 Master Thread 定时地将缓冲池中的脏页,也就是下面儿咱们批改的页,刷新至磁盘,此时被批改数据真正的写入至 . ibd 文件。

总结

很多时候,咱们不得不把数据存储到硬盘上,然而因为硬盘绝对于内存来说切实是太“慢”了。所以咱们就得想方法晋升性能。文章里总结了两个办法,第一个是追加写,利用程序 IO 来实现疾速写;第二个是很多数据库中为了晋升性能都会引入的 WAL 机制。文章里别离拿了 Kafka 和 MySQL 的 InnoDB 存储引擎举例。除了这两个,感兴趣的同学也能够看下 LSM 树,etcd 等是怎么实现疾速写的。

举荐浏览

【文言科普】10s 从零看懂 H5

面试官问,Redis 是单线程还是多线程? 我懵了

正文完
 0