【数据蒋堂】第7期:硬盘的性能特征

我们都知道内存比硬盘要快得多,大概能快出一两个数量级(价格也要贵这么多)。不过,硬盘的问题并不只是访问速度慢。

硬盘不适合做频繁小量访问

所谓频繁小量访问,是指运算过程中每次获取的数据量很小,而读取的次数很多。对于内存,每次取10字节、取1000万次、总共访问1亿字节;和每次取1000万字段、取10次、也访问1亿字节;这两者耗时是差不多的。内存访问数据的最小单位就是字节,无论怎么做,最后涉及到的字节数是一样的。

但硬盘的机制完全不同,在硬盘中数据是按扇区存放的,数据访问的最小单位是扇区(一般是512字节),也就是说从硬盘上读1个字节和读512字节的时间几乎一样的(内存复制时间相对于硬盘时间忽略不计了)。这样,每次取10字节取1000万次,和每次取1000万字节取10次,访问量一样,但耗时就可能会有巨大的差异,前者可能会多取很多无用的数据。

实际情况还要更恶劣一些,我们常常直接使用操作系统中的文件存储数据,而大部分文件系统的读取单位是簇,缺省大小一般是4K,比512字节要大8倍。而且,读取硬盘是一个复杂的动作,不象内存那样执行一条CPU指令就可以读取,访问硬盘需要一系列的动作来启动硬盘控制器并确定读取位置,读取1000万次就要执行1000万次这样的动作,当然一次读1000万字节时也会涉及较多次的磁盘动作(1000万字节会在很多扇区中),但总次数仍然会少得多,批量不频繁读取的性能就会远远好于频繁小量读取。

不连续的随机访问是罪魁

不过,我们在上述结论中用了“可能”二字,而没有用肯定的语气,这是因为还要考虑数据存储是否连续。如果要访问的数据在硬盘上是连续存储的,那取1000万次10字节也不会很慢,因为后面的10字节已经在前面读出的扇区里面而不必再读,硬盘控制器以及操作系统都有缓存功能,实际硬盘读取次数并没有那么多,结果的性能相差也不会非常大。所以我们还要在"频繁小量"前面加上“随机”这个定语,也就是读取的内容不连续,这时候,前面读出的扇区取出需要的部分外,其它内容和后面要访问的数据没有关系,只能浪费掉,而且后面再访问又要再次读,”可能“就会变成”肯定“了。

对于目前仍在大量采用的机械硬盘,随机访问还存在磁头跳动问题,也就是硬盘指标中的平均寻道时间。寻道是个非常慢的机械动作,比读一个扇区要慢得多得多。这样,即使每次读出扇区(簇)都没有任何浪费,在随机访问时的寻道成本却可能超过读取本身。使用机械硬盘时要特别注意避免随机频繁小时访问。

固态硬盘的情况要好一些,它没有寻道的机械动作了,这样在随机读取时也没有寻道时间问题。不过,尽管固态硬盘并不是按扇区形式存储数据,操作系统仍将它模拟得和机械硬盘类似,必须按某个基本单位(簇)读写,这样,随机的频繁小量(小于簇)访问g还是会有前述的低效问题。对于许多需要随机访问小量数据的运算,簇(扇区)这个单位太大了。

并行和并发导致随机访问

那么,对于只需要连续批量访问的运算(比如遍历汇总或查找),使用硬盘时的性能是否就只是其本身访问速度决定的呢?

对于单线程或单任务的运算基本上是这样。但现在研究高性能计算时显然不可能不考虑并行运算,而且许多运算服务也需要支持多并发。并行和并发运算会使原本可以连续访问的硬盘数据一定程度变成随机访问,原因很简单:多线程实际上在共享同一套硬盘,不同线程的访问请求显然不会连续,硬盘要同时响应这些请求就会发生跳动,也就是随机访问了。

对于机械硬盘这个后果常常很严重,如果线程之间切换频繁,就会导致频繁的寻道动作,结果就会发生多线程反而比单线程慢的现象。而有些单任务时性能尚可的场景,一旦并发了性能就会急剧下降。一个补救的办法是加大读数据的缓冲区,每个线程每次读出的数据足够多且连续,这样能使寻道时间占比变小而感觉不明显。但同时也会加剧内存占用,线程越多对内存需求越大。固态硬盘就好得多,缓冲区达到簇(扇区)的规模就可了。

有点类似的场景是列式存储,数据是按列连续存放的,需要多列计算时,即使单线程也会发生硬盘随机访问现象,涉及列较多时就未必会比行存有优势,多线程还会进一步加剧这个问题。在机械硬盘上用列存时要特殊注意这个问题,不一定总能提高性能。

外存运算需要采用不同的算法

由于硬盘的这些特征,有些运算从内存换到外存时会采用完全不同的方法,性能下降的程度也不是简单按比例做乘法。

比较典型的是JOIN运算,对于外键式1:N的JOIN,如果数据全部在内存中,可以使用针对外键维表主键做HASH索引,遍历事实表时用索引直接可以找到维表的相应记录,事实表有多个外键指向不同维表时也只要遍历一次就可以全解析。但如果维表过大而不能装入内存时就不能采用同样的算法了,因为硬盘无法支持随机频繁小量的访问,而访问维表记录恰恰是这种运算,强行使用这种方案的性能会恶劣到还不如把数据先排序再来归并的地步。外存大表JOIN时要按键值(的HASH值)分段,每段都足够小可以装入内存做JOIN,这种方法一次只能解析掉一个关联,事实表指向多个外键大维表时就要做多轮解析,运算量比内存JOIN大得多。

单机内存不足时还可以利用集群来避免复杂的外存运算。网络本身的延迟和硬盘差不多,通过网络获取集群机的内存数据时,单位数据量的访问性能不会比硬盘好多少,但却可以利用内存的随机访问能力和并发能力。不过网络和硬盘类似,每次启动一个网络连接的消耗较大,也不合适频繁小量的访问,要把多次获取数据的请求和返回结果积累起来一起传输。用这种方法做大维表JOIN,比内存计算麻烦,但比外存运算还是简单很多,仍然可以一次性解析掉多个关联。

原文发布时间为:2017-5-19

本文作者:蒋步星

本文来自合作伙伴“数据蒋堂”,了解相关信息可以关注“数据蒋堂”微信公众号

时间: 2024-10-26 16:47:21

【数据蒋堂】第7期:硬盘的性能特征的相关文章

【数据蒋堂】第3期:功夫都在报表外-漫谈报表性能优化

应用系统中的报表,作为面向业务用户的窗口,其性能一直被高度关注.用户输入参数后都希望立即就能看到统计查询结果,等个十几二十秒还能接受,等到三五分钟的用户体验就非常恶劣了. 那么,报表为什么会慢,又应当从哪里入手进行性能调优呢? 数据准备 当前应用中的报表大都用报表工具开发,当报表响应太慢时,不明就里的用户就会把矛头指向使用报表工具的开发人员或者报表工具厂商.其实,大多数情况报表的慢只是个表现,背后的原因是数据准备太慢,在数据进入报表环节之前就已经慢了,这时再去优化报表开发或压迫报表工具并没有用处

【数据蒋堂】功夫都在报表外--漫谈报表性能优化

应用系统中的报表,作为面向业务用户的窗口,其性能一直被高度关注.用户输入参数后都希望立即就能看到统计查询结果,等个十几二十秒还能接受,等到三五分钟的用户体验就非常恶劣了. 那么,报表为什么会慢,又应当从哪里入手进行性能调优呢? 数据准备 当前应用中的报表大都用报表工具开发,当报表响应太慢时,不明就里的用户就会把矛头指向使用报表工具的开发人员或者报表工具厂商.其实,大多数情况报表的慢只是个表现,背后的原因是数据准备太慢,在数据进入报表环节之前就已经慢了,这时再去优化报表开发或压迫报表工具并没有用处

【数据蒋堂】多维分析的后台性能优化手段

" 开篇辞 <数据蒋堂>的作者蒋步星,从事信息系统建设和数据处理长达20多年的时间.他丰富的工程经验与深厚的理论功底相互融合.创新思想与传统观念的相互碰撞,虚拟与现实的相互交织,产生出了一篇篇的沥血之作.此连载的内容涉及从数据呈现.采集到加工计算再到存储以及挖掘等各个方面.大可观数据世界之远景.小可看技术疑难之细节.针对数据领域一些技术难点,站在研发人员的角度从浅入深,进行全方位.360度无死角深度剖析:对于一些业内观点,站在技术人员角度阐述自己的思考和理解.蒋步星还会对大数据的发展

【数据蒋堂】第15期:开放的计算能力为数据库瘦身

[数据蒋堂]第14期:计算封闭性导致臃肿的数据库 我们在上一期谈到,数据库的臃肿,也就是过多的中间表以及相关存储过程,是由于其计算封闭性造成的.如果能够实现独立的计算引擎,使计算不再依赖于数据库提供,那么就可以为数据库瘦身了. 内部来源的中间数据不必再以数据表的形式落地在数据库中,而可以放到文件系统中,由外部计算引擎提供进一步的计算能力.对于只读的中间数据,使用文件存储时不需要考虑再改写,可以更为紧致并采用一定的压缩手段,而且在访问时也不必考虑事务一致性,机制大为简化,这样能获得比数据库更好多的

【数据蒋堂】第5期:1T数据到底有多大?

一英里不是个很长的距离,一立方英里相对于地球也不会让人觉得是个很大的空间.然后我说,这个空间内能装下全世界所有人,你会不会觉到很惊讶?不过这话不是我说的,是美国作家房龙在一本书里写的. 业内有个著名的数据仓库产品,叫Teradata,20多年前起这个名字,显然是想给人能处理海量数据的感觉.可现在,论用户还是厂商,谈论数据量时都常常以T为单位了,动不动就有几十上百T甚至PB级的数据.似乎T不是个多大的数,多几个几十个T也没什么大不了的. 其实T有点像上面说的立方英里,是个挺大的数.很多人对它没有多

【数据蒋堂】第16期:SQL像英语是个善意的错误

我们知道,SQL长得很像英语,简单的SQL语句直接可以作为英语读.除了SQL外,其它主要程序设计语言都没有这样,语法中就算有英语单词也仅仅是作为某些概念或操作的助记符而已,写出来的是形式化的程序语句(statement)而不是英语句子(sentence).而SQL不同,它会把整个句子写成符合英语习惯的形式,还会补充很多不必要的介词,比如FROM作为语句的运算主体却被写到后面,GROUP后面要写一个多余的BY. 为什么会这样?很容易想到的理由是希望非程序设计人员也能使用.用户只要会读写英语,就可以

《数据蒋堂》第9期:报表应用的三层结构

在传统的报表应用结构中,报表工具一般都是与数据源直接连接,并没有一个中间的数据计算层.确实,大部分情况下的报表开发并不需要这一层,相关的数据计算在数据源和呈现环节分别处理就够了.不过,在开发过程中,我们发现,有一部分报表的计算即不适合在数据源也不适合在呈现环节实现,这类报表在数量上并不占多数,但耗用的开发工作量占比却很大. 有过程的计算 报表工具都可以完成计算列.分组排序等运算,有些报表工具还提供了跨行组运算和相对格与集合的引用方案,可以完成颇为复杂的运算. 不过,报表工具中的运算是一种状态式的

【数据蒋堂】第8期:列式存储的另一面

列存是常见的数据存储技术,在许多场景下也确实很有效,因而也被不少数据仓库类产品采用,在业内列存也常常就意味着高性能. 可是,列存真有这么好吗?搜索一下,容易找到的列存缺点一般是针对数据修改的,而对于只读的分析计算任务,却很少能见到较详细的讨论.我们在这里来研究一下这个问题. 对内存计算意义不大 列存的原理很简单:由于磁盘不适合跳动式读取,采用行式存储时在读取数据时会扫描所有列,而一次运算可能只涉及很少的列,这样就会多读很多用不上的数据.采用列存则只需要读取需要用到的列,数据访问量大概率会大幅减少

【数据蒋堂】第17期:SQL的困难源于关系代数

在结构化数据处理领域,SQL无疑是应用最广泛的工作语言,不仅被所有关系数据库采用,许多新进的大数据平台也将实现SQL作为目标.但现实是,面对当前纷杂的计算查询需求,SQL在很多方面并不够好用.我们在前面说过SQL的过程性问题,这其实并不是最关键的问题,SQL的更大困难来源于其理论基础,即关系代数. 关系代数是一种代数体系.我们无法在本文的篇幅中严格定义代数体系这个概念,只能通俗地解释.人们为解决某种运算问题,定义了一些数据对象及针对这些数据对象的一套运算规则,确保这些运算的封闭性和自洽性,就可以