spark连数据库
DataFrame提供了一条联结所有主流数据源并自动转化为可并行处理格式的渠道,通过它Spark能取悦大数据生态链上的所有玩家,无论是善用R的数据科学家,惯用SQL的商业分析师,还是在意效率和实时性的统计工程师。
以一个常见的场景 -- 日志解析为例,有时我们需要用到一些额外的结构化数据(比如做IP和地址的映射),通常这样的数据会存在MySQL,而访问的方式有两种:一是每个worker远程去检索数据库,弊端是耗费额外的网络I/O资源;二是使用JdbcRDD的API转化为RDD格式,然后编写繁复的函数去实现检索,显然要写更多的代码。而现在Spark一行代码就能实现从MySQL到DataFrame的转化,并且支持SQL查询。
在上一篇已经对文本格式进行测试,现在对hive hbase mysql oracle 以及临时表之间join查询做测试

1.访问mysql
除了JSON之外,DataFrame现在已经能支持MySQL、Hive、HDFS、PostgreSQL等外部数据源,而对关系数据库的读取,是通过jdbc实现的。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
bin/spark-shell --driver-class-path ./lib/mysql-connector-java-5.1.24-bin.jar val sc = new org.apache.spark.SparkContext val sqlContext = new org.apache.spark.sql.SQLContext(sc) val jdbcDF = sqlContext.load("jdbc", Map("url" -> "jdbc:mysql://192.168.0.110:3306/hidata?user=root&password=123456", "dbtable" -> "loadinfo")) bin/spark-sql --driver-class-path ./lib/mysql-connector-java-5.1.24-bin.jar spark-sql> create temporary table jdbcmysql using org.apache.spark.sql.jdbc options(url "jdbc:mysql://192.168.0.110:3306/hidata?user=root&password=123456",dbtable "loadinfo")spark-sql>select * from jdbcmysql;//注意src是hive本来就存在的表,在spark sql中不用建立临时表,直接可以进行操作//实现hive和mysql中表的联合查询select * from src join jdbcmysql on (src.key=jdbcmysql.id); |
2.访问Oracle
同理,但注意连接的URL不一样,也是试了好久
|
1
2
|
bin/spark-shell --driver-class-path ./lib/ojdbc6.jarval jdbcDF = sqlContext.load("jdbc", Map("url" -> "jdbc:oracle:thin:kang/123456@192.168.0.110:1521:orcl", "dbtable" -> "TEST")) |
Spark十八般武艺又可以派上用场了。
错误的URL:
|
1
2
|
val jdbcDF = sqlContext.load("jdbc", Map("url" -> "jdbc:oracle:thin:@192.168.0.110:1521:orcl&user=kang&password=123456", "dbtable" -> "TEST"))val jdbcDF = sqlContext.load("jdbc", Map("url" -> "jdbc:oracle:thin:@192.168.0.110:1521/orcl&user=kang&password=123456", "dbtable" -> "TEST")) |
报错类型:看起来最像的解决办法,留着以后用
java.sql.SQLException: Io : NL Exception was generated错误解决(jdbc数据源问题)
解决Oracle ORA-12505, TNS:listener does not currently know of SID given in connect
第一种方式,会告知无法识别SID,其实在连接时将orcl&user=kang&password=123456都当做其SID,其实就接近了。一般平时用jdbc连接数据库,url user password都分开,学习一下这种方式^^
Oracle的JDBC url三种方式:这
|
1
2
3
4
5
6
|
1.普通SID方式jdbc:oracle:thin:username/password@x.x.x.1:1521:SID2.普通ServerName方式jdbc:oracle:thin:username/password@//x.x.x.1:1522/ABCD3.RAC方式jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=x.x.x.1)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=x.x.x.2)(PORT=1521)))(LOAD_BALANCE=yes)(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=xxrac))) |
具体参看这里
3.访问hive
hive和spark sql的关系,参见
其实spark sql从一开始就支持hive。Spark提供了一个HiveContext的上下文,其实是SQLContext的一个子类,但从作用上来说,sqlContext也支持Hive数据源。只要在部署Spark的时候加入Hive选项,并把已有的hive-site.xml文件挪到$SPARK_HOME/conf路径下,我们就可以直接用Spark查询包含已有元数据的Hive表了。
1.Spark-sql方式
spark-sql是Spark bin目录下的一个可执行脚本,它的目的是通过这个脚本执行Hive的命令,即原来通过
hive>输入的指令可以通过spark-sql>输入的指令来完成。
spark-sql可以使用内置的Hive metadata-store,也可以使用已经独立安装的Hive的metadata store
配置步骤:
1. 将Hive的conf目录的hive-site.xml拷贝到Spark的conf目录
2. 将hive-site.xml中关于时间的配置的时间单位,比如ms,s全部删除掉
错误信息:Exception in thread "main" java.lang.RuntimeException:
java.lang.NumberFormatException: For input string: "5s" 一直以为是输入格式的问题。。
3. 将mysql jdbc的驱动添加到Spark的Classpath上
|
1
|
export SPARK_CLASSPATH=$SPARK_CLASSPATH:/home/hadoop/software/spark-1.2.0-bin-hadoop2.4/lib/mysql-connector-java-5.1.34.jar |
|
1
2
3
|
[hadoop@hadoop bin]$ ./spark-sql Spark assembly has been built with Hive, including Datanucleus jars on classpath SET spark.sql.hive.version=0.13.1 |
提示编译的时候要带2个参数
重新编译:./make-distribution.sh --tgz -Phadoop-2.4 -Pyarn -DskipTests -Dhadoop.version=2.4.1 -Phive -Phive-thriftserver
在Spark-default中已经指定
创建表
|
1
2
3
|
spark-sql> create table word6 (id int,word string) row format delimited fields terminated by ',' stored as textfile ; OK Time taken: 10.852 seconds |
导入数据
|
1
2
3
4
5
6
7
|
spark-sql> load data local inpath '/home/hadoop/word.txt' into table word6; Copying data from file:/home/hadoop/word.txt Copying file: file:/home/hadoop/word.txt Loading data to table default.word6 Table default.word6 stats: [numFiles=1, numRows=0, totalSize=31, rawDataSize=0] OK Time taken: 2.307 seconds |
与其他数据源联合查询
|
1
|
select * from src join jdbcmysql on (src.key=jdbcmysql.id); |
2.Spark-shell方式
|
1
|
sqlContext.sql("select count(*) from hive_people").show() |
4.将dataframe数据写入Hive分区表
DataFrame将数据写入hive中时,默认的是hive默认数据库,insertInto没有指定数据库的参数,使用下面方式将数据写入hive表或者hive表的分区中。这
1、将DataFrame数据写入到Hive表中
从DataFrame类中可以看到与hive表有关的写入Api有以下几个:
|
1
2
3
4
|
registerTempTable(tableName: String): Unit,insertInto(tableName: String): UnitinsertInto(tableName: String, overwrite: Boolean): UnitsaveAsTable(tableName: String, source: String, mode: [size=13.3333320617676px]SaveMode, options: Map[String, String]): Unit |
还有很多重载函数,不一一列举
registerTempTable函数是创建spark临时表
insertInto函数是向表中写入数据,可以看出此函数不能指定数据库和分区等信息,不可以直接进行写入。
向hive数据仓库写入数据必须指定数据库,hive数据表建立可以在hive上建立,或者使用hiveContext.sql(“create table ....")
下面语句是向指定数据库数据表中写入数据:
|
1
2
3
4
5
6
7
|
case class Person(name:String,col1:Int,col2:String) val sc = new org.apache.spark.SparkContext val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc) import hiveContext.implicits._ hiveContext.sql("use DataBaseName") val data=sc.textFile("path").map(x=>x.split("\\s+")).map(x=>Person(x(0),x(1).toInt,x(2)))<br>data.toDF()insertInto("tableName") |
创建一个case类将RDD中数据类型转为case类型,然后通过toDF转换为DataFrame,调用insertInto函数时,首先指定数据库,使用的是hiveContext.sql("use
DataBaseName")语句,就可以将DataFrame数据写入hive数据表中了
2、将DataFrame数据写入hive指定数据表的分区中
hive数据表建立可以在hive上建立,或者使用hiveContext.sql(“create table
...."),使用saveAsTable时数据存储格式有限,默认格式为parquet,可以指定为json,如果有其他格式指定,尽量使用语句来建立hive表。
将数据写入分区表的思路是:首先将DataFrame数据写入临时表,之后是由hiveContext.sql语句将数据写入hive分区表中。具体操作如下:
|
1
2
3
4
5
6
7
8
|
case class Person(name:String,col1:Int,col2:String) val sc = new org.apache.spark.SparkContext val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc) import hiveContext.implicits._ hiveContext.sql("use DataBaseName") val data = sc.textFile("path").map(x=>x.split("\\s+")).map(x=>Person(x(0),x(1).toInt,x(2))) data.toDF().registerTempTable("table1") hiveContext.sql("insert into table2 partition(date='2015-04-02') select name,col1,col2 from table1") |
使用以上方式就可以将dataframe数据写入hive分区表了。
spark连数据库的更多相关文章
- 160624、Spark读取数据库(Mysql)的四种方式讲解
目前Spark支持四种方式从数据库中读取数据,这里以Mysql为例进行介绍. 一.不指定查询条件 这个方式链接MySql的函数原型是: 1 def jdbc(url: String, table: S ...
- spark操作数据库的几种方法
一.使用jdbcRDD的接口: SparkConf conf = new SparkConf(); conf.setAppName("Simple Application").se ...
- 6.3 使用Spark SQL读写数据库
Spark SQL可以支持Parquet.JSON.Hive等数据源,并且可以通过JDBC连接外部数据源 一.通过JDBC连接数据库 1.准备工作 ubuntu安装mysql教程 在Linux中启动M ...
- zhihu spark集群,书籍,论文
spark集群中的节点可以只处理自身独立数据库里的数据,然后汇总吗? 修改 我将spark搭建在两台机器上,其中一台既是master又是slave,另一台是slave,两台机器上均装有独立的mongo ...
- SequoiaDB x Spark 新主流架构引领企业级应用
6月,汇集当今大数据界精英的Spark Summit 2017盛大召开,Spark作为当今最炙手可热的大数据技术框架,向全世界展示了最新的技术成果.生态体系及未来发展规划. 巨杉作为业内领先的分布式数 ...
- Spark SQL 之 Join 实现
原文地址:Spark SQL 之 Join 实现 Spark SQL 之 Join 实现 涂小刚 2017-07-19 217标签: spark , 数据库 Join作为SQL中一个重要语法特性,几乎 ...
- Spark jdbc postgresql数据库连接和写入操作源码解读
概述:Spark postgresql jdbc 数据库连接和写入操作源码解读,详细记录了SparkSQL对数据库的操作,通过java程序,在本地开发和运行.整体为,Spark建立数据库连接,读取数据 ...
- Spark jdbc postgresql数据库连接和写入操作源代码解读
概述:Spark postgresql jdbc 数据库连接和写入操作源代码解读.具体记录了SparkSQL对数据库的操作,通过java程序.在本地开发和执行.总体为,Spark建立数据库连接,读取数 ...
- 行业顶级NoSQL成员坐阵,NoSQL数据库专场重点解析!
NoSQL数据库作为数据库市场最重要的组成之一,它的一举一动都影响着成千上万的企业.本专场邀请了行业顶级的NoSQL核心成员与大家共同展望NoSQL数据库的未来,阿里巴巴.MongoDB.Rediss ...
随机推荐
- Docker命令使用详解(转)
如果各位看官熟悉 Git 和 GitHub ,可与 Docker 做个类比,可更加容易理解 Docker 和 Docker Hub 及两者关系. 1. docker version 显示 Docker ...
- /debug/requests is already registered. You may have two independent copies of golang.org/x/net/trace in your binary, trying to maintain separate state. This may involve a vendored copy of golang.org/x
找到问题就很好解决了,直接百度 go依赖管理-govendor go get -u github.com/kardianos/govendor 先获取这个,然后将govendor.exe放入path ...
- laravel实战化项目之三板斧
laravel实战化项目之三板斧 spring mvc 实战化项目之三板斧 asp.net mvc 实战化项目之三板斧 laravel是我工作10多年来见到的真正能称得上让phper从面条一样杂乱的代 ...
- SpringBoot2.x使用EasyPOI导入Excel浅谈
SpringBoot2.x使用EasyPOI导入Excel浅谈 平时经常遇到客户要帮忙导入一些数据到数据库中,有些数据比较多有时候手动录入就会很耗时间,所以就自己写一个Excel导入的demo记录一下 ...
- android构建过程
参考: http://blog.csdn.net/shangmingchao/article/details/47375111 首先,需要了解一下构建APK的七大工具: ①aapt 全称是Androi ...
- Rabbit五种消息队列学习(一) – 总述
RabbitMQ支持五种消息传递类型,分别如下图所示: 上图中显示6中消息队列分别为: 1.简单队列 一个生产者将消息放到队列中,一个消费者监听队列 2.工作队列(Work queues) 一个生产者 ...
- Saltstack之Scheduler
一.引言: 在日常的运维工作中经常会遇到需要定时定点启动任务,首先会考虑到crontab,但是通过crontab的话需要每台机器下进行设置,这样统一管理的话比较复杂:通过查百度和google发现sal ...
- Visual Studio 2017 - Windows应用程序打包成exe文件(2)- Advanced Installer 关于Newtonsoft.Json,LINQ to JSON的一个小demo mysql循环插入数据、生成随机数及CONCAT函数 .NET记录-获取外网IP以及判断该IP是属于网通还是电信 Guid的生成和数据修整(去除空格和小写字符)
Visual Studio 2017 - Windows应用程序打包成exe文件(2)- Advanced Installer Advanced Installer :Free for 30 da ...
- Effective Java 第三版——88. 防御性地编写READOBJECT方法
Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...
- 关于java多线程中异常捕获的理解
在java多线程程序中,所有线程都不允许抛出未捕获的checked exception(比如sleep时的InterruptedException),也就是说各个线程需要自己把自己的checked e ...