背景介绍——NoSQL 和 NewSQL

2020-06-23 00:00:00 数据 分布式 单机 这一 实际上

传统的关系型数据经历了相当长的一段繁荣时期。但是随着时代的发展,我们产生和需要处理的数据量急剧增长。根据 DOMO 公司的统计,互联网人口数量增长情况如 图 6 所示。数据量的增长带来的一个问题是,这些数据难以(不能)在单一机器上得到有效的存储和处理。

图 6 互联网人口增长趋势

一个比较常见的思路是将数据分布在多台机器上进行存储和处理。传统数据库的分布式方案,江湖俗称分库分表,实际上涉及到两种截然不同的拆分形式:

  1. 将同一个数据库中的不同表放在不同的机器上
  2. 将同一个表的不同行放在不同的机器上

前者只要不进行跨表查询,例如 Join 操作,就可以像单机数据库一样使用。遗憾的是,使用传统数据库的主要场景就是基于表之间的关系做查询的,这样的限制还是比较大的。另一方面,随着数据的进一步增长,我们还是面临着一台机器放一张表也有困难的场景,此时就需要将表中的不同行放在不同的机器上。这样做之后,即便是一些简单的 Scan 操作,也需要在多台机器上执行,然后将结果进行一些汇总(聚合)后,再进行使用。

这样的做法表面上好像解决了问题,实际上完全破坏了 SQL 查询接口提供的封装特性。本来我们只需要提供 SQL 语句,数据库系统内部会自动对 SQL 语句进行优化,并完成整套查询操作。但是现在我们不仅要提供 SQL 语句,还要去完成 SQL 执行中的一些功能,例如任务的分发和聚合,而这些功能原本都应该由 SQL 执行引擎(例如 Spark SQL,Flink SQL 等等)去完成。上面说的还都只涉及到普通的查询功能,没有涉及到数据的写入和事务。

这意味着,实际上我们已经不需要单机的系统提供 SQL 层的功能了。我们只需要单机存储系统提供存储相关的功能即可,所有 SQL 层面的工作都应该由所谓的数据库中间件来完成。

另一方面,我们对于单机存储系统又提出了新的要求。由于我们使用更多的机器存放我们的数据并提供服务,整个系统的故障率上升了(,为了照顾数学不好的同学提示一下,当 时 )。我们需要单机存储系统能够组成互备的系统,当一台机器发生故障时,能够自动从另一台机器上恢复数据。

基于这样的背景,NoSQL 运动如火如荼的展开了。表面上看来,大家完全抛弃了 SQL 这一已被证明非常实用的已经发展的比较成熟的存储体系,整体倒退到裸用存储设备的年代。实际上,是整个存储系统从单机系统走向分布式系统的一次涅槃重生。

整体基调虽然确定了,但是具体的实现方式缺各有不同。有的人选择实现一个分布式文件系统,理想情况下分布式文件系统的性能和本地文件系统的性能相当,这样的话上层应用几乎无需什么改动,直接跑在分布式文件系统上,就能享受几乎无限大的存储空间。然而遗憾的是,这样的系统在随机访问时的性能仍然难以和本地文件系统相当,更别提 SSD 横空出世后进一步拉大了这一差距。另一方面,即便存储方面的问题得以解决,单机的计算性能仍然难以满足这样的数据量的需求。有的人选择实现一个分布式共享内存系统,这一要求实际上相较于分布式文件系统更为苛刻,因此也因为类似的原因失败了。有的人选择实现分布式对象存储系统(或者叫 Key-Value 存储系统)。这一模型足够简单,但是实际上暗合了磁碟硬盘的模型,即存储空间由一系列 Blocks 组成,因此也得到了较为广泛的应用和很好的发展。

上面说的这些,实际上都是人们还没来得及实现 SQL 时的妥协方案。实际上是先抛开 SQL,解决更原始的问题,之后还是想要把 SQL 加回来的。对于这些方案,称之为 NoSQL 并没有什么不妥。但是在新的时代也确实涌现出了一些新的方法,这些显著不同的方法宣称自己是 NewSQL 或者是 Not only SQL。例如列式存储数据库在部分查询分析场景下的性能可能是传统数据库的 10-100 倍,全内存数据库的 TPS(Transactions Per Second)性能可能是传统数据库的 10-100 倍,等等[1]

参考

  1. ^"One size fits all": an idea whose time has come and gone https://ieeexplore.ieee.org/document/1410100

相关文章