Spark RDD 练习

 1、创建一个1-10数组的RDD,将所有元素*2形成新的RDD

scala> val rdd1 = sc.parallelize(1 to 10)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[2] at parallelize at <console>:24

scala> val rdd2 = rdd1.map(_ * 2)
rdd2: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[3] at map at <console>:26

scala> rdd2.collect
res1: Array[Int] = Array(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)


val rdd1 = sc.parallelize(1 to 10)
val  rdd2 = rdd1.map(_*2)
rdd2 .collect  

2、创建一个10-20数组的RDD,使用mapPartitions将所有元素*2形成新的RDD


val rdd1 =sc.makeRDD  (10 to 20 )
cal rdd2 = rdd1.mapPartitions(_.map(_*2)

3、创建一个元素为 1-5 的RDD,运用 flatMap创建一个新的 RDD,新的 RDD 为原 RDD 每个元素的 平方和三次方 来组成 1,1,4,8,9,27..


scala> val rdd1 = sc.parallelize(Array(1,2,3,4,5))
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[8] at parallelize at <console>:24

scala>  rdd1.flatMap(x => Array(x * x, x * x * x))
res7: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[9] at flatMap at <console>:27

scala> res7.collect
res8: Array[Int] = Array(1, 1, 4, 8, 9, 27, 16, 64, 25, 125)

4、创建一个 4 个分区的 RDD数据为Array(10,20,30,40,50,60),使用glom将每个分区的数据放到一个数组


scala> var rdd1 = sc.parallelize(Array(10,20,30,40,50,60), 4)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[10] at parallelize at <console>:24

scala> rdd1.glom.collect
res9: Array[Array[Int]] = Array(Array(10), Array(20, 30), Array(40), Array(50, 60))

5、创建一个 RDD数据为Array(1, 3, 4, 20, 4, 5, 8),按照元素的奇偶性进行分组


scala> val rdd1 = sc.makeRDD(Array(1, 3, 4, 20, 4, 5, 8))
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[12] at makeRDD at <console>:24

scala> rdd1.groupBy(x =>if(x % 2 == 1) "odd"else"even")
res10: org.apache.spark.rdd.RDD[(String, Iterable[Int])] = ShuffledRDD[14] at groupBy at <console>:27

scala> res10.collect
res11: Array[(String, Iterable[Int])] = Array((even,CompactBuffer(4, 20, 4, 8)), (odd,CompactBuffer(1, 3, 5)))

6、创建一个 RDD(由字符串组成)Array("xiaoli", "laoli", "laowang", "xiaocang", "xiaojing", "xiaokong"),过滤出一个新 RDD(包含“xiao”子串)


scala> val names = sc.parallelize(Array("xiaoli", "laoli", "laowang", "xiaocang", "xiaojing", "xiaokong"))
names: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[15] at parallelize at <console>:24

scala> names.filter(_.contains("xiao"))
res12: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[16] at filter at <console>:27

scala> res12.collect
res13: Array[String] = Array(xiaoli, xiaocang, xiaojing, xiaokong)

7、创建一个 RDD数据为1 to 10,请使用sample不放回抽样


scala> val rdd1 = sc.parallelize(1 to 10)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[17] at parallelize at <console>:24

scala> rdd1.sample(false, 0.5).collect
res14: Array[Int] = Array(1, 2, 5, 6)

8、创建一个 RDD数据为1 to 10,请使用sample放回抽样


scala> rdd1.sample(true, 2).collect
res15: Array[Int] = Array(1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10)

9、创建一个 RDD数据为Array(10,10,2,5,3,5,3,6,9,1),对 RDD 中元素执行去重操作


scala> val rdd1 = sc.parallelize(Array(10,10,2,5,3,5,3,6,9,1))
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[20] at parallelize at <console>:24

scala> rdd1.distinct().collect
res16: Array[Int] = Array(1, 9, 5, 6, 10, 2, 3)

10、创建一个分区数为5的 RDD,数据为0 to 100,之后使用coalesce再重新减少分区的数量至 2



scala> val rdd1 = sc.parallelize(0 to 100, 5)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[0] at parallelize at <console>:24

scala> rdd1.partitions.length
res0: Int = 5

scala> rdd1.coalesce(2) // 减少分区的数量为2
res1: org.apache.spark.rdd.RDD[Int] = CoalescedRDD[1] at coalesce at <console>:27

scala> res1.partitions.length
res2: Int = 2

11、创建一个分区数为5的 RDD,数据为0 to 100,之后使用repartition再重新减少分区的数量至 3

repartition(numPartitions)

作用: 根据新的分区数, 重新 shuffle 所有的数据, 这个操作总会通过网络.新的分区数相比以前可以多, 也可以少

scala> val rdd1 = sc.parallelize(0 to 100, 5)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[2] at parallelize at <console>:24

scala> rdd1.repartition(3)
res3: org.apache.spark.rdd.RDD[Int] = MapPartitionsRDD[6] at repartition at <console>:27

scala> res3.partitions.length
res5: Int = 3

12、创建一个 RDD数据为1,3,4,10,4,6,9,20,30,16,请给RDD进行分别进行升序和降序排列


sortBy(func,[ascending], [numTasks])
作用: 使用func先对数据进行处理,按照处理后结果排序,默认为正序。

scala> val rdd1 = sc.parallelize(Array(1,3,4,10,4,6,9,20,30,16))
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[11] at parallelize at <console>:24

scala> rdd1.sortBy(x => x).collect
res8: Array[Int] = Array(1, 3, 4, 4, 6, 9, 10, 16, 20, 30)

scala> rdd1.sortBy(x => x, true).collect // 升序输出
res9: Array[Int] = Array(1, 3, 4, 4, 6, 9, 10, 16, 20, 30)

scala> rdd1.sortBy(x => x, false).collect // 降序输出
res10: Array[Int] = Array(30, 20, 16, 10, 9, 6, 4, 4, 3, 1)  

13、创建两个RDD,分别为rdd1和rdd2数据分别为1 to 6和4 to 10,求并集


union(otherDataset)

作用:求并集. 对源 RDD 和参数 RDD 求并集后返回一个新的 RDD

scala> val rdd1 = sc.parallelize(1 to 6)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[7] at parallelize at <console>:24

scala> val rdd2 = sc.parallelize(4 to 10)
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[8] at parallelize at <console>:24

scala> rdd1.union(rdd2)
res4: org.apache.spark.rdd.RDD[Int] = UnionRDD[9] at union at <console>:29

scala> res4.collect
res5: Array[Int] = Array(1, 2, 3, 4, 5, 6, 4, 5, 6, 7, 8, 9, 10)

14、创建两个RDD,分别为rdd1和rdd2数据分别为1 to 6和4 to 10,计算差集,两个都算


subtract (otherDataset) 作用: 计算差集. 从原 RDD 中减去 原 RDD 和 otherDataset 中的共同的部分


scala> val rdd1 = sc.parallelize(1 to 6)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[7] at parallelize at <console>:24

scala> val rdd2 = sc.parallelize(4 to 10)
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[8] at parallelize at <console>:24

scala> rdd1.subtract(rdd2).collect
res0: Array[Int] = Array(2, 1, 3)

scala> rdd2.subtract(rdd1).collect
res7: Array[Int] = Array(8, 9, 10, 7)

15、创建两个RDD,分别为rdd1和rdd2数据分别为1 to 6和4 to 10,计算交集


intersection(otherDataset)

作用: 计算交集. 对源 RDD 和参数 RDD 求交集后返回一个新的 RDD



scala> val rdd1 = sc.parallelize(1 to 6)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[7] at parallelize at <console>:24

scala> val rdd2 = sc.parallelize(4 to 10)
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[8] at parallelize at <console>:24

scala> rdd1.intersection(rdd2).collect
res2: Array[Int] = Array(4, 5, 6) 

16、创建两个RDD,分别为rdd1和rdd2数据分别为1 to 6和4 to 10,计算 2 个 RDD 的笛卡尔积


cartesian(otherDataset)

作用: 计算 2 个 RDD 的笛卡尔积. 尽量避免使用


scala> val rdd1 = sc.parallelize(1 to 6)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[7] at parallelize at <console>:24

scala> val rdd2 = sc.parallelize(4 to 10)
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[8] at parallelize at <console>:24

scala> val rdd3 = rdd1.cartesian(rdd2)
rdd3: org.apache.spark.rdd.RDD[(Int, Int)] = CartesianRDD[10] at cartesian at <console>:28

scala> rdd3.collect
res2: Array[(Int, Int)] = Array((1,4), (1,5), (1,6), (2,4), (2,5), (2,6), (3,4), (3,5), (3,6), (1,7), (1,8), (1,9), (1,10), (2,7), (2,8), (2,9), (2,10), (3,7), (3,8), (3,9), (3,10), (4,4), (4,5), (4,6), (5,4), (5,5), (5,6), (6,4), (6,5), (6,6), (4,7), (4,8), (4,9), (4,10), (5,7), (5,8), (5,9), (5,10), (6,7), (6,8), (6,9), (6,10))

17、创建两个RDD,分别为rdd1和rdd2数据分别为1 to 5和11 to 15,对两个RDD拉链操作

zip(otherDataset)

作用: 拉链操作. 需要注意的是, 在 Spark 中, 两个 RDD 的元素的数量和分区数都必须相同, 否则会抛出异常.(在 scala
中, 两个集合的长度可以不同)。本质就是要求的每个分区的元素的数量相同。

scala> val rdd1 = sc.parallelize(1 to 5)
rdd1: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[8] at parallelize at <console>:24

scala> val rdd2 = sc.parallelize(11 to 15)
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[9] at parallelize at <console>:24

scala> rdd1.zip(rdd2).collect
res3: Array[(Int, Int)] = Array((1,11), (2,12), (3,13), (4,14), (5,15))

18、创建一个RDD数据为List(("female",1),("male",5),("female",5),("male",2)),请计算出female和male的总数分别为多少


reduceByKey(func, [numTasks])

作用: 在一个(K,V)的 RDD 上调用,返回一个(K,V)的
RDD,使用指定的reduce函数,将相同key的value聚合到一起,reduce任务的个数可以通过第二个可选的参数来设置。


scala> val rdd1 = sc.parallelize(List(("female",1),("male",5),("female",5),("male",2)))
rdd1: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[13] at parallelize at <console>:24

scala>  rdd1.reduceByKey(_ + _)
res6: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[14] at reduceByKey at <console>:27

scala> res6.collect
res8: Array[(String, Int)] = Array((female,6), (male,7))

19、创建一个有两个分区的 RDD数据为List(("a",3),("a",2),("c",4),("b",3),("c",6),("c",8)),取出每个分区相同key对应值的最大值,然后相加


aggregateByKey(zeroValue)(seqOp, combOp, [numTasks])

使用给定的 combine 函数和一个初始化的zero value, 对每个key的value进行聚合. 这个函数返回的类型U不同于源
RDD 中的V类型. U的类型是由初始化的zero value来定的. 所以, 我们需要两个操作: - 一个操作(seqOp)去把 1
个v变成 1 个U - 另外一个操作(combOp)来合并 2 个U 第一个操作用于在一个分区进行合并, 第二个操作用在两个分区间进行合并.
为了避免内存分配, 这两个操作函数都允许返回第一个参数, 而不用创建一个新的U 参数描述:

zeroValue:给每一个分区中的每一个key一个初始值;
seqOp:函数用于在每一个分区中用初始值逐步迭代value;
combOp:函数用于合并每个分区中的结果。


scala> val rdd = sc.parallelize(List(("a",3),("a",2),("c",4),("b",3),("c",6),("c",8)),2)
rdd: org.apache.spark.rdd.RDD[(String, Int)] = ParallelCollectionRDD[0] at parallelize at <console>:24

scala> rdd.aggregateByKey(Int.MinValue)(math.max(_, _), _ +_)
res0: org.apache.spark.rdd.RDD[(String, Int)] = ShuffledRDD[1] at aggregateByKey at <console>:27

scala> res0.collect
res1: Array[(String, Int)] = Array((b,3), (a,3), (c,12))    

20、 创建一个有两个分区的 pairRDD数据为Array(("a", 88), ("b", 95), ("a", 91), ("b", 93), ("a", 95), ("b", 98)),根据 key 计算每种 key 的value的平均值


combineByKey
   

解 : 
遍历过程中,统计a和b的个数,同时计算总和。

scala> val score2=rdd.combineByKey(x =>(1,x) ,
     | (c1:(Int,Int),newScore)=>(c1._1+1,c1._2+newScore),
     | (c1:(Int,Int),c2:(Int,Int))=>(c1._1+c2._1,c1._2+c2._2))]
	 
score2: org.apache.spark.rdd.RDD[(String, (Int, Int))] = ShuffledRDD[31] at combineByKey at <console>:26


得到编号ab:个数+总和
scala> score2.foreach(println)
(b,(3,286))
(a,(3,274))

// 求平均值
scala>                                    val average=score2.map{case(name, (num,score) )=>(name,score/num) }


average: org.apache.spark.rdd.RDD[(String, Int)] = MapPartitionsRDD[32] at map at <console>:28

//  结果 
scala> average.foreach(println)
(b,95)
(a,91)

21、统计出每一个省份广告被点击次数的 TOP3,数据在access.log文件中

数据结构:时间戳,省份,城市,用户,广告 字段使用空格分割。

样本如下:

1516609143867 6 7 64 16

1516609143869 9 4 75 18

1516609143869 1 7 87 12

RDD编程

package Province
 
import org.apache.spark.{SparkConf, SparkContext}
 
/** 统计出每一个省份广告被点击次数的TOP3
  * 数据结构:时间戳,省份,城市,用户,广告,中间字段使用空格分割。
  * 日志样例:
  * 1516609143867 6 7 64 16
  * 1516609143869 9 4 75 18
  * 1516609143869 1 7 87 12
  *
  */
  
object Province {
 
  def main(args: Array[String]): Unit = {
 
    //1.初始化spark配置信息并建立与spark的连接
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("ProvinceOfAdvertising")
    val sc = new SparkContext(sparkConf)
 
    //2.读取数据生成RDD:TS,Province,City,User,AD
    val line = sc.textFile("Spark\\src\\main\\scala\\access.log")
 
    //3.按照最小粒度聚合:((Province,AD),1)
    val provinceAdToOne = line.map { x =>
      val fields: Array[String] = x.split(" ")
      ((fields(1), fields(4)), 1)
    }
 
    //4.计算每个省中每个广告被点击的总数:((Province,AD),sum)
    val provinceAdToSum = provinceAdToOne.reduceByKey(_ + _)
 
    //5.将省份作为key,广告加点击数为value:(Province,(AD,sum))
    val provinceToAdSum = provinceAdToSum.map(x => (x._1._1, (x._1._2, x._2)))
 
    //6.将同一个省份的所有广告进行聚合(Province,List((AD1,sum1),(AD2,sum2)...))
    val provinceGroup = provinceToAdSum.groupByKey()
 
    //7.对同一个省份所有广告的集合进行排序并取前3条,排序规则为广告点击总数.
    val provinceAdTop3 = provinceGroup.mapValues { x =>
      x.toList.sortWith((x, y) => x._2 > y._2).take(3)
    }
 
    //8.将数据拉取到Driver端并打印
    provinceAdTop3.collect().foreach(println)
 
    //9.关闭与spark的连接
    sc.stop()
  }
 
}

22、读取本地文件words.txt,统计出每个单词的个数,保存数据到 hdfs 上


import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}

object WordCount {
  def main(args: Array[String]): Unit = {
    val master: SparkConf = new SparkConf().setAppName("WrodCount").setMaster("local[2]")

    val sc: SparkContext = new SparkContext(master)
    //读取文件
    val file: RDD[String] = sc.textFile("E:\\2020-传智资料1\\第二学期Spark\\day01_Spark\\练习题\\words.txt")

    //对文件中每一行单词进行压平切分
    val words: RDD[String] = file.flatMap(_.split(" "))
    //对每一个单词计数为1 转化为(单词,1)
    val wordAndOne: RDD[(String, Int)] = words.map(x=>(x,1))
    //相同的单词进行汇总 前一个下划线表示累加数据,后一个下划线表示新数据
    val result: RDD[(String, Int)] = wordAndOne.reduceByKey(_+_)
    //val finalResult: Array[(String, Int)] = result.collect()
   // finalResult.foreach(println)

    //保存数据到HDFS
    result.saveAsTextFile(args(1))
    sc.stop()
  }

}

23、读取 people.json 数据的文件, 每行是一个 json 对象,进行解析输出



import org.apache.spark._
import scala.util.parsing.json.JSON
object JSONApp {
    def main(args:Array[String]): Unit ={
        //初始化配置:设置主机名和程序主类的名字
        val conf = new SparkConf().setMaster("local").setAppName("JSONApp");
        //通过conf来创建sparkcontext
        val sc = new SparkContext(conf);
 
        val inputFile = "file:///usr/local/spark/people.json"//读取json文件
        val jsonStr = sc.textFile(inputFile);
        val result = jsonStr.map(s => JSON.parseFull(s));//逐个JSON字符串解析
        result.foreach(
            {
                r => r match {
                case Some(map:Map[String,Any]) => println(map)
                case None => println("parsing failed!")
                case other => println("unknown data structure" + other)
                }
            }
        );
    }
}

24、保存一个 SequenceFile 文件,使用spark创建一个RDD数据为Array(("a", 1),("b", 2),("c", 3)),保存为SequenceFile格式的文件到hdfs上


val ArrayList = Array(("a", 1),("b", 2),("c", 3))
val r = sc.makeRDD(ArrayList, 1)
r.saveAsObjectFile("hdfs:/your/path/ArrayList")
 
val file = sc.sequenceFile[Null,org.apache.hadoop.io.BytesWritable]("hdfs:/path/ArrayList/part-00000")
val bw = file.take(1).apply(0)._2
val bs = bw.getBytes

25、读取24题的SequenceFile 文件并输出


import java.io._
val bis = new ByteArrayInputStream(bs)
val ois = new ObjectInputStream(bis)
ois.readObject

26、读写 objectFile 文件把 RDD 保存为objectFile,RDD数据为Array(("a", 1),("b", 2),("c", 3)),并进行读取出来


 val data26_1 = sc.makeRDD(Array(("a", 1), ("b", 2), ("c", 3)))
 data26_1.saveAsObjectFile("src\\input\\objectFile")
 val data26_2 = sc.textFile(src\\input\\objectFile")

27、使用内置累加器计算Accumulator.txt文件中空行的数量


 val data27 = sc.textFile("input/Accumulator.txt")
 var count = sc.longAccumulator("count")
 data27.foreach { x => if (x == "") count.add(1) }
 println(count.value)


28、使用Spark广播变量

用户表:

id name age gender(0|1)

001,刘向前,18,0

002,冯  剑,28,1

003,李志杰,38,0

004,郭  鹏,48,2

要求,输出用户信息,gender必须为男或者女,不能为0,1

使用广播变量把Map("0" -> "女", "1" -> "男")设置为广播变量,最终输出格式为

001,刘向前,18,女

003,李志杰,38,女

002,冯  剑,28,男

004,郭  鹏,48,男

val data = sc.textFile("input/user.txt")
 val sex = sc.broadcast(Map("0" -> "女", "1" -> "男"))
 data.foreach { x => var datas = x.split(","); println(datas(0) + "," + datas(1) + "," + datas(2) + "," + sex.value(datas(3))) }

29、mysql创建一个数据库bigdata0407,在此数据库中创建一张表

CREATE TABLE `user` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `username` varchar(32) NOT NULL COMMENT '用户名称',

  `birthday` date DEFAULT NULL COMMENT '生日',

  `sex` char(1) DEFAULT NULL COMMENT '性别',

  `address` varchar(256) DEFAULT NULL COMMENT '地址',

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

数据如下:

依次是:姓名 生日 性别 省份

安荷 1998/2/7 女 江苏省

白秋 2000/3/7 女 天津市

雪莲 1998/6/7 女 湖北省

宾白 1999/7/3 男 河北省

宾实 2000/8/7 男 河北省

斌斌 1998/3/7 男 江苏省

请使用spark将以上数据写入mysql中,并读取出来。


 val data29 = sc.textFile("input20200407/users.txt")
 val driver = "com.mysql.jdbc.Driver"
 val url = "jdbc:mysql://localhost:3306/bigdata01"
 val username = "root"
 val password = "root"




  /*
    CREATE TABLE `t_student` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
    `age` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
 */

/**
 * MySQL插入数据
 */
 data29.foreachPartition {
   data =>
     Class.forName(driver)
     val connection = java.sql.DriverManager.getConnection(url, username, password)
     val sql = "INSERT INTO `user` values (NULL,?,?,?,?)"
     data.foreach {
       tuples => {
         val datas = tuples.split(" ")
         val statement = connection.prepareStatement(sql)
         statement.setString(1, datas(0))
         statement.setString(2, datas(1))
         statement.setString(3, datas(2))
         statement.setString(4, datas(3))
         statement.executeUpdate()
         statement.close()
       }
     }
     connection.close()
 }
/**
 * MySQL查询数据
  */
 var sql = "select * from `user` where id between ? and ?"
 val jdbcRDD = new JdbcRDD(sc,
   () => {
     Class.forName(driver)
     java.sql.DriverManager.getConnection(url, username, password)
   },
   sql,
   0,
   44,
   3,
   result => {
     println(s"id=${result.getInt(1)},username=${result.getString(2)}" +
       s",birthday=${result.getDate(3)},sex=${result.getString(4)},address=${result.getString(5)}")
   }
 )
 jdbcRDD.collect() 


30、在hbase中创建一个表student,有一个 message列族

create 'student', 'message'

scan 'student', {COLUMNS => 'message'}

给出以下数据,请使用spark将数据写入到hbase中的student表中,并进行查询出来

数据如下:

依次是:姓名 班级 性别 省份,对应表中的字段依次是:name,class,sex,province

飞松 3 女 山东省

刚洁 1 男 深圳市

格格 4 女 四川省

谷菱 5 女 河北省

国立 2 男 四川省

海涛 3 男 广东省

含芙 3 女 四川省

华敏 4 女 上海市

乐和 2 男 上海市

乐家 3 男 黑龙江

乐康 4 男 湖北省

乐人 5 男 四川省

乐水 3 男 北京市

乐天 4 男 河北省

乐童 5 男 江苏省

乐贤 1 男 陕西省

乐音 2 男 广东省

李仁 3 男 湖北省

立涛 3 女 陕西省

凌青 4 女 湖北省

陆涛 4 男 山东省

媚媚 5 女 河南省

梦亿 4 男 江苏省

铭忠 5 男 四川省

慕梅 3 女 北京市

鹏吉 1 男 上海市

娉婷 4 女 河南省

淇峰 2 男 广东省

庆元 3 男 上海市

庆滋 4 男 北京市

丘东 5 男 江苏省

荣郑 1 男 黑龙江

蕊蕊 5 女 四川省

尚凯 2 男 北京市

诗涵 1 女 河南省

淑凤 2 女 天津市

淑娇 3 女 上海市

淑燕 4 女 河北省

淑怡 4 女 广东省

思璇 2 女 湖北省

苏华 3 女 山东省

苏梅 4 女 四川省

听荷 5 女 深圳市

文怡 1 女 天津市

文怡 2 女 河北省

香凝 3 女 山东省

翔云 4 女 河南省

小芸 5 女 深圳市


 /**
  * 
  * create 'student', 'message'
  * scan 'student', {COLUMNS => 'message'}
  * 给出以下数据,请使用spark将数据写入到hbase中的student表中,并进行查询出来
  * 数据如下:
  * 依次是:姓名 班级 性别 省份,对应表中的字段依次是:name,class,sex,province
  */
 //org.apache.hadoop.hbase.mapreduce.TableInputFormat
 val conf = HBaseConfiguration.create()
 conf.set("hbase.zookeeper.quorum", "node01:2181,node02:2181,node03:2181")	
 conf.set(TableInputFormat.INPUT_TABLE, "student")
 /**
  * HBase插入数据
  */
 val dataRDD: RDD[String] = sc.textFile("input20200407/student.txt")
 val putRDD: RDD[(ImmutableBytesWritable, Put)] = dataRDD.map {
  // 刚洁	1	男	深圳市
   case line => {
     val datas = line.split("\t")
     val rowkey = Bytes.toBytes(datas(0))
     val put = new Put(rowkey)
     put.addColumn(Bytes.toBytes("message"), Bytes.toBytes("name"), Bytes.toBytes(datas(0)))
     put.addColumn(Bytes.toBytes("message"), Bytes.toBytes("class"), Bytes.toBytes(datas(1)))
     put.addColumn(Bytes.toBytes("message"), Bytes.toBytes("sex"), Bytes.toBytes(datas(2)))
     put.addColumn(Bytes.toBytes("message"), Bytes.toBytes("province"), Bytes.toBytes(datas(3)))
     (new ImmutableBytesWritable(rowkey), put)
   }
 }
 val jobConf = new JobConf(conf)
 //org.apache.hadoop.hbase.mapred.TableOutputFormat
 jobConf.setOutputFormat(classOf[TableOutputFormat])
 jobConf.set(TableOutputFormat.OUTPUT_TABLE, "student")
 putRDD.saveAsHadoopDataset(jobConf)


 /**
  * HBase查询数据
  */
 val hbaseRDD: RDD[(ImmutableBytesWritable, Result)] = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat],
   classOf[ImmutableBytesWritable],
   classOf[Result])
 hbaseRDD.foreach {
   case (rowKey, result) => {
     val cells: Array[Cell] = result.rawCells()
     for (cell <- cells) {
       println(Bytes.toString(CellUtil.cloneRow(cell)) + "\t" +
         Bytes.toString(CellUtil.cloneFamily(cell)) + "\t" +
         Bytes.toString(CellUtil.cloneQualifier(cell)) + "\t" +
         Bytes.toString(CellUtil.cloneValue(cell))
       )
     }
   }
 }

                                           TobeContinue

发布了253 篇原创文章 · 获赞 362 · 访问量 33万+

猜你喜欢

转载自blog.csdn.net/bbvjx1314/article/details/105497527