Spark全栈:SQL vs.NoSQL

来自CloudWiki
跳转至: 导航搜索

NoSQL运动把我们从SQL的束缚中解放了出来。这是什么意思呢?这意味着NoSQL给了我们除关系型数据库中SQL以外的数据处理方式。SQL模式的问题不是SQL语言本身,而是单一的数据处理方式,让人们似乎不得不把所有的数据处理交给SQL,而无视了数据本身是否真的适合这种方式。

随着像Spark这样的新工具出现,SQL和NoSQL已经逐渐统一 。人们开始意识到只要有足够多的数据处理方式可选,SQL本身其实也是非常有用的。

SQL

SQL在构建数据分析应用时到底会发挥什么作用呢?要查询关系型、结构化的数据,我们通常使用SQL这类声明式的编程语言。在SQL中,我们只要声明我们想要的是什么,而不是写要怎么获得我们想要的。这和Java、Scala、Python等语言所属的命令式的编程迥然不同。用SQL我们只要写我们要的输出,而不是对数据的一组具体操作。

SQL有两大不足之处。首先,我们要依赖数据库来决定如何执行查询操作,这对于查询来说可能是好事也可能是坏事,取决于具体的查询操作。对于大数据场景,这就有问题了。如果查询计划器不好,我们可能会永远也等不到查询完成的时候。

使用PySpark,只要我们想做,就可以通过数据流编程指定各操作具体该怎么完成。在不想这么做的时候,PySpark的SQL抽象也可以为我们生成执行计划。我们可以兼得两种方式的优点。

其次是复杂性。一旦查询过于复杂,SQL语句就非常难以看懂。查询语句嵌套的子查询中还嵌套着子查询,这意味着代码不够直观。对于复杂操作,命令式的代码比声明式的更加易读、易理解。

对于简单的查询来说,SQL强大、简单、易学,优点明显。

NoSQL与数据流编程

与SQL相反,在构建分析型应用时,我们常常并不知道要执行的查询是什么,因此我们无法写出查询语句,需要许多次试验和迭代才能得到问题的解。数据也常常不是以关系型的形式存在的。很多数据尚未处理,仍是杂乱无章的脏数据。提取这些数据的结构是一个冗长的过程,因此我们选择在迭代中依次提取不同的特征。直接获取数据的结构是不现实的。

出于这样的原因,在敏捷数据科学中,我们经常要使用运行于分布式系统上的命令式的语言。Python和PySpark这种命令式的工具让我们可以描述操作数据的步骤。我们要用到并行的多处理核来暴力读取数据记录以快速执行,而不是使用基于我们还没获得的结构才能预计算的索引。Spark(以及之前的Hadoop)使这一切成为可能。

除了可以很好地利用Hadoop和Spark等技术让我们轻松扩展数据处理,命令式语言还让我们把重点放在构建分析型应用的主要任务上:以迭代和增量的方式搞定艰难而关键的步骤。这也是让我们的应用能够发掘价值的关键所在,是一个内在的命令式过程。和写SQL语句相比,实现这些精巧的命令式操作是一个漫长而曲折的过程,我们要用到包括统计学、机器学习、社会科学等在内的技术。这种任务适合命令式编程。

Spark: SQL+NoSQL

所以,SQL是为查询数据而优化设计的,而针对数据流的工具则是为提炼数据而优化设计的。我们既需要查询数据(对数据提问),也需要处理数据(从一个或多个数据源中计算出一些新东西)。幸运的是,Spark同时支持这两种编程范式!这是Spark接口中最大的创新。这个特性使得我们可以在声明式的SQL语句和命令式的Python语句中随心所欲地自由切换。这是Spark的一大好处。相对于Hadoop是一个巨大的进步。之前,Pig(Hadoop软件栈中的数据流编程工具)和Hive(Hadoop软件栈中的SQL)是两个相互独立的工具,而且很不幸的是这两个工具社区之间还有些不友好。

NoSQL中的表结构

我们使用数据流编程语言在代码中定义数据的格式,然后使用SQL查询数据,或直接发布到文档存储中。这些都不需要正式指定表结构!表结构信息随数据存在,是内在的而不是外在的。这是为数据科学而优化的,

数据序列化

尽管我们可以直接操作纯文本格式的半结构化数据,但是使用一些包含表结构信息的格式还是可以帮助强化原始记录的某些结构化信息。

JSON行格式也叫作换行符分隔的JSON格式(newline-delimited JSON(NDJSON)) (http://ndjson.org/),这种格式很简单,一条JSON记录会被存储为文本中的一行。

动态结构表的特征提取与呈现

正如Pete Warden在他的讲座“拥抱混沌的数据”(Embracing the Chaos of Data)中提到的,大多数可以免费得到的数据都很粗糙而且是非结构化的。这些难看的、没有仔细清理并正则化的数据表有很多,也很容易获得,正是对这些数据的处理,才称得上“大数据”。

从非结构化数据中提取出的特征只有在“强光曝晒”下才会变得更好,因为用户使用了这些特征,如果不好用会进行投诉;特征必须在生成时就以某种产品的形式呈现,否则将永远无法达到可以用于实际决策的状态。产品内部的中间数据不会自行改善。最好创建出实体页面,让数据逐渐达到“客户级别”的形式,不断改进这些实体,逐步将它们组合起来,而不是试图从一开始就以宏大的视角展示数不清的中间数据。