这篇文章构思了很久,因为我不是做计算机底层研究的,也没做过数据库,一直在应用层打转转,最多读过几篇相关的文章,所以担心我的知识储备不够写这么一篇比较严肃的话题,后来有朋友说服了我,可以不聊纯技术方面,而是谈谈笔者对大数据时代,计算与存储应该分离吗?于是就有了本文。注意,本文不牵扯到具体的技术细节和代码,要是被读者发现了有错误,请大胆指出。
在聊计算与存储分离这个话题,先来看看计算与存储的关系。计算机语言中的计算和存储其实来源于数学。举一个简单的例子,1+1=2 这个公式大家都很了解了,1 + 1 这个过程实际上就是“计算”,计算机通过某种规则获得了某种结果的过程就是计算。而 1 + 1 这个过程中,1 这个数字并不是凭空得来的,实际上需要存储在某个地方,计算机才能知道加号左右是两个 1 ,而不是其它数字。不仅如此,1+1=2计算出来的结果 2 也需要存储在某个地方,计算机才能知道得出的结果是 2 。这就是“计算”与“存储”的关系。
在计算机中,计算与存储实际上是不可分离的,计算需要存储在某个地方的数据,而数据没有经过计算只会是毫无价值的数字。
在不考虑计算机与计算机交互之前,计算与存储的交互都是发生在一台机器上的,通过计算机内部高速的缓存机制实现 CPU(计算的大脑)和硬盘(数据存储的地方)之间的交互。互联网兴起之后,开发者们就不能满足于单机的性能,而且单机的性能提升相对于互联网的发展性价比越来越低,大家开始构建集群,把一整个集群当做一个单独的计算机去处理。
在前文提到过,Hadoop 第一次实现了在大规模、分布式的计算机集群中的稳定和可靠的计算数据。而 Hadoop 的经典架构就是分布式文件系统 HDFS 和分布式计算引擎 MapReduce 。对比传统的单机,我们可以把 HDFS 理解为硬盘,而 MapReduce 类比为 CPU 。它们之间的交互变成了磁盘 IO。在 Hadoop 诞生的年代,网络速度还不是那么快,计算与存储实际上还没完全分离,Hadoop 仅仅是将“数据移动到计算的地方”这个理念变成了“计算移动到数据存储的地方”,用磁盘 IO 代替计算机内部缓存机制。计算与存储分离只是一个苗头而已。
随着网络速度进入千兆网、万兆网时代,计算机之间的网络传输速度几乎可以媲美计算机内部的磁盘 IO,计算与存储分离的概念开始有了实际的价值。
在聊计算与存储分离之前,不得不提云计算的发展。本文不是专门讲云计算的文章,具体的概念不介绍了。云计算的发展离不开 Hadoop 对分布式系统的探索,但是在 Hadoop 系统里,计算和存储实际上是在融合的,它们可能发生在同一台机器上。对于私有集群而言,如果集群计算或者存储性能不够了,加机器就好了,但是对于云计算而言,某个云上用户可能仅仅只是计算能力不足了,存储是足够的,单纯的加机器性价比太低了,那么云计算厂商就会在想,要不把计算与存储分离?这样的话,用户计算能力不足了,我给他加算力,存储空间不够了,我给他加存储空间,用户的花的钱少了,云计算投入的成本也降低了。
第一个搞出计算与存储分离的自然是 Hadoop 和其对应的数据分析领域。因为在数据分析中,传统数据库的事务不是非常重要,而且数据分析动辄几个 GB、几个 TB 的数据,计算时间花费长点没有多大影响。
随之而来的是关系型数据库,数据分析的蛋糕就那么多,而事务性交易才是大头。虽然说网络传输速度越来越快,但是事务性交易强调的事务和高并发,不仅仅是网速所能弥补的。知道 AWS 提出了日志即数据的概念,将日志彻底从数据库的计算节点中抽离出来,都由存储节点进行保存,并且也取消了 undo 日志,用于减小计算存储之间的交互和传输数据带宽。
有了论文和实际的产品,各种云厂商和开源数据库一拥而上,把计算与存储的概念发挥的淋漓尽致,终于形成了计算与存储分离的潮流。
计算与存储分离发展成了“云原生”,成为了云数据库的标配,比如 TiDB 严格的存储归存储,计算归计算;当然也有像 CockroachDB 一样的数据库,坚持存储与计算不分离。作为应用方,不太好评价两个选择的优劣,毕竟这算是数据库创作者的哲学和理念问题。读者感兴趣的话,可以拿 TiDB 和 CockroachDB 做一下严格的比较,而不是纯看论文和“宣传”文章,这样也能更好的理解计算与存储分离这个话题。