大数据练习七
实验7:Spark初级编程实践
实验环境
操作系统:Ubuntu 18.04
Spark版本:2.4.0
Hadoop版本:3.1.3
JDK版本:1.8.0_212
Scala版本:2.11.12
sbt版本:1.3.8
实验内容与完成情况
- Spark读取文件系统的数据
1.1 在spark-shell中读取本地文件并统计行数
创建本地测试文件
echo -e "line1\nline2\nline3\nline4\nline5" > /home/hadoop/test.txt
启动spark-shell
spark-shell
在spark-shell中执行
val localFile = sc.textFile("file:///home/hadoop/test.txt")
val lineCount = localFile.count()
println(s"Local file line count: $lineCount")
执行结果:
Local file line count: 5
1.2 在spark-shell中读取HDFS文件并统计行数
上传文件到HDFS
hdfs dfs -mkdir -p /user/hadoop
hdfs dfs -put /home/hadoop/test.txt /user/hadoop/
在spark-shell中执行
val hdfsFile = sc.textFile("hdfs://localhost:9000/user/hadoop/test.txt")
val lineCount = hdfsFile.count()
println(s"HDFS file line count: $lineCount")
执行结果:
HDFS file line count: 5
1.3 编写独立应用程序统计HDFS文件行数
Scala代码(LineCountApp.scala):
import org.apache.spark.sql.SparkSession
object LineCountApp {
def main(args: Array[String]): Unit = {
// 创建SparkSession
val spark = SparkSession.builder()
.appName("Line Count Application")
.master("local[*]")
.getOrCreate()
// 读取HDFS文件
val hdfsFile = spark.sparkContext.textFile("hdfs://localhost:9000/user/hadoop/test.txt")
// 统计行数
val lineCount = hdfsFile.count()
// 输出结果
println(s"HDFS file line count: $lineCount")
// 停止SparkSession
spark.stop()
}
}
sbt配置文件(build.sbt):
name := "LineCountApp"
version := "1.0"
scalaVersion := "2.11.12"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.4.0"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "2.4.0"
编译打包与运行:
编译打包
sbt package
运行
spark-submit --class LineCountApp target/scala-2.11/linecountapp_2.11-1.0.jar
执行结果:
HDFS file line count: 5
2. 编写独立应用程序实现数据去重
Scala代码(DataDeduplication.scala):
import org.apache.spark.sql.SparkSession
object DataDeduplication {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder()
.appName("Data Deduplication")
.master("local[*]")
.getOrCreate()
// 读取两个输入文件
val fileA = spark.sparkContext.textFile("hdfs://localhost:9000/user/hadoop/input/A.txt")
val fileB = spark.sparkContext.textFile("hdfs://localhost:9000/user/hadoop/input/B.txt")
// 合并文件并去重
val merged = fileA.union(fileB).distinct()
// 排序并保存结果
merged.sortBy(line => line).saveAsTextFile("hdfs://localhost:9000/user/hadoop/output")
spark.stop()
}
}
执行步骤:
创建输入文件
echo -e "20170101 x\n20170102 y\n20170103 x\n20170104 y\n20170105 z\n20170106 z" > A.txt
echo -e "20170101 y\n20170102 y\n20170103 x\n20170104 z\n20170105 y" > B.txt
上传到HDFS
hdfs dfs -mkdir -p /user/hadoop/input
hdfs dfs -put A.txt B.txt /user/hadoop/input/
编译运行
sbt package
spark-submit --class DataDeduplication target/scala-2.11/datadedup_2.11-1.0.jar
查看结果
hdfs dfs -cat /user/hadoop/output/part-*
执行结果:
20170101 x
20170101 y
20170102 y
20170103 x
20170104 y
20170104 z
20170105 y
20170105 z
20170106 z
3. 编写独立应用程序实现求平均值问题
Scala代码(AverageScore.scala):
import org.apache.spark.sql.SparkSession
object AverageScore {
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder()
.appName("Average Score Calculation")
.master("local[*]")
.getOrCreate()
// 读取所有成绩文件
val scores = spark.sparkContext.textFile("hdfs://localhost:9000/user/hadoop/scores/*.txt")
// 计算平均成绩
val averageScores = scores
.map(line => {
val parts = line.split("\s+")
(parts(0), parts(1).toDouble)
})
.groupByKey()
.mapValues(scores => {
val sum = scores.sum
val count = scores.size
BigDecimal(sum / count).setScale(2, BigDecimal.RoundingMode.HALF_UP).toDouble
})
// 保存结果
averageScores.saveAsTextFile("hdfs://localhost:9000/user/hadoop/avg_scores")
spark.stop()
}
}
执行步骤:
创建成绩文件
mkdir -p scores
echo -e "小明 92\n小红 87\n小新 82\n小丽 90" > scores/Algorithm.txt
echo -e "小明 95\n小红 81\n小新 89\n小丽 85" > scores/Database.txt
echo -e "小明 82\n小红 83\n小新 94\n小丽 91" > scores/Python.txt
上传到HDFS
hdfs dfs -mkdir -p /user/hadoop/scores
hdfs dfs -put scores/*.txt /user/hadoop/scores/
编译运行
sbt package
spark-submit --class AverageScore target/scala-2.11/averagescore_2.11-1.0.jar
查看结果
hdfs dfs -cat /user/hadoop/avg_scores/part-*
执行结果:
(小红,83.67)
(小新,88.33)
(小明,89.67)
(小丽,88.67)
出现的问题及解决方案
问题 解决方案
Spark应用程序编译错误 确保Scala版本与Spark版本兼容,sbt配置文件中的依赖版本正确
spark-submit提交失败 检查Spark服务是否正常运行,JAR包路径是否正确
读取本地文件权限不足 确保Spark用户对本地文件有读取权限
写入HDFS失败 确保HDFS目录存在且有写入权限,使用hdfs dfs -mkdir -p创建目录
结果文件过多 使用coalesce(1)或repartition(1)合并输出文件
数据格式错误 确保输入文件的格式正确,分隔符与代码中一致

浙公网安备 33010602011771号