本次总结图如下
Spark Sql介绍
1、Shark是基于Spark计算框架之上的且兼容Hive语法的SQL执行引擎 ,但是底层依赖于Hive的解析器,查询优化器,正是由于Shark的整体设计架构对Hive的依赖性太强,难以支持其长远发张,无法满足Spark的一站式解决大数据处理问题
2、Hive是Shark的前身,Shark是SparkSql的前身
3、相对于Shark,SparkSQL的优势
a、完全脱离了Hive的限制
b、支持原生的RDD
c、能够在Scala中写Sql语句,支持简单的Sql语法检查,能够在Scala中写Hive语句访问Hive数据,并将结果取回作为RDD使用
创建SparkSql之DataFrame方式
1、通过读取json格式文件
2、通过一个JSON格式RDD
3、普通RDD转换DataFrame
a、反射方式(不建议),修改类或者增加类,麻烦
》自定义类必须是public
》自定义类必须是可序列化
》RDD转化成DataFramed的时候,DF中列的顺序会根据自定义类的字段名按照字典序进行排列
b、动态创建schedule方式
》可以将列信息存储到外部文件
4、通过读取parquet文件
a、数据输出
b、Parquet格式文件能够自动推断分区
5、通过读取mysql数据创建
6、通过读取Hive中的数据
Spark on Hive整合说明:Hive提供了一个metaStore服务,直接开启这个服务,spark Sql连接这个服务,就能读取数据
一:开启Hive的metaSotre服务 hive --service metaStore
二:在Spark集群客户端节点Spark的安装包目录conf,创建一个hive-site.xml
<configuration>
<property>
<name>hive.metastore.uris</name>
<value>thrift://hadoop1:9083</value>
</property>
</configuration>
三:开启spark shell测试是否成功
代码实现
SparkConf conf =new SparkConf().setAppName("DataFrameCreate").setMaster("local"); JavaSparkContext sc =new JavaSparkContext(conf); SQLContext sqlContext =new SQLContext(sc); DataFrame df=sqlContext.jsonFile("people.json"); df.registerTempTable("tb"); String sql= "select * from tb "; DataFrame result=sqlContext.sql(sql); result.show(); // SELECT age FROM tb result.select("age").show(); // SELECT name|'_1',age as _age FROM tb result.select(result.col("name"),result.col("age").plus(10).alias("_age")).show(); // SELECT * FROM tb WHERE age > 20 result.filter(result.col("age").gt(20)).show(); /** * 示例一: 通过读取json文件创建DataFrame * 读取数据文件,转成Dataframe */ DataFrame people =sqlContext.jsonFile("people.json"); //相当于 select age+20 as _age , name from people people.select(people.col("age").plus(20).alias("_age"),people.col("name")).show(); //相当于 select * from people where age >0 people.filter(people.col("age").gt(20)).show(); /** *示例二: 通过jsonRDD 创建DataFrame * 创建一个本地的集合 集合中元素的格式 json 类型String */ List<String> nameList = Arrays.asList( "{'name':'zhangsan', 'age':55}", "{'name':'lisi', 'age':30}", "{'name':'lisisi', 'age':30}", "{'name':'wangwu', 'age':19}"); List<String> scoreList = Arrays.asList( "{'name':'zhangsan','score':100}", "{'name':'lisi','score':99}" ); /** * 集合转成RDD */ JavaRDD<String> nameRdd=sc.parallelize(nameList); JavaRDD<String> scoreRdd=sc.parallelize(scoreList); /** * RDD转成DataFrame */ DataFrame nameDf =sqlContext.jsonRDD(nameRdd); DataFrame scoreDf =sqlContext.jsonRDD(scoreRdd); /** * 使用 DataFrame 对象联合查询 */ nameDf.join(scoreDf,nameDf.col("name").$eq$eq$eq(scoreDf.col("name"))) .select(nameDf.col("name"),nameDf.col("age"),scoreDf.col("score")).show(); System.out.println("---------------------------"); /** * 使用sql 方式查询 */ nameDf.registerTempTable("nameTB"); scoreDf.registerTempTable("scoreTB"); sql ="select * from nameTB n inner join scoreTB s on n.name =s.name"; sqlContext.sql(sql).show(); /** * 示例三: 使用动态创建schedule方式 */ JavaRDD<String> peopelStr=sc.textFile("Peoples.txt"); JavaRDD<Row> rowJavaRDD = peopelStr.map(new Function<String, Row>() { @Override public Row call(String s) throws Exception { String [] lines= s.split(","); return RowFactory.create(Integer.valueOf(lines[0]),lines[1],Integer.valueOf(lines[2])); } }); /** * 查询数据库 id_int_true, name_String_true, age_int_true * * id、Int、true * * 我们可以将每列的信息存储到外部文件或者数据库中,在创建schema的时候去外部文件或者数据库中查询 修改每一列的列名以及列的类型的时候就变的非常方便了 */ ArrayList<StructField> structFields=new ArrayList<>(); structFields.add(DataTypes.createStructField("id",DataTypes.IntegerType,true)); structFields.add(DataTypes.createStructField("name",DataTypes.StringType,true)); structFields.add(DataTypes.createStructField("age",DataTypes.IntegerType,true)); /** * 构建StructType,用于最后DataFrame元数据的描述 */ StructType structType=DataTypes.createStructType(structFields); /** * 通过schedule+RDD 来构造DataFrame */ DataFrame rowDF=sqlContext.createDataFrame(rowJavaRDD,structType); rowDF.show(); rowDF.registerTempTable("peotext"); System.out.println("------------------"); sqlContext.sql("select * from peotext").show(); //输出流 sqlContext.sql("select * from peotext").write().format("json").save("ttttt.text"); /** * 示例五:读取数据库方式 */ DataFrameReader reader =sqlContext.read().format("jdbc") ; reader.option("url","jdbc:mysql://192.168.0.153:3306/rb?useUnicode=true&characterEncoding=utf-8"); reader.option("dirver","com.mysql.jdbc.Driver"); reader.option("user","root"); reader.option("password","a1234567"); reader.option("dbtable","role"); DataFrame mysqlDf =reader.load(); mysqlDf.show(); sc.stop();