Spark是一个通用的大规模数据快速处理引擎。可以简单理解为Spark就是一个大数据分布式处理框架。基于内存计算的Spark的计算速度要比Hadoop的MapReduce快上100倍以上,基于磁盘的计算速度也快于10倍以上。Spark运行在Hadoop第二代的yarn集群管理之上,可以轻松读取Hadoop的任何数据。能够读取HBase、HDFS等Hadoop的数据源。

从Spark 1.0版本起,Spark开始支持Spark SQL,它最主要的用途之一就是能够直接从Spark平台上面获取数据。并且Spark SQL提供比较流行的Parquet列式存储格式以及从Hive表中直接读取数据的支持。之后,Spark SQL还增加了对JSON等其他格式的支持。到了Spark 1.3 版本Spark还可以使用SQL的方式进行DataFrames的操作。我们通过JDBC的方式通过前台业务逻辑执行相关sql的增删改查,通过远程连接linux对文件进行导入处理,使项目能够初步支持Spark平台,现如今已支持Spark1.4版本。

SparkSQL具有内置的SQL扩展的基类实现Catalyst,提供了提供了解析(一个非常简单的用Scala语言编写的SQL解析器)、执行(Spark Planner,生成基于RDD的物理计划)和绑定(数据完全存放于内存中)。

前台我们使用ThriftServer连接后台SparkSQL,它是一个JDBC/ODBC接口,通过配置Hive-site.xml,就可以使前台用JDBC/ODBC连接ThriftServer来访问SparkSQL的数据。ThriftServer通过调用hive元数据信息找到表或文件信息在hdfs上的具体位置,并通过Spark的RDD实现了hive的接口。对于标签、客户群探索的增、删、改、查都是通过SparkSQL对HDFS上存储的相应表文件进行操作,突破了传统数据库的瓶颈,同时为以后的客户群智能分析作了铺垫。

1.数据的存储格式

我们使用Parquet面向列存存储的文件存储结构,因为Parquet具有高压缩比的特点且适合嵌套数据类型的存储,能够避免不必要的IO性能。Parquet建表如下所示:

CREATE TABLE dw_coclbl_d01_20140512_lzo_256_parquet(op_time string,

join_id double, city_id int, product_no string, brand_id int, vip_level int, county_id int, l2_01_01_04 double,  l2_01_01_04_01 double)

ROW FORMAT SERDE 'parquet.hive.serde.ParquetHiveSerDe'STORED AS

INPUTFORMAT 'parquet.hive.DeprecatedParquetInputFormat'

OUTPUTFORMAT 'parquet.hive.DeprecatedParquetOutputFormat';

2、由于压缩文件占用的空间较少,文件load的速度比较快。故使用压缩文件进行数据的load.使用gzip进行压缩时,单个文件只能在一个节点上进行load,加载时间很长。使用split命令将解压后的csv文件分割成多个256M的小文件,机器上每个block块的大小为128M,故将小文件分割为128M或256M以保证效率。由于Parquet存储格式暂时只支持Gzip,项目中暂时使用Gzip压缩格式。通过在控制台输入set mapreduce.output.fileoutputformat.compress=true指令命令设置压缩格式为true。再执行set mapreduce.output. fileoutput format.compress.codec = org.apache.hadoop.io.compress.GzipCodec;将文件的压缩格式设置为Gzip压缩格式

3、数据的导入。使用的是Apache的一个项目,最早作为Hadoop的一个第三方模块存在,主要功能是在Hadoop(hive)与传统的数据库(mysql、oracle等)间进行数据的传递,可以将一个关系型数据库中的数据导入到Hadoop的HDFS中,也可以将HDFS的数据导进到关系数据库中。

由于执行sqoop导入需要通过yarn的任务调度进行mapreduce,由于spark开启后即便在空闲状态下也不释放内存,故修改spark-env.sh配置,分配多余内存以便sqoop执行。

Create job -f 3 -t 4
Creating job for links with from id 3 and to id 4
    Please fill following values to create new job object
    Name: Sqoopy
    From database configuration
    Schema name: hive
    Table name: TBLS
    Table SQL statement: 
    Table column names: 
    Partition column name: 
    Null value allowed for the partition column: 
    Boundary query: 
    ToJob configuration
    Output format: 
      0 : TEXT_FILE
      1 : SEQUENCE_FILE
    Choose: 0
    Compression format: 
successfully created with validation status OK  and persistent id 2
     0 : NONE
      1 : DEFAULT
      2 : DEFLATE
      3 : GZIP
      4 : BZIP2
      5 : LZO
      6 : LZ4
      7 : SNAPPY
      8 : CUSTOM
    Choose: 0
    Custom compression format: 
    Output directory: hdfs://hadoop000:8020/sqoop2
    Throttling resources
    Extractors: 
    Loaders: 
    New job was

4、前台与后台交互工具类

工具类提供静态的方法,可以进行相应业务逻辑的调用,由于Hadoop集群存在于服务器端,前台需要实现跨平台服务器的连接,才能执行相应的Hadoop命令,实现对HDFS上文件的操作。此次设计的ShellUtils类,通过jsch连接Linux服务器执行shell命令.

private static JSch jsch;  
    private static Session session;  
    public static void connect(String user, String passwd, String host) throws JSchException {  
        jsch = new JSch();  
        session = jsch.getSession(user, host,22);  
        session.setPassword(passwd);  
        java.util.Properties config = new java.util.Properties();  
        config.put("StrictHostKeyChecking", "no");  
        session.setConfig(config);  

通过传入的Linux命令、用户名、密码等参数对远程linux服务器进行连接。由于执行Hadoop命令根据不同文件的大小所需占用的时间是不同的,在hadoop尚未将文件完全从hdfs上合并到本地时,本地会提前生成文件但文件内容为空,至此这里需要多传入前台客户群探索出来的客户群数目与文件条数进行对比,倘若数目相同则说明执行完毕。

CodecUtil类,用来实现不同类型压缩文件的解压工作,通过传入的压缩类型,利用反射机制锁定压缩的类型,由于存储在hdfs上的文件都是以文件块的形式存在的,所以首先需要获取hdfs中文件的二级子目录,遍历查询到每一个文件块的文件路径,随后通过输入输出流进行文件的解压工作。然后将此类打包成jar包放入集群中,通过前台远程连接服务端,执行hadoop命令操作执行,实现类部分代码如下:

public class CodecUtil{

public static void main(String[] args) throws Exception {

//compress("org.apache.hadoop.io.compress.GzipCodec");

String listName = args[0];

String codecType = args[1];

String hdfsPath = args[2];

uncompress(listName,codecType,hdfsPath);

//解压缩

public static void uncompress(String listName,String CodecType,String hdfsPath) throws Exception{

Class<?> codecClass = Class.forName(CodecType);

Configuration conf = new Configuration();

FileSystem fs = FileSystem.get(conf);

Path listf =new Path(hdfsPath+listName);

//获取根目录下的所有2级子文件目录

FileStatus stats[]=fs.listStatus(listf);

CompressionCodec codec = (CompressionCodec)

ReflectionUtils.newInstance(codecClass, conf);

int i;

for ( i = 0; i < stats.length; i++){

//获得子文件块的文件路径

String Random = findRandom();

Path list = new Path(stats[i].getPath().toString());

InputStream in = codec.createInputStream(inputStream);

FSDataOutputStream output = fs.create(new Path(hdfsPath + listName+"/"+unListName));

IOUtils.copyBytes(in, output, conf);

IOUtils.closeStream(in);

}

}

}

5、导入生成客户群

由于sparksql不支持insert into value语句,无法通过jdbc方式连接后台HDFS通过sparksql对文件进行导入数据的操作。于是将需要导入的csv文件通过ftp方式上传到远程服务器,再将文件通过load的方式导入表中,实现导入生成客户群的功能。

// 将文件上传到ftp服务器

CiFtpInfo ftp = customFileRelService.getCiFtpInfoByFtpType(1);

FtpUtil.ftp(ftp.getFtpServerIp(),ftp.getFtpPort(),ftp.getFtpUser(),DES.decrypt

(ftp.getFtpPwd()), ftpFileName, ftp.getFtpPath());

// 将文件load到表中

String ftpPath = ftp.getFtpPath();

if (!ftpPath.endsWith("/")) {

ftpPath = ftpPath + "/";

}

String sql = " LOAD DATA LOCAL INPATH '" + ftpPath + fileName

+ "' OVERWRITE INTO TABLE " + tabName;

log.info("loadSql=" + sql);

customersService.executeInBackDataBase(sql);

log.info("load table=" + tabName + " successful");

6、数据表或文件下载的实现

由于存储在hdfs上的数据为Gzip压缩格式,首先通过执行事先编好的解压代码对文件块进行解压,这里需要传入需要解压的文件名、解压类型、hdfs的完全路径,解压完毕后通过执行hadoop文件合并命令将文件从hdfs上合并到本地服务器,合并完毕后由于解压缩后的文件会占用hdfs的空间,同时执行hadoop文件删除命令将解压后的文件删除,再通过ftp传到前台服务器,完成客户群清单下载。

String command = "cd " + ftpPath + ";" + hadoopPath + "hadoop jar "+hadoopPath+"CodecTable.jar " + listRandomName +" "+ CodecType

+" " + " "+ hdfsWholePath + ";" + hadoopPath + "hadoop fs -cat '" +  hdfsPath + listRandomName + "/*'>" + listName1+".csv;" + hadoopPath +"hadoop fs -rm -r " + hdfsPath + listRandomName + ";" + "wc -l " + listName1 +".csv;";

LOG.debug(command);

flag = ShellUtils.execCmd(command, user, passwd, host,num);

清单的推送也是通过文件合并传输的方式进行其他平台的推送,大大降低了读取数据插入表数据所消耗的时间。

SparkSQL项目中的应用的更多相关文章

  1. VS项目中使用Nuget还原包后编译生产还一直报错?

    Nuget官网下载Nuget项目包的命令地址:https://www.nuget.org/packages 今天就遇到一个比较奇葩的问题,折腾了很久终于搞定了: 问题是这样的:我的解决方案原本是好好的 ...

  2. ABP项目中使用Swagger生成动态WebAPI

    本文是根据角落的白板报的<使用ABP实现SwaggerUI,生成动态webapi>一文的学习总结,感谢原文作者角落的白板报. 1 安装Swashbuckle.core 1.1 选择WebA ...

  3. iOS 之项目中遇到的问题总结

    昨天去一家公司面试,面试官问了我在项目开发中遇到过哪些问题,是什么引起的,怎样解决的? 当时由于有点小紧张只说出了一两点,现在就来好好总结一下. 问题: 1.两表联动 所谓的两表联动就是有左右两个表格 ...

  4. My97DatePicker时间控件在项目中的应用

    一.下载My97DatePicker的压缩包My97DatePicker.rar,解压. 注:My97DatePicker最新版本有开发包,项目中使用时删掉,以便节省空间,提高程序的运行效率. 二.在 ...

  5. 在项目中同时使用Objective-C和Swift

    苹果发布的Swift语言可以和之前的Objective-C语言同时存在于一个项目中. 可能有人会认为是同一个类文件中既可以有Objective-C也可以有Swift,这是不对的.同一个类文件或同一个代 ...

  6. 在数据库访问项目中使用微软企业库Enterprise Library,实现多种数据库的支持

    在我们开发很多项目中,数据访问都是必不可少的,有的需要访问Oracle.SQLServer.Mysql这些常规的数据库,也有可能访问SQLite.Access,或者一些我们可能不常用的PostgreS ...

  7. 在基于MVC的Web项目中使用Web API和直接连接两种方式混合式接入

    在我之前介绍的混合式开发框架中,其界面是基于Winform的实现方式,后台使用Web API.WCF服务以及直接连接数据库的几种方式混合式接入,在Web项目中我们也可以采用这种方式实现混合式的接入方式 ...

  8. Web API项目中使用Area对业务进行分类管理

    在之前开发的很多Web API项目中,为了方便以及快速开发,往往把整个Web API的控制器放在基目录的Controllers目录中,但随着业务越来越复杂,这样Controllers目录中的文件就增加 ...

  9. 如何决解项目中hibernate中多对多关系中对象转换json死循环

    先写一下原因吧!我是写的SSH项目,在项目中我遇到的问题是把分页对象(也就是pageBean对象)转化为json数据,下面为代码: public class PageBean <T>{// ...

随机推荐

  1. php部分---函数、四类常用函数、例子(下拉菜单添加内容);

    1.简单函数 四要素:返回类型,函数名,参数列表,函数体 function Show() { echo "hello"; } Show(); 2.有返回值的函数 function ...

  2. Apahce的虚拟用户认证及server-status页

    一.Apache虚拟用户认证配置 编辑配置文件加入如下内容: <Directory "/www/htdoc/fin"> Options None AllowOverri ...

  3. Objective-c——UI基础开发第六天(UITableView)

    一.UITableView的简单使用 显示要素: 1.显示多少给区组 2.显示多少行数据 3.每行显示什么内容 代理不会提醒你有什么方法没调用,但是UITableViewDataSource会 1)用 ...

  4. HTML初讲

    整理老师所讲: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...

  5. hihoCoder:#1079(线段树+离散化)

    题目大意:给n个区间,有的区间可能覆盖掉其他区间,问没有完全被其他区间覆盖的区间有几个?区间依次给出,如果有两个区间完全一样,则视为后面的覆盖前面的. 题目分析:区间可能很长,所以要将其离散化.但离散 ...

  6. CSS3卡片旋转效果

    HTML: <div id="rotate"> <div id="rotate_wrap"> <div id="fron ...

  7. 黑马程序员——JAVA基础之Map集合

    ------- android培训.java培训.期待与您交流! ---------- Map集合: 该集合存储键值对.一对一对往里存.而且要保证键的唯一性. 和Set很像,其实Set底层就是使用了M ...

  8. 7 款开源 Java 反编译工具

    今天我们要来分享一些关于Java的反编译工具,反编译听起来是一个非常高上大的技术词汇,通俗的说,反编译是一个对目标可执行程序进行逆向分析,从而得到原始代码的过程.尤其是像.NET.Java这样的运行在 ...

  9. android数据存储之Sqlite(一)

    SQLite学习笔记 1. Sqlite简介 SQLite是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入 式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低 ...

  10. Extjs4.2.1中的helloworld

    ExtJS最新正式版4.2.1下载地址:http://pan.baidu.com/s/1qWNt2kk (开发api文档:https://github.com/extjs-doc-cn/ext4api ...