任务要求如下:
现在明确了我们的任务目标,就从头开始进行。
Spark内部可以直接让SparkContext从hdfs上获取数据(保证和集群具有相同的网络环境)。
//举例
//创建sparkConf对象,设置spark应用的配置信息
SparkConf conf = new SparkConf()
.setAppName("WordCount")
.setMaster("local"); //spark应用程序要连接的spark集群的master节点的url,local代表的是本地运行
//.setMaster("spark://ip:port");
//创建JavaSparkContext对象
JavaSparkContext sc = new JavaSparkContext(conf);
//针对输入源(hdfs文件、本地文件等)创建一个初始的RDD
JavaRDD lines = sc.textFile("hfs://master:9000/wordcount.txt");
在Spark1.6开始之后增加了DataSet数据类型,我们注意到通过SparkContext获得的数据为RDD类型,而通过SparkSession获得的数据为DataSet数据类型。
val sparkSession = SparkSession.builder.
master("local")
.appName("example")
.getOrCreate()
val data = sparkSession.read.text("hdfs://master:9000/wordcount.txt").as[String]
这里的data是DataSet类型的,如果要转化为java可操作的数据类型List或者Array,之后会介绍。因此对于Spark通信hdfs不需要在配置上花费时间。
只需要实现Spark到Hive之间的通信,需要将Hive/conf目录下的hive-site.xml配置文件复制到Spark/Conf目录下(这里假设Hive已经配置好,能和hdfs交互,这里不赘述);同时还要将JDBC连接器copy到Spark/jars下面,例如mysql-connector-5.4.7.jar类似的,如果连接器版本过高要下载更低版本的。如果出现其他问题,就在Google吧。
这里直接粘一下我的项目代码
SparkConf conf = new SparkConf().setAppName("sterilizedmilk").setMaster("local");;
SparkSession spark = SparkSession
.builder()
.appName("sterilizedmilk")
.config(conf)
.enableHiveSupport() //支持hive
.getOrCreate();
String querySql = "SELECT * FROM myth.sterilizedmilk";
Dataset data = spark.sql(querySql);
data_sterilizedmilk = data.collectAsList();
之前说过Spark封装了自己的sql函数,跟其他的sql语法一样,只需要写成字符串执行就可。查询到的结果为DataSet
获得的结果可以直接java遍历操作。下面就需要将数据以Spark.ml算法官方文档中使用的文件结构存储。libsvm格式如下:
Label1 para1:value1 para2:value1
Label2 para1:value2 para2:value2
这里就不沾代码了,直接按照格式写入文件就成。
这部分没什么好说的,直接去看官方文档给的示例吧!很清楚也很简洁Spark.ml传送门
我这里选择的是追加的方式直接将结果写回hdfs上,也可以保存在服务器本地,再上传至hdfs(个人觉得麻烦)。
public static void write_prediction_hdfs(List prediction, String path) throws Exception{
//获取precition数据
int interval = (int)(data_regression.size() * 0.9);
for(int i = interval; i < data_regression.size(); i++){
ArrayList temp = data_regression.get(i);
temp.add(Float.parseFloat(prediction.get(i-interval).get(2).toString()));
data_prediction.add(temp);
}
//将prediction数据写入hdfs中
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://master:9000");
FileSystem fs = FileSystem.get(conf);
FSDataOutputStream out = fs.create(new Path(path));
//写出
for(int i = 0; i < data_prediction.size(); i++) {
String re = "";
for(int j = 0;j
可以看到通过追加的方式写hdfs,就需要配置项,也就是Configuration,这个是hadoop.conf包下的Configuration,通过这个来链接hdfs,传入的path就是hdfs下的目录,文件将要写入的位置。for循环里面的都是我为了数据格式好看一些做的一些操作,嫌麻烦可以直接把数据每行toString()之后就写。
项目的完整代码已经提交到Github上,需要自取:传送门