如果用户希望在spark sql 中,执行某个sql 后,将其结果集保存到本地,并且指定csv 或者 json 格式,在 beeline 中,实现起来很麻烦。通常的做法是将其create table tempTable as *** ,通过将结果集写入到新的临时表中,进行保存,然后再通过其他方式export 到本地。

这种方式,对于 HDFS 是可行到,但是如果数据是保存在像SequoiaDB 中,就比较难办了。因为spark 向 SequoiaDB 写入记录时,可能部分task 会失败重试,这样就容易造成SequoiaDB 目标表中写入了重复记录,从而造成数据不准确的问题。

因此,需要寻找一种的新的方式,将其结果集准确地读取出来,并且写入本地文件。

在网上有很多替代方案,无外乎是通过beeline 或者 spark-sql ,执行 SQL 命令,通过重定向的方式,将结果集保存到指定文件中。

这样的方式,首先不讨论其输出格式的问题,最无法让人接受的是,spark-sql 需要将所有的结果数据收集到一个 Driver 进程中后,才会开始输出终端。这个过程有以下 3 个问题

  1. 时间久,如果数据量大了,Driver 收集的过程会很久,并且通过top 可以查看到进程CPU 飙升
  2. 容易OOM,当数据量增大后,因为需要将所有结果数据存储在内存中,一旦数据量用超了,就抛出 OOM 的错误,一切前功尽弃
  3. 输出格式,因为保存本地文件的内容就是输出终端的数据,CSV 格式不友好,有时候甚至会因为不可见字符而导致整个本地文件格式错乱,最终导致数据无法恢复

所以本文主要是向读者们介绍一种新的方式,直接使用 scala / python 语言开发的程序,利用 RDD 将其结果数据保存本地,输出格式支持 CSV 和 JSON。

  • scala 版本

scala 版本作者没有直接编写程序,但是通过 spark-shell 进行了验证

import org.apache.spark.sql.hive.HiveContext
// sc - existing spark context
val sqlContext = new HiveContext(sc)
val df = sqlContext.sql("SELECT * FROM test_sdb")
df.coalesce().write.format("com.databricks.spark.csv").mode("overwrite").option("header", "true").save("/opt/sequoiadb/chenfool")

如果有用户喜欢这个方式,可以考虑将程序打包成jar 包来执行。

导出格式的更多参数,请参考 python 版本

  • python 版本

在执行python 的脚本前,首先需要设置一下环境变量

export SPARK_HOME=/root/software/spark-2.1.-bin-hadoop2.
export PYTHONPATH=${SPARK_HOME}/python/:${SPARK_HOME}/python/lib/py4j-0.10.-src.zip;

注意:py4j-0.10.4-src.zip 文件名可能随不同的spark 版本有所变化

然后准备以下脚本程序, spark_sql_export.py

import atexit
import os
import platform import pyspark
from pyspark.context import SparkContext
from pyspark.sql import SparkSession, SQLContext spark = SparkSession \
.builder \
.enableHiveSupport() \
.getOrCreate() df = spark.sql("SELECT * FROM test_sdb limit 100") #df.coalesce(1).write.format("org.apache.spark.sql.json").mode("overwrite") \
# .save("/opt/sequoiadb/chenfool") df.coalesce(1).write.format("com.databricks.spark.csv").mode("overwrite") \
.option("enforceSchema", "false") \
.option("quoteAll", "true") \
.option("escapeQuotes", "false") \
.option("header", "true") \
.option("delimiter", "|") \
.option("charToEscapeQuoteEscaping", "\"") \
.option("inferSchema", "true") \
.option("ignoreLeadingWhiteSpace", "false") \
.option("ignoreTrailingWhiteSpace", "false") \
.save("/opt/sequoiadb/chenfool")

执行方式

python spark_sql_export.py

结果数据就会被保存在 /opt/sequoiadb/chenfool/part-00000* 文件中。

结果数据只会被保存在一个文件中,因为设置了 coalesce 参数。

JSON 格式请参考 spark_sql_export.py 注释部分。

CSV 的详细参数,可以参考spark 源码:${SPARK_HOME}/sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/csv/CSVOptions.scala

注意:

在spark 2.1.1 版本中,ignoreLeadingWhiteSpace 和 ignoreTrailingWhiteSpace 参数无法生效,默认值为:true。在 spark 2.4.0 版本中,经过测试,这两个参数才能够生效。如果要求保存的数据中不做 trim 操作,只能够将spark 升级为2.4.0 版本。

本博客参考了之前 spark 学习(二) 的内容,里面有介绍如果利用python 来执行spark 的程序的说明,感兴趣的读者们可以移步查阅

spark sql 导出数据的更多相关文章

  1. SQL导出数据到EXCEL的问题

    DTS导出向导 不会 我这有个是用C#语言写的 try { Excel.Application xApp = new Excel.ApplicationClass(); xApp.Visible = ...

  2. 使用sql导出数据_mysql

    在mysql中 使用sql 脚本导出数据的方式之一: select * from table_name where x=y  INFO OUTFILE "/tmp/table_name.tx ...

  3. Sql Server 2000/2008 用Sql导出数据表结构(包括注释)到Excel

    --Sql Server 2000 declare @id int, ), ) declare cur_1 cursor for select id,name from sysobjects wher ...

  4. spark sql中将数据保存成parquet,json格式

    val df = sqlContext.load("/opt/modules/spark1.3.1/examples/src/main/resources/people.json" ...

  5. Spark SQL数据加载和保存实战

    一:前置知识详解: Spark SQL重要是操作DataFrame,DataFrame本身提供了save和load的操作, Load:可以创建DataFrame, Save:把DataFrame中的数 ...

  6. Spark SQL读取Oracle的number类型的数据时精度丢失问题

    Spark SQL读取数据Oracle的数据时,发现number类型的字段在读取的时候精度丢失了,使用的spark版本是Spark2.1.0的版本,竟然最后经过排查和网上查资料发现是一个bug.在Sp ...

  7. Spark SQL数据载入和保存实战

    一:前置知识具体解释: Spark SQL重要是操作DataFrame,DataFrame本身提供了save和load的操作. Load:能够创建DataFrame. Save:把DataFrame中 ...

  8. 新闻网大数据实时分析可视化系统项目——18、Spark SQL快速离线数据分析

    1.Spark SQL概述 1)Spark SQL是Spark核心功能的一部分,是在2014年4月份Spark1.0版本时发布的. 2)Spark SQL可以直接运行SQL或者HiveQL语句 3)B ...

  9. Spark SQL笔记——技术点汇总

    目录 概述 原理 组成 执行流程 性能 API 应用程序模板 通用读写方法 RDD转为DataFrame Parquet文件数据源 JSON文件数据源 Hive数据源 数据库JDBC数据源 DataF ...

随机推荐

  1. Python习题-一个函数实现读写功能

    def new_op_file(filename,content=None): f = open(filename,'a+') f.seek(0) if content: #非空即真,如果有内容就往下 ...

  2. nodejs cluster 学习记录

    最近在使用 egg.js ,这个框架提供多进程管理机制 我们知道 JavaScript 代码是运行在单线程上的,换句话说一个 Node.js 进程只能运行在一个 CPU 上.如何榨干服务器资源,利用上 ...

  3. IpIImage -> CvMat 转换方法

    Ipl转为CvMat 一般为这两种方法: 1: /*cvGetMat*/ CvMat matheader; CvMat * mat = cvGetMat(img, &matheader); 2 ...

  4. PS 滤镜——水波 water wave

    %%%% Water wave %%%% 制作水波效果 clc; clear all; close all; addpath('E:\PhotoShop Algortihm\Image Process ...

  5. SHOI2016 随机序列

    给你一个数列,在相邻两个数之间插入加号,减号或乘号 每次支持单点修改,求所有这样可以得到的表达式之和,膜1e9 + 7 sol: 我是个 sb ... 可以发现,如果某位置出现了加号,后面一定有一个减 ...

  6. bzoj 1242 弦图判定 MCS

    题目大意: 给定一张无向图,判断是不是弦图. 题解: 今天刚学了<弦图与区间图> 本来写了一个60行+的学习笔记 结果因为忘了保存重启电脑后被还原了... 那就算了吧. MCS最大势算法, ...

  7. Windows下安装MySQL-5.7.19

    下载MySQL-5.7.19版本,解压之后发现安装包不是一个exe文件: 于是网上找资料,发现了另外一种安装方法. 1.新建一个环境变量,我的电脑-属性-高级-环境变量-系统变量-新建 2.在系统变量 ...

  8. 简单易懂dubbo入门实例

    一.创建Maven多模块项目 项目结构如下 模块介绍: dubbo-api            ----API接口 dubbo-consumer ----消费者 dubbo-provider     ...

  9. nginx gzip

    # 开启gzip gzip on;   # 启用gzip压缩的最小文件,小于设置值的文件将不会压缩 gzip_min_length 1k;   # gzip 压缩级别,1-10,数字越大压缩的越好,也 ...

  10. LAMP 1.2 Apache编译安装

    1.下载                                                                                                 ...