前言
Spark是目前主流的分布式计算框架之一,本文谈在使用Spark进行计算时与结果正确性相关的一些issue的场景以及分析。
计算可以分为三个过程,数据读取,数据计算,数据写入,本文就从这三个部分来阐述可能遇到的问题以及规避方案(如有错误,请指正)。
数据读取
首先,Spark在生产中最常用的使用场景就是Spark-SQL。在Spark-SQL中,使用Hive的Metastore进行元数据存储,因此在使用中,往往是Spark DataSource表和Hive表共存。
表类型
表的类型,可以分为以下几种。
Hive内部表: 表不用指定location,直接存储在数据库对应的目录下,如果进行drop 操作,会将对应的数据删掉。
Hive外部表: 对表指定location,数据存在指定的路径下,如果进行drop操作,不会删除对应的数据,这样相对来说会更安全一些,减小一些误操作造成数据丢失的风险。
Spark DataSource表: 使用Spark DataSource创建的表,都是内部表。
Parquet是一种列式存储格式,在数据库场景中可以在查询时过滤掉不必要的数据,适用于读多写少的场景。
Spark选择Parquet作为常用的存储格式,因此在生产中,最常见的表就是Parquet表。
Parquet是一种存储格式,既然是存储,就会有写入和读取的过程,也就是序列化和反序列化。
在Spark-SQL场景中,有两种Parquet版本,一种是Spark内置的Parquet,一种是Hive内置的Parquet版本,往往Hive中的Parquet版本较老,而Spark中的Parquet较新,其序列化和反序列化性能更好,但是可能会出现一些不兼容的情况。
下面谈一下创建Spark DataSource表和Hive表的方式:
Spark DataSource表
使用Spark DataFrame API进行创建
使用 using parquet 来创建. 例如: create table ta(id int, name string) using parquet
Hive表
使用stored as parquet来创建. 例如: create table ta(id int, name string) stored as parquet
如果想判断一张已经建的表是Hive表还是Spark DataSource表可以使用show create table命令查看信息:
Hive表:可以看到其INPUTFORMAT/OUTPUTFORMAT是hive开头的。
Spark DataSource表: