我们知道Hive,它是将Hive SQL转换成MapReduce然后提交到集群上执行,大大简化了编写MapReduc的程序的复杂性,但是由于Hive基于MapReduce进行处理,在该过程中大量的中间磁盘落地过程消耗了大量的I/O,这大大降低了运行效率。所有Spark SQL的应运而生,它是将Spark SQL转换成RDD,然后提交到集群执行,执行效率非常快!
Spark的RDD API 比传统的MapReduce API在易用性有了巨大的提升,但是对于没有MapReduce和函数式编程经验的新手,RDD API还是存在一定的门槛。Spark在SchemaRDD的基础上,提供了2个编程抽象:DataFrame和DataSet,作为分布式SQL查询引擎的作用。仅大大降低了新手学习门槛高,最重要的是脱胎SchemaRDD的DataFrame/DataSet支持分布式大数据处理。
SparkSQL对SQL语句的处理和关系型数据库采用了类似的方法,SparkSQL先会将SQL语句进行解析(Parse) 形成一个Tree,然后使用Rule 对Tree进行绑定、优化等处理过程,通过模式匹配对不同类型的节点采用不同的操作。而Spark SQL的查询优化器是Catalyst,它负责处理查询语句的解析、绑定、优化和生成物理计划等过程,Catalyst是SparkSQL最核心的部分,其性能优劣将决定整体的性能。
实质上,结构化API包含两类API,即非类型化的DataFrame和类型化的Dataset。说DataFrame是无类型的可能不太准确,因为它们其实是有类型的,只是Spark完全负责维护它们的类型,仅在运行时检查这些类型是否与schema中指定的类型一致。与之相对应的,Dataset在编译时就会检查类型是否符合规范。Dataset仅适用于基于Java虚拟机(JVM)的语言(比如Scala和Java),并通过case类或Java beans指定类型。
因此在大多数情况下,你会使用DataFrame。在Scala版本的Spark中, DataFrame就是一些Row类型的Dataset的集合。“Row”类型是Spark用于支持内存计算而优化的数据格式。这种格式有利于高效计算,因为它避免使用会带来昂贵垃圾回收开销和对象实例化开销的JVM类型,而是基于自己的内部格式运行,所以并不会产生这种开销。Python版本和R语言版本的Spark并不支持Dataset,所有东西都是DataFrame,这样我们就可以使用这种优化的数据格式进行计算处理。
第三章:SparkSQL编程(2)