spark 读取各类数据源

原创 2018年04月15日 18:56:10

本文章主要通过代码实现spark读取各类数据源

1 spark读取hive数据

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.hive.HiveContext;

/**
 * Hive数据源
 * @author Administrator
 *
 */
public class HiveDataSource {

   @SuppressWarnings("deprecation")
   public static void main(String[] args) {
      // 首先还是创建SparkConf
      SparkConf conf = new SparkConf()
            .setAppName("HiveDataSource");
      // 创建JavaSparkContext
      JavaSparkContext sc = new JavaSparkContext(conf);
      // 创建HiveContext,注意,这里,它接收的是SparkContext作为参数,不是JavaSparkContext
      HiveContext hiveContext = new HiveContext(sc.sc());
      
      // 第一个功能,使用HiveContext的sql()方法,可以执行Hive中能够执行的HiveQL语句
      // 判断是否存在student_infos表,如果存在则删除
      hiveContext.sql("DROP TABLE IF EXISTS student_infos");
      // 判断student_infos表是否不存在,如果不存在,则创建该表
      hiveContext.sql("CREATE TABLE IF NOT EXISTS student_infos (name STRING, age INT)");
      // 将学生基本信息数据导入student_infos表
      hiveContext.sql("LOAD DATA "
            + "LOCAL INPATH '/usr/local/spark-study/resources/student_infos.txt' "
            + "INTO TABLE student_infos");
      
      // 用同样的方式给student_scores导入数据
      hiveContext.sql("DROP TABLE IF EXISTS student_scores"); 
      hiveContext.sql("CREATE TABLE IF NOT EXISTS student_scores (name STRING, score INT)");  
      hiveContext.sql("LOAD DATA "
            + "LOCAL INPATH '/usr/local/spark-study/resources/student_scores.txt' "
            + "INTO TABLE student_scores");
      
      // 第二个功能,执行sql还可以返回DataFrame,用于查询
      // 执行sql查询,关联两张表,查询成绩大于80分的学生
      DataFrame goodStudentsDF = hiveContext.sql("SELECT si.name, si.age, ss.score "
            + "FROM student_infos si "
            + "JOIN student_scores ss ON si.name=ss.name "
            + "WHERE ss.score>=80");
      
      // 第三个功能,可以将DataFrame中的数据,理论上来说,DataFrame对应的RDD的元素,是Row即可
      // 将DataFrame中的数据保存到hive表中
      // 接着将DataFrame中的数据保存到good_student_infos表中
      hiveContext.sql("DROP TABLE IF EXISTS good_student_infos");  
      goodStudentsDF.saveAsTable("good_student_infos");  
      
      // 第四个功能,可以用table()方法,针对hive表,直接创建DataFrame
      
      // 然后针对good_student_infos表,直接创建DataFrame
      Row[] goodStudentRows = hiveContext.table("good_student_infos").collect();  
      for(Row goodStudentRow : goodStudentRows) {
         System.out.println(goodStudentRow);  
      }
      
      sc.close();
   }
   
}

2 spark读取jdbc数据源

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.api.java.function.VoidFunction;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;

import scala.Tuple2;

/**
 * JDBC数据源
 * @author Administrator
 *
 */
public class JDBCDataSource {

   public static void main(String[] args) {
      SparkConf conf = new SparkConf()
            .setAppName("JDBCDataSource");  
      JavaSparkContext sc = new JavaSparkContext(conf);
      SQLContext sqlContext = new SQLContext(sc);
      
      // 总结一下
      // jdbc数据源
      // 首先,是通过SQLContext的read系列方法,将mysql中的数据加载为DataFrame
      // 然后可以将DataFrame转换为RDD,使用Spark Core提供的各种算子进行操作
      // 最后可以将得到的数据结果,通过foreach()算子,写入mysql、hbase、redis等等db / cache中
      
      // 分别将mysql中两张表的数据加载为DataFrame
      Map<String, String> options = new HashMap<String, String>();
      options.put("url", "jdbc:mysql://spark1:3306/testdb");
      options.put("dbtable", "student_infos");

      DataFrame studentInfosDF = sqlContext.read().format("jdbc")
            .options(options).load();
      
      options.put("dbtable", "student_scores");
      DataFrame studentScoresDF = sqlContext.read().format("jdbc")
            .options(options).load();
      
      // 将两个DataFrame转换为JavaPairRDD,执行join操作
      JavaPairRDD<String, Tuple2<Integer, Integer>> studentsRDD = 
            
            studentInfosDF.javaRDD().mapToPair(
            
                  new PairFunction<Row, String, Integer>() {
      
                     private static final long serialVersionUID = 1L;
            
                     @Override
                     public Tuple2<String, Integer> call(Row row) throws Exception {
                        return new Tuple2<String, Integer>(row.getString(0), 
                              Integer.valueOf(String.valueOf(row.get(1))));  
                     }
                     
                  })
            .join(studentScoresDF.javaRDD().mapToPair(
                     
                  new PairFunction<Row, String, Integer>() {
      
                     private static final long serialVersionUID = 1L;
      
                     @Override
                     public Tuple2<String, Integer> call(Row row) throws Exception {
                        return new Tuple2<String, Integer>(String.valueOf(row.get(0)),
                              Integer.valueOf(String.valueOf(row.get(1))));  
                     }
                     
                  }));
      
      // 将JavaPairRDD转换为JavaRDD<Row>
      JavaRDD<Row> studentRowsRDD = studentsRDD.map(
            
            new Function<Tuple2<String,Tuple2<Integer,Integer>>, Row>() {

               private static final long serialVersionUID = 1L;

               @Override
               public Row call(
                     Tuple2<String, Tuple2<Integer, Integer>> tuple)
                     throws Exception {
                  return RowFactory.create(tuple._1, tuple._2._1, tuple._2._2);
               }
               
            });
      
      // 过滤出分数大于80分的数据
      JavaRDD<Row> filteredStudentRowsRDD = studentRowsRDD.filter(
            
            new Function<Row, Boolean>() {

               private static final long serialVersionUID = 1L;

               @Override
               public Boolean call(Row row) throws Exception {
                  if(row.getInt(2) > 80) {
                     return true;
                  } 
                  return false;
               }
               
            });
      
      // 转换为DataFrame
      List<StructField> structFields = new ArrayList<StructField>();
      structFields.add(DataTypes.createStructField("name", DataTypes.StringType, true));  
      structFields.add(DataTypes.createStructField("age", DataTypes.IntegerType, true)); 
      structFields.add(DataTypes.createStructField("score", DataTypes.IntegerType, true)); 
      StructType structType = DataTypes.createStructType(structFields);
      
      DataFrame studentsDF = sqlContext.createDataFrame(filteredStudentRowsRDD, structType);
      
      Row[] rows = studentsDF.collect();
      for(Row row : rows) {
         System.out.println(row);  
      }
      
      // 将DataFrame中的数据保存到mysql表中
      // 这种方式是在企业里很常用的,有可能是插入mysql、有可能是插入hbase,还有可能是插入redis缓存
      studentsDF.javaRDD().foreach(new VoidFunction<Row>() {
         
         private static final long serialVersionUID = 1L;

         @Override
         public void call(Row row) throws Exception {
            String sql = "insert into good_student_infos values(" 
                  + "'" + String.valueOf(row.getString(0)) + "',"
                  + Integer.valueOf(String.valueOf(row.get(1))) + ","
                  + Integer.valueOf(String.valueOf(row.get(2))) + ")";   
            
            Class.forName("com.mysql.jdbc.Driver");  
            
            Connection conn = null;
            Statement stmt = null;
            try {
               conn = DriverManager.getConnection(
                     "jdbc:mysql://spark1:3306/testdb", "", "");
               stmt = conn.createStatement();
               stmt.executeUpdate(sql);
            } catch (Exception e) {
               e.printStackTrace();
            } finally {
               if(stmt != null) {
                  stmt.close();
               } 
               if(conn != null) {
                  conn.close();
               }
            }
         }
         
      }); 
      
      sc.close();
   }
   
}

3 spark读取json格式数据

import java.util.ArrayList;
import java.util.List;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.RowFactory;
import org.apache.spark.sql.SQLContext;
import org.apache.spark.sql.types.DataTypes;
import org.apache.spark.sql.types.StructField;
import org.apache.spark.sql.types.StructType;

import scala.Tuple2;

/**
 * JSON数据源
 * @author Administrator
 *
 */
public class JSONDataSource {

   public static void main(String[] args) {
      SparkConf conf = new SparkConf()
            .setAppName("JSONDataSource");  
      JavaSparkContext sc = new JavaSparkContext(conf);
      SQLContext sqlContext = new SQLContext(sc);
      
      // 针对json文件,创建DataFrame(针对json文件创建DataFrame)
      DataFrame studentScoresDF = sqlContext.read().json(
            "hdfs://spark1:9000/spark-study/students.json");  
      
      // 针对学生成绩信息的DataFrame,注册临时表,查询分数大于80分的学生的姓名
      // (注册临时表,针对临时表执行sql语句)
      studentScoresDF.registerTempTable("student_scores");
      DataFrame goodStudentScoresDF = sqlContext.sql(
            "select name,score from student_scores where score>=80");
      
      // (将DataFrame转换为rdd,执行transformation操作)
      List<String> goodStudentNames = goodStudentScoresDF.javaRDD().map(
            
            new Function<Row, String>() {
               
               private static final long serialVersionUID = 1L;
      
               @Override
               public String call(Row row) throws Exception {
                  return row.getString(0);
               }
               
            }).collect();
      
      // 然后针对JavaRDD<String>,创建DataFrame
      // (针对包含json串的JavaRDD,创建DataFrame)
      List<String> studentInfoJSONs = new ArrayList<String>();
      studentInfoJSONs.add("{\"name\":\"Leo\", \"age\":18}");  
      studentInfoJSONs.add("{\"name\":\"Marry\", \"age\":17}");  
      studentInfoJSONs.add("{\"name\":\"Jack\", \"age\":19}");
      JavaRDD<String> studentInfoJSONsRDD = sc.parallelize(studentInfoJSONs);

      DataFrame studentInfosDF = sqlContext.read().json(studentInfoJSONsRDD);
      
      // 针对学生基本信息DataFrame,注册临时表,然后查询分数大于80分的学生的基本信息
      studentInfosDF.registerTempTable("student_infos");  
      
      String sql = "select name,age from student_infos where name in (";
      for(int i = 0; i < goodStudentNames.size(); i++) {
         sql += "'" + goodStudentNames.get(i) + "'";
         if(i < goodStudentNames.size() - 1) {
            sql += ",";
         }
      }
      sql += ")";
      
      DataFrame goodStudentInfosDF = sqlContext.sql(sql);
      
      // 然后将两份数据的DataFrame,转换为JavaPairRDD,执行join transformation
      // (将DataFrame转换为JavaRDD,再map为JavaPairRDD,然后进行join)
      JavaPairRDD<String, Tuple2<Integer, Integer>> goodStudentsRDD = 
            
            goodStudentScoresDF.javaRDD().mapToPair(new PairFunction<Row, String, Integer>() {

               private static final long serialVersionUID = 1L;
      
               @Override
               public Tuple2<String, Integer> call(Row row) throws Exception {
                  return new Tuple2<String, Integer>(row.getString(0), 
                        Integer.valueOf(String.valueOf(row.getLong(1))));  
               }
               
            }).join(goodStudentInfosDF.javaRDD().mapToPair(new PairFunction<Row, String, Integer>() {
      
               private static final long serialVersionUID = 1L;
      
               @Override
               public Tuple2<String, Integer> call(Row row) throws Exception {
                  return new Tuple2<String, Integer>(row.getString(0),
                        Integer.valueOf(String.valueOf(row.getLong(1))));   
               }
               
            }));
      
      // 然后将封装在RDD中的好学生的全部信息,转换为一个JavaRDD<Row>的格式
      // (将JavaRDD,转换为DataFrame)
      JavaRDD<Row> goodStudentRowsRDD = goodStudentsRDD.map(
            
            new Function<Tuple2<String,Tuple2<Integer,Integer>>, Row>() {

               private static final long serialVersionUID = 1L;

               @Override
               public Row call(
                     Tuple2<String, Tuple2<Integer, Integer>> tuple)
                     throws Exception {
                  return RowFactory.create(tuple._1, tuple._2._1, tuple._2._2);
               }
               
            });
      
      // 创建一份元数据,将JavaRDD<Row>转换为DataFrame
      List<StructField> structFields = new ArrayList<StructField>();
      structFields.add(DataTypes.createStructField("name", DataTypes.StringType, true)); 
      structFields.add(DataTypes.createStructField("score", DataTypes.IntegerType, true));  
      structFields.add(DataTypes.createStructField("age", DataTypes.IntegerType, true));  
      StructType structType = DataTypes.createStructType(structFields);
      
      DataFrame goodStudentsDF = sqlContext.createDataFrame(goodStudentRowsRDD, structType);
      
      // 将好学生的全部信息保存到一个json文件中去
      // (将DataFrame中的数据保存到外部的json文件中去)
      goodStudentsDF.write().format("json").save("hdfs://spark1:9000/spark-study/good-students");  
   }
   
}

4 spark读取parquet数据

import java.util.List;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SQLContext;

/**
 * Parquet数据源之使用编程方式加载数据
 * @author Administrator
 *
 */
public class ParquetLoadData {

   public static void main(String[] args) {
      SparkConf conf = new SparkConf()
            .setAppName("ParquetLoadData");  
      JavaSparkContext sc = new JavaSparkContext(conf);
      SQLContext sqlContext = new SQLContext(sc);
      
      // 读取Parquet文件中的数据,创建一个DataFrame
      DataFrame usersDF = sqlContext.read().parquet(
            "hdfs://spark1:9000/spark-study/users.parquet");
      
      // 将DataFrame注册为临时表,然后使用SQL查询需要的数据
      usersDF.registerTempTable("users");  
      DataFrame userNamesDF = sqlContext.sql("select name from users");  
      
      // 对查询出来的DataFrame进行transformation操作,处理数据,然后打印出来
      List<String> userNames = userNamesDF.javaRDD().map(new Function<Row, String>() {

         private static final long serialVersionUID = 1L;

         @Override
         public String call(Row row) throws Exception {
            return "Name: " + row.getString(0);
         }
         
      }).collect();
      
      for(String userName : userNames) {
         System.out.println(userName);  
      }
   }
   
}

各类接口测试实战合集

适用人群:适合有基础的童鞋,无基础的建议先看疯狂LoadRunner性能测试实战视频;友情提示,觉得自己是高手的请绕行! 课程特点:史上最热门课程,销售量持续走高!(包括但不限于下方内容) 1、接口介绍与文档规范 2、接口测试实战(HTTP、webservice等) 3、多种接口测试的方法与工具 QQ群288567073
  • 2015年08月26日 23:10

如何实现一个spark数据源

如何实现自己的spark数据源 简介 spark data source API是一套接口,让开发者可以通过实现这些接口,从而将存储在磁盘(或者hdfs whatever)上的各种格式的数据转化为...
  • tiandiwoxin92
  • tiandiwoxin92
  • 2016-04-07 00:13:00
  • 797

Spark从外部读取数据之textFile

textFile函数 /** * Read a text file from HDFS, a local file system (available on all nodes), or a...
  • legotime
  • legotime
  • 2016-07-11 06:13:46
  • 34249

sparksql各种数据源

sparksql各种数据源的测试: 大致的有json文件parquet文件,和常用的文件,jdbc等 还有hbase的数据源(还没有贴出,可能要等几天贴出来了) 代码:一般过程: 第一步创建:...
  • HANLIPENGHANLIPENG
  • HANLIPENGHANLIPENG
  • 2016-12-15 22:04:18
  • 2116

SparkStream文件监控和数据读取

代码 package main.scala import org.apache.spark.SparkConf import org.apache.spark.streaming.{Seconds...
  • silentwolfyh
  • silentwolfyh
  • 2016-05-24 12:53:49
  • 3191

Spark支持四种方式从数据库中读取数据

目前Spark支持四种方式从数据库中读取数据,这里以Mysql为例进行介绍。 文章目录 [hide] 1 一、不指定查询条件2 二、指定数据库字段的范围3 三、根据任意字段进行分区4 四、...
  • kc87654321
  • kc87654321
  • 2016-10-06 08:14:44
  • 1615

SparkStreaming之基本数据源输入

输入DStreams表示从数据源获取的原始数据流。Spark Streaming拥有两类数据源 (1)基本源(Basic sources):这些源在StreamingContext API中直接可用。...
  • legotime
  • legotime
  • 2016-07-06 07:45:47
  • 5086

spark使用文档

最近在看了一些spark的使用文档,以及官网简介,自己总结了一点使用文档,记录一下 快速启动spark 关于这一部分 Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎。S...
  • qq_30408111
  • qq_30408111
  • 2018-01-26 14:19:52
  • 1207

Spark 数据读取与保存

文件格式与文件系统 对于存储在本地文件系统或分布式文件系统(比如NFS、HDFS、Amazon S3 等)中的数据,Spark 可以访问很多种不同的文件格式,包括文本文件、JSON、Sequence...
  • carolzhang8406
  • carolzhang8406
  • 2017-09-15 16:02:27
  • 168

Spark读取数据库(Mysql)的四种方式讲解

Spark读取数据库(Mysql)的四种方式讲解
  • high2011
  • high2011
  • 2016-03-09 09:02:31
  • 2133
收藏助手
不良信息举报
您举报文章:spark 读取各类数据源
举报原因:
原因补充:

(最多只允许输入30个字)