鱼喃

听!布鲁布鲁,大鱼又在那叨叨了

数据本地性是否仍那么重要?

随着网络带宽的增加,数据本地性优化带来的提升是否还重要?

大数据时代的数据本地性

最早接触数据本地性(Data Locality)这个概念是在学习Hadoop的时候,在分配节点时先检查所需处理的数据所在节点,然后尽可能选择这些节点启动mapper任务,由于不需要网络传输,这种调度策略能够减少一定的延迟,提升任务执行速度。为了尽可能的做到数据本地性,基于pull的YARN采用了延迟调度优化来选择适合的节点。上上届的师兄在苏宁项目中更是将延迟调度优化改用了push策略,进一步提升了效率。

时代在发展

初识这个策略觉得还是很有道理的,毕竟相比较于本地硬盘IO,网络传输既费时,还增加了容错的难度。不过月前重读Hadoop,却有了另外一种想法:数据本地性是否仍那么重要?或者换句话说,在当前框架繁杂、底层存储相对统一、计算与存储分离的云计算趋势、基于内存的分布式存储兴起等的大环境下,我们是否还要坚持数据本地性?

平台繁多

在最早Hadoop一统江湖的时候,尽管YARN、HDFS都是独立的组件,但是毕竟都是同源,做数据本地性十分便捷,但是随着Spark、Flink等新的大数据处理框架流行,不断取代Hadoop的地位,为了兼容性而保留了HDFS这一个存储。Hadoop时代,每个节点上既有datanode也有nodemanager,但是在当前平台众多的情况下,很有可能部署在不同的节点上,甚至是在不同的机架上,没有所谓的数据本地性了。而且各平台架构不同,Storm的设计是数据在节点间流动,数据是性外部系统流入的。数据本地性带来的性能提升微乎其微。

云时代的计算与存储分离

计算与存储分离。随着云计算的兴起,虚拟化技术也不断发展。以前,我们的服务是跟节点绑定的,要实现高可用,就必须在不同的节点上都部署上这些服务,而且一旦部署,就很难迁移,而随着docker等虚拟化技术的成熟,微服务、服务编排进入视野,大多数服务不再需要跟节点绑定,在启动时由服务编排工具去动态的选择节点,如果节点出现异常再自动调度到其他节点上执行,只要不是所有服务实例都失败,服务依旧是可用的,而且比之前的设计更加可靠。无状态的容器天然就可以在不同的节点上运行,至于有状态的容器,则可以通过挂载外部存储等形式实现共享。天下大势分久必合,计算与存储混合的架构阻碍了这种云计算的发展,将存储独立出来,更加便于管理,而且可以针对存储做特定的优化。既然计算与存储都分离了,再谈所谓的数据本地性也就没有什么意义了。

硬盘与网络带宽差异

硬盘IO与网络吞吐量的差距。同机房的节点间网络延迟大概在毫秒级别,而硬盘寻址的时间则是远低于这个量级,这也是数据本地性带来性能提升的关键因素之一。但是这么多年过去了,硬盘存储容量不断呈倍数增加,读写能力的提升却泛善可陈。相比较于硬盘的数百兆读写速度,网速却从当年的数兆到数十兆、数百兆,到目前为止,万兆、十万兆交换机已是机房的标配了,而且还在不断的提升之中。对于大数据量的读写,硬盘会逐渐成为瓶颈,而得益于分布式的优势,我们可以从不同的节点上分别取数据,网络带宽却很充足。除此之外,数据读写不仅仅是寻址的时间,还包括了数据传输的过程,在当前GB级别数据都不算大数据的背景下,对于大数据集的读取,从分布式存储中并行读取可能要比在本地有限的硬盘上读取更为迅速。

数据缓存

数据缓存。对读写速度越来越高的要求也带来了存储方面的改进,Spark同实验室推出了基于内存的分布式文件系统Alluxio,内存和硬盘的读写速度差了一个数量级,这极大的弥补了由于网络通信所带来的延迟。与其把Alluxio称作是一个分布式存储,我更愿意把它当成是一个高速的分布式缓存,比起文件系统,Alluxio由于内存的固有缺陷难以保证数据的持久性,而且由于内存相对昂贵也无法像HDFS那样做多备份。以Alluxio为代表的(内存中)缓存,即便是加上网络通信所带来的延迟,在速度上也不输本地硬盘。而且,统一的文件存储也有益于整体的缓存构建,降低了整体的读写速度。

英雄不老

那么,数据本地性是否就一文不值了呢?其实,并不是想说数据本地性没有用了,而是说它带来的性能优势不再那么大了,拘泥于数据本地性,可能会错过一些更好的点子。在数据大的场景下,数据本地性并不能带来多少的性能提升,但是在小批量数据,尤其是IO密集型场景下,本地性还是非常重要的。即便是在当前全栈容器化的背景下,一些应用如数据库等io密集型服务仍然是按照传统的方式部署在固定的节点上。

在云时代,不如我们来聊聊网络本地性?