一、文件数据读写

1.本地文件系统的数据读写

可以采用多种方式创建Pair RDD,其中一种主要方式是使用map()函数来实现

惰性机制,即使输入了错误的语句spark-shell也不会马上报错。

(1)读

给出路径名称,TextFile会把路径下面的所有文件都读进来,生成一个RDD5.3 RDD编程---数据读写_数据 

(2)写

5.3 RDD编程---数据读写_apache_02

当只有一个分区时,单线程才会出现part-0000

如果分了两个分区,写完之后会生成part-0000和part-0001

2.分布式文件系统HDFS的数据读写

(1)读

5.3 RDD编程---数据读写_json_035.3 RDD编程---数据读写_json_04

(2)写

5.3 RDD编程---数据读写_apache_05

3.JSON文件的数据读写

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式

(1)读

5.3 RDD编程---数据读写_json_06

Scala中有一个自带的JSON库——scala.util.parsing.json.JSON,可以实现对JSON数据的解析

JSON.parseFull(jsonString:String)函数,以一个JSON字符串作为输入并进行解析,如果解析成功则返回一个Some(map: Map[String, Any]),如果解析失败则返回None。5.3 RDD编程---数据读写_spark_07

5.3 RDD编程---数据读写_spark_085.3 RDD编程---数据读写_spark_09

将整个应用程序打包成 JAR包,通过 spark-submit 运行程序

5.3 RDD编程---数据读写_spark_10

 执行后可以在屏幕上的大量输出信息中找到如下结果:

5.3 RDD编程---数据读写_数据_11

二、读写HBase数据

1.HBase简介

HBase是Google BigTable的开源实现

5.3 RDD编程---数据读写_spark_125.3 RDD编程---数据读写_spark_13

  1. HBase是一个稀疏、多维度、排序的映射表,这张表的索引是行键、列族、列限定符和时间戳;
  2. 每个值是一个未经解释的字符串,没有数据类型;
  3. 用户在表中存储数据,每一行都有一个可排序的行键和任意多的列;
  4. 表在水平方向由一个或者多个列族组成,一个列族中可以包含任意多个列,同一个列族里面的数据存储在一起;
  5. 列族支持动态扩展,可以很轻松地添加一个列族或列,无需预先定义列的数量以及类型,所有列均以字符串形式存储,用户需要自行进行数据类型转换;
  6. HBase中执行更新操作时,并不会删除数据旧的版本,而是生成一个新的版本,旧有的版本仍然保留(这是和HDFS只允许追加不允许修改的特性相关的)

5.3 RDD编程---数据读写_apache_14

  1. 表:HBase采用表来组织数据,表由行和列组成,列划分为若干个列族
  2. 行:每个HBase表都由若干行组成,每个行由行键(row key)来标识。
  3. 列族:一个HBase表被分组成许多“列族”(Column Family)的集合,它是基本的访问控制单元
  4. 列限定符:列族里的数据通过列限定符(或列)来定位
  5. 单元格:在HBase表中,通过行、列族和列限定符确定一个“单元格”(cell),单元格中存储的数据没有数据类型,总被视为字节数组byte[]
  6. 时间戳:每个单元格都保存着同一份数据的多个版本,这些版本采用时间戳进行索引

5.3 RDD编程---数据读写_spark_15

5.3 RDD编程---数据读写_hadoop_16

 5.3 RDD编程---数据读写_spark_17

5.3 RDD编程---数据读写_数据_18

先切水平(学号1-10000,10001-20000,...),再切竖直(按列族分),每一种颜色得到小方格内都是一个分区,一个分区就是属于负载分发的基本单位,这样就可以实现分布式存储。有个元数据表可以存储每个分区对应的位置。

2.创建一个HBase表

第一步:安装配置HBase,将HBase安装成伪分布式

5.3 RDD编程---数据读写_hadoop_19

第二步:启动Hadoop和HBase

5.3 RDD编程---数据读写_数据_20

5.3 RDD编程---数据读写_json_21

HBase也有shell环境,可以输入类似SQL的语句

5.3 RDD编程---数据读写_json_225.3 RDD编程---数据读写_hadoop_235.3 RDD编程---数据读写_hadoop_245.3 RDD编程---数据读写_spark_25

3.配置Spark

把HBase的lib目录下的一些jar文件拷贝到Spark中,这些都是编程时需要引入的jar包,需要拷贝的jar文件包括:所有hbase开头的jar文件、guava-12.0.1.jar、htrace-core-3.1.0-incubating.jar和protobuf-java-2.5.0.jar

5.3 RDD编程---数据读写_数据_26

4.编写程序读取HBase数据

如果要让Spark读取HBase,就需要使用SparkContext提供的newAPIHadoopRDD这个API将表的内容以RDD的形式加载到Spark中。

5.3 RDD编程---数据读写_数据_275.3 RDD编程---数据读写_apache_28

import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.hbase._
import org.apache.hadoop.hbase.client._
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.hadoop.hbase.util.Bytes
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf

// 在SparkOperateHBase.scala文件中输入以下代码:

object SparkOperateHBase {
def main(args: Array[String]) {
    val conf = HBaseConfiguration.create()
    val sc = new SparkContext(new SparkConf())
    //设置查询的表名
    conf.set(TableInputFormat.INPUT_TABLE, "student")
    val stuRDD = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat],
  classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable],
  classOf[org.apache.hadoop.hbase.client.Result])
    val count = stuRDD.count()
    println("Students RDD Count:" + count)
    stuRDD.cache()
    //遍历输出
    stuRDD.foreach({ case (_,result) =>
        val key = Bytes.toString(result.getRow)
        val name = Bytes.toString(result.getValue("info".getBytes,"name".getBytes))
        val gender = Bytes.toString(result.getValue("info".getBytes,"gender".getBytes))
        val age = Bytes.toString(result.getValue("info".getBytes,"age".getBytes))
        println("Row key:"+key+" Name:"+name+" Gender:"+gender+" Age:"+age)
    })
}
}

5.3 RDD编程---数据读写_数据_295.3 RDD编程---数据读写_spark_305.3 RDD编程---数据读写_hadoop_31 

5.编写程序向HBase写入数据

下面编写应用程序把表中的两个学生信息插入到HBase的student表中5.3 RDD编程---数据读写_spark_32

在SparkWriteHBase.scala文件中输入下面代码:

import org.apache.hadoop.hbase.HBaseConfiguration  
import org.apache.hadoop.hbase.mapreduce.TableOutputFormat  
import org.apache.spark._  
import org.apache.hadoop.mapreduce.Job  
import org.apache.hadoop.hbase.io.ImmutableBytesWritable  
import org.apache.hadoop.hbase.client.Result  
import org.apache.hadoop.hbase.client.Put  
import org.apache.hadoop.hbase.util.Bytes

object SparkWriteHBase {  
  def main(args: Array[String]): Unit = {  
    val sparkConf = new SparkConf().setAppName("SparkWriteHBase").setMaster("local")  
    val sc = new SparkContext(sparkConf)        
    val tablename = "student"        
    sc.hadoopConfiguration.set(TableOutputFormat.OUTPUT_TABLE, tablename)  
    val job = new Job(sc.hadoopConfiguration)  
    job.setOutputKeyClass(classOf[ImmutableBytesWritable])  
    job.setOutputValueClass(classOf[Result])    
    job.setOutputFormatClass(classOf[TableOutputFormat[ImmutableBytesWritable]])    
    val indataRDD = sc.makeRDD(Array("3,Rongcheng,M,26","4,Guanhua,M,27")) //构建两行记录
    val rdd = indataRDD.map(_.split(',')).map{arr=>{  
      val put = new Put(Bytes.toBytes(arr(0))) //行健的值 
      put.add(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes(arr(1)))  //info:name列的值
      put.add(Bytes.toBytes("info"),Bytes.toBytes("gender"),Bytes.toBytes(arr(2)))  //info:gender列的值
      put.add(Bytes.toBytes("info"),Bytes.toBytes("age"),Bytes.toBytes(arr(3).toInt))  //info:age列的值
      (new ImmutableBytesWritable, put)   
    }}        
    rdd.saveAsNewAPIHadoopDataset(job.getConfiguration())  
  }    
} 

5.3 RDD编程---数据读写_数据_335.3 RDD编程---数据读写_json_34

切换到HBase Shell中,执行如下命令查看student表 

5.3 RDD编程---数据读写_spark_355.3 RDD编程---数据读写_hadoop_36