SparkSql实现Mysql到hive的数据流动
今天去面试了一波,因为调度系统采用了SparkSql实现数据从Mysql到hive,在这一点上面试官很明显很不满我对于Spark的理解,19年的第一个面试就这么挂了。
有问题不怕,怕的是知道了问题还得过且过。现在就来梳理下我的项目是怎么使用Spark导数的
第一步:把mysql中的表放入内存
properties.put("user", dbUser);
properties.put("password", dbPassword);
properties.put("driver", dbDriver);
Dataset<Row> bizdateDS = sparkSession.read().jdbc(
dbUrl,
dbTableName,
properties
);
其中:org.apache.spark.sql.Dataset(这里面试官问我怎么把mysql的数据转化到Spark,我没答上来)
第二步:创建数据库与表
2.1 创建库
String createDBSQL = "CREATE DATABASE IF NOT EXISTS " + hiveDBName + " LOCATION '" + dbPath + "'";
sparkSession.sql(createDBSQL);
```
2.2创建表
分成两步,第一步读取Mysql元数据字段,第二步把这些字段创建出来
2.2.1 读取mysql字段
StructType structType = bizdateDS.schema();
StructField[] structFields = structType.fields();
/*
structField是StructType中的字段。
param:name此字段的名称。
param:dataType此字段的数据类型。
param:nullable指示此字段的值是否为空值。
param:metadata此字段的元数据。 如果未修改列的内容(例如,在选择中),则应在转换期间保留元数据。
*/
2.2.2 创建字段
String sourceType; //Name of the type used in JSON serialization.
String columnName;
String targetType;
StructField structField;
SparkDataTypeEnum sparkDataType;
StringBuilder createBuilder = new StringBuilder(capacity);
createBuilder.append("CREATE TABLE IF NOT EXISTS ").append(realHiveTableName).append(" (");
List<String> dbTableColumns = Lists.newArrayList();
Map<String, String> dbTableColumnTypeMap = Maps.newHashMap();
//把Mysql中的每个字段都提取出来
for (int i = 0, len = structFields.length; i < len; i++) {
structField = structFields[i];
sourceType = structField.dataType().typeName();
columnName = structField.name();
if (sourceType.contains("(")) { //处理类似varchar(20)
sourceType = sourceType.substring(0, sourceType.indexOf("("));
}
sparkDataType = SparkDataTypeEnum.getItemByType(sourceType);
if (null != sparkDataType) {
targetType = sparkDataType.getHiveDataType().getType();
//时间戳字段强转成string字段
if(targetType.equals("timestamps")) targetType.equals("string");
} else {
targetType = HiveDataTypeEnum.STRING.getType();
}
dbTableColumns.add(columnName);
dbTableColumnTypeMap.put(columnName, targetType);
if (i != 0) {
createBuilder.append(",");
}
createBuilder.append(columnName).append(" ").append(targetType);
}
createBuilder.append(") PARTITIONED by (").append(partitionColumn)
.append(" STRING) ");
sparkSession.sql(createTableSQL);
2.3 对比字段
我们在2.2中,如果hive有字段了,那么就不会创建表。
问题在于,如果hive中的字段比mysql中的少怎么办?
2.3.1 获取hive中的表字段
HiveUtil connectionToHive = new HiveUtil("org.apache.hive.jdbc.HiveDriver", hiveUrl, hiveUser, hivePassword);
public List<String> getTableColumns(String dbName,String tableName) throws SQLException {
ResultSet rs = null;
try {
if (!this.validateTableExist(tableName)) {
return null;
}
DatabaseMetaData metaData = connection.getMetaData();
rs = metaData.getColumns(null, dbName, tableName.toUpperCase(), "%");
List<String> columns = new ArrayList();
while (rs.next()) {
columns.add(rs.getString("COLUMN_NAME").toLowerCase());
}
return columns;
} catch (SQLException e) {
throw e;
} finally {
if (null != rs) {
rs.close();
}
}
}
2.3.2 对比字段并且添加:
for (String dbTableColumn : dbTableColumns) {
if (StringUtil.hasCapital(dbTableColumn)) {
DingDingAlert.sendMsg(dbTableName + "的" + dbTableColumn + "是大写字段,替换成小写");
logger.warn(dbTableName + "的" + dbTableColumn + "是大写的,把他替换成小写");
sb.append("\n " + GetTime.getTimeStamp("yyyy-MM-dd HH:mm:ss") + "| WARN |" + "表" + hiveTableName + "在hive中不存在,程序关闭");
dbTableColumn = StringUtil.convertStringToLowerCase(dbTableColumn, false);
}
if (!hiveTableColumns.contains(dbTableColumn)) {
alterColumns.add(dbTableColumn);
}
}
2.4 将内存中的表存入hive
bizdateDS.createOrReplaceTempView(tmpTableName); //注意这里不是直接从mysql抽到hive,而是先从Mysql抽到内存中
insert hive_table select hive中的已经有的表的字段 from tmpTableName
##很明显的,如果不是需要和hive已经有的表交互根本用不到jdbc
SparkSql实现Mysql到hive的数据流动的更多相关文章
- 从MySQL到Hive,数据迁移就这么简单
使用Sqoop能够极大简化MySQL数据迁移至Hive之流程,并降低Hadoop处理分析任务时的难度. 先决条件:安装并运行有Sqoop与Hive的Hadoop环境.为了加快处理速度,我们还将使用Cl ...
- 使用Sqoop从mysql向hdfs或者hive导入数据时出现的一些错误
1.原表没有设置主键,出现错误提示: ERROR tool.ImportTool: Error during import: No primary key could be found for tab ...
- Spark操作MySQL,Hive并写入MySQL数据库
最近一个项目,需要操作近70亿数据进行统计分析.如果存入MySQL,很难读取如此大的数据,即使使用搜索引擎,也是非常慢.经过调研决定借助我们公司大数据平台结合Spark技术完成这么大数据量的统计分析. ...
- 从hive将数据导出到mysql(转)
从hive将数据导出到mysql http://abloz.com 2012.7.20 author:周海汉 在上一篇文章<用sqoop进行mysql和hdfs系统间的数据互导>中,提到s ...
- sqoop用法之mysql与hive数据导入导出
目录 一. Sqoop介绍 二. Mysql 数据导入到 Hive 三. Hive数据导入到Mysql 四. mysql数据增量导入hive 1. 基于递增列Append导入 1). 创建hive表 ...
- Hive[4] 数据定义 HiveQL
HiveQL 是 Hive 查询语言,它不完全遵守任一种 ANSI SQL 标准的修订版,但它与 MySQL 最接近,但还有显著的差异,Hive 不支持行级插入,更新和删除的操作,也不支持事务,但 H ...
- hadoop笔记之Hive的数据存储(视图)
Hive的数据存储(视图) Hive的数据存储(视图) 视图(view) 视图是一种虚表,是一个逻辑概念:可以跨越多张表 既然视图是一种虚表,那么也就是说用操作表的方式也可以操作视图 但是视图是建立在 ...
- Sqoop使用,mysql,hbase,hive等相互转换
Sqoop 是一款用来在不同数据存储软件之间进行数据传输的开源软件,它支持多种类型的数据储存软件. 安装 Sqoop 1.下载sqoop并加mysql驱动包 http://mirror.bit.edu ...
- 使用sqoop将MySQL数据库中的数据导入Hbase
使用sqoop将MySQL数据库中的数据导入Hbase 前提:安装好 sqoop.hbase. 下载jbdc驱动:mysql-connector-java-5.1.10.jar 将 mysql-con ...
随机推荐
- Qt5 编程基础
Qt 是一个C++ GUI应用框架,Qt 具有良好的可移植性支持大多数桌面和移动操作系统并常用于嵌入式开发. Qt的发行版分为商业版和开源版,提供了Qt Creator作为轻量级IDE. Hello ...
- c#调用webservices
有两种方式,静态调用(添加web服务的暂且这样定义)和动态调用: 静态调用: 使用添加web服务的方式支持各种参数,由于vs2010会自动转换,会生成一个特定的Reference.cs类文件 动态 ...
- 对象的深度拓展$.extend(true,{},a,b),深入理解,小心陷阱
转载:https://www.cnblogs.com/DJeanWeb/p/4388689.html $.extend一般情景下,使用深度拓展两个对象时,我们想要的效果是,b对象覆盖掉a对象中存在的所 ...
- [javaSE] 集合框架(HashSet)
Set:元素是无序,不可重复的 HaseSet:底层数据结构是哈希表 定义一个类Demo 获取Demo对象,system.out.println(demo),打印demo对象,Demo@xxxxxx ...
- vue + element ui 表格自定义表头,提供线上demo
前言:工作中用到 vue+element ui 的前端框架,需要使用自定义表头,需要使用 re.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9710826.h ...
- java设计模式-----18、职责链模式
概念: Chain of Responsibility(CoR)模式也叫职责链模式.责任链模式或者职责连锁模式,是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的 ...
- Centos7 安装 ActiveMq
1.安装 # cd /usr/local/src/# wget http://mirrors.shu.edu.cn/apache//activemq/5.15.3/apache-activemq-5. ...
- [js高手之路]Node.js实现简易的爬虫-抓取博客所有文章列表信息
抓取目标:就是我自己的博客:http://www.cnblogs.com/ghostwu/ 需要实现的功能: 抓取博客所有的文章标题,超链接,文章摘要,发布时间 需要用到的库: node.js自带的h ...
- 一步一步学Python-基础篇
1.安装 地址:https://www.python.org/downloads/windows/ 安装完成过后,配置环境变量,比如:path后面计入;C:\Python27(可能需要重启一下) 然后 ...
- JS全局变量VAR和THIS--在函数内部,加var是局部变量,不加是全局变量
JS全局变量VAR和THIS 2011-05-23 21:43 很多人都觉得在JavaScript声明一个变量,加var和不加var没有什么区别,实际上是一个错误的观点,如果在函数外面,也就是说在wi ...