数据持久化,即将spark streaming 生成的数据进行保存以便未来进行数据的复现和查询,目前数据持久化的方案主要有:Hbase、HDFS、MySql、Dataworks四种,这四种方案各有千秋,下面详细说明这四种方案:
5.1 数据持久化方案简介
HBase:全称: Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群 ,可以提供快速随机访问海量结构化数据。它利用了Hadoop的文件系统(HDFS)提供的容错能力。
HDFS:全称:Hadoop Distributed File System,是一个高度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实现流式读取文件系统数据的目的。
上图对比,可明显看出HBase对比HDFS在大数据面前有明显的,可以快速访问大量数据,但是在针对目前spark streaming数据持久化的需求方面,HDFS更适合目前的业务场景,首先数据量较少,在少量数据面前HDFS的易用性和可操作性更具备吸引力。
Dataworks是目前公司进行大数据计算的主要依赖平台,且由阿里巴巴开发,其安全性、可靠性、可操作性都是不言而喻的。
MySql是目前公司数据存储的主要途径,也是经过历史考验的方案,无需赘述。
综上所述,目前数据量不大的情况下,Hbase进行数据持久化存在资源浪费(服务器、运维等),采用其它方案完全可以满足目前的业务需求,所以此方案暂不实现;HDFS数据在spark平台上,这样的好处是在未来进行数据复现时,可以快速访问;
MySql是目前主要的数据存储平台,数据存放MySql,方便未来的数据管理;dataworks是目前数据开发的主要平台之一,方便未来进行数据开发。
5.2 数据持久化demo之HDFS
HDFS实际上就是将数据存放至本地,简单易于操作,相关demo:
import org.apache.spark.streaming.{Milliseconds, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext}
object testspark{
def main(args: Array[String]): Unit = {
//离线任务是创建SparkContext;实现实时计算,用StreamingContext
val conf = new SparkConf().setAppName("testspark").setMaster(master = "yarn-client")
val sc = new SparkContext(conf)
//StreamingContext是对SparkContext的包装,包了一层就增加了实时的功能
//第二个参数是小批次产生的时间间隔
val ssc = new StreamingContext(sc, Milliseconds(5000))
val lines = ssc.textFileStream(args(0))
val words = lines.flatMap(_.split(","))
val con=words.map(x => (x, 1)).reduceByKey(_ + _)
con.saveAsTextFiles(hdfs://localhost:8020/user/****/*****)//指定计算结果的存储路径,可直接用args替代
//启动sparksteaming程序
ssc.start()
//等待优雅的退出
ssc.awaitTermination()
}}
spark+HDFS,相关demo:
import org.apache.spark.{SparkConf, SparkContext}
object ScalaPi {
def main(args: Array[String]): Unit = {
//创建SparkConf()并且设置App的名称
val conf = new SparkConf()
.setAppName("ScalaPi.scala")
.setMaster(master = "yarn-client");
//创建SparkContext,该对象是提交spark app的入口
val sc = new SparkContext(conf);
val res=sc.textFile(args(0))
.flatMap(_.split(" "))
.map((_ ,1))
.reduceByKey(_ + _,4)
.sortBy(_._2,false);
res.collect().foreach(println(_));
res.saveAsTextFile(args(1))//args(1)在hue任务提交平台设置相关的本地路径即可
//停止sc,结束该任务
sc.stop();
}
}
POM:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>testspark</groupId>
<artifactId>testspark</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<spark.version>2.3.0</spark.version>
<cupid.sdk.version>3.3.8-public</cupid.sdk.version>
<scala.version>2.11.8</scala.version>
<scala.binary.version>2.11</scala.binary.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.11</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_${scala.binary.version}</artifactId>
<version>${spark.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
</exclusion>
<exclusion>
<groupId>org.scala-lang</groupId>
<artifactId>scalap</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId&g