目录
前言
Spark是一个快速、通用、可扩展的大数据处理引擎,提供了高效的数据处理能力和丰富的库,支持多种数据处理场景,包括批处理、实时流处理、机器学习和图计算等。
使用Spark进行统计指标计算的原因包括:
- 高性能:Spark采用内存计算和优化的执行计划,能够快速处理大规模数据。
- 多种数据处理模式:Spark支持批处理和实时流处理,能够满足不同的数据处理需求。
- 易用性:Spark提供了丰富的API和库,易于开发人员编写复杂的数据处理逻辑。
- 可扩展性:Spark能够在集群上进行分布式计算,支持横向扩展,能够处理大规模数据集。
- 统一的数据处理平台:Spark支持多种数据处理场景,能够在同一个平台上进行统一的数据处理和分析。
本篇博客仅供参考,更多的是自己的学习笔记,希望可以帮助到其他人。
一、准备数据集
要进行统计指标计算,首先得有数据,可以在数据网站找,也可以自己生成,在这里我是自己生成的,字段说明如下:
字段 | 类型 | 注释 | 备注 |
---|---|---|---|
pile | String | 充电桩编号 | 随机生成10位数的充电桩编号 |
pileType | String | 充电桩类型 | 随机生成桩型为T80、T132、T240、T22、T40的充电桩类型 |
status | Integer | 充电桩状态 | 随机生成充电桩状态,0表示未使用,1表示被使用 |
duration | Integer | 充电时长 | 随机生成充电时长,最高充电时长为720,单位为分钟 |
generationTime | String | 生成时间 | 根据前一次生成时间获取新的生成时间,间隔5秒采集一次 |
errCoedList | List< Integer> | 故障码列表 | 随机生成故障码列表,如果ifGenErr随机数是6的倍数,则产生故障码 |
1.准备数据信息
1.1 准备数据
public class PileData implements Serializable {
/**
* 充电桩编号
*/
private String pile;
/**
* 充电桩类型
*/
private String pileType;
/**
* 充电桩状态
*/
private Integer status;
/**
* 充电时长
*/
private Integer duration;
/**
* 生成时间
*/
private String generationTime;
/**
* 故障码列表
*/
private List<Integer> errCoedList;
public String getPile() {
return pile;
}
public void setPile(String pile) {
this.pile = pile;
}
public String getPileType() {
return pileType;
}
public void setPileType(String pileType) {
this.pileType = pileType;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Integer getDuration() {
return duration;
}
public void setDuration(Integer duration) {
this.duration = duration;
}
public String getGenerationTime() {
return generationTime;
}
public void setGenerationTime(String generationTime) {
this.generationTime = generationTime;
}
public List<Integer> getErrCoedList() {
return errCoedList;
}
public void setErrCoedList(List<Integer> errCoedList) {
this.errCoedList = errCoedList;
}
}
这段代码定义了一个Java类PileData
,用于表示充电桩的数据信息。这个类的作用是用来封装充电桩的相关数据,以便在Spark程序中对充电桩数据进行处理和分析。
1.2 写入HDFS
public class WriteToHdfs {
/**
* 数据文件存放的父路径
*/
private final String pileDataDir;
/**
* 文件名的固定部分
*/
private final String FileName = "pileData.json.";
/**
* 文件名后缀的当前值
* 可区分不同的文件
*/
private int FileNameSuffix = 1;
/**
* 当前文件已写入的行数
*/
private int LineNum = 0;
/**
* 每个文件的最大行数
* 超过则写入下一个文件
*/
private final int Max = 1000;
/**
* HDFS文件系统对象
* 与HDFS进行交互
*/
private FileSystem fs;
/**
* 构造函数
* @param pileDataDir
* @param defaultFS
* @throws IOException
* pileDataDir表示数据文件存放的父路径
* defaultFS表示HDFS的默认文件系统
*/
public WriteToHdfs(String pileDataDir, String defaultFS) throws IOException {
this.pileDataDir = pileDataDir;
// 获取HDFS文件系统对象
Configuration conf = new Configuration();
conf.set("fs.defaultFS", defaultFS);
fs = FileSystem.get(conf);
// 父目录删除
boolean exists = fs.exists(new Path(this.pileDataDir));
if (exists) {
fs.delete(new Path(this.pileDataDir), true);
}
fs.mkdirs(new Path(this.pileDataDir));
}
/**
* 获取当前文件的路径 拼接父路径、文件名、文件名后缀
* @return
*/
public String getCurPileDataFilePath() {
return this.pileDataDir + "/" + FileName + this.FileNameSuffix;
}
public void writePileDataToHdfs(List<PileData> pileDataList) throws IOException {
// 如果数据列表为空,则直接返回
if (pileDataList.size() == 0) {
return;
}
int curHandledIndex = 0;
// 循环处理数据列表
while (curHandledIndex < pileDataList.size()) {
// 如果当前行数超过了最大行数,则增加文件名后缀并重置当前行数
if (LineNum >= Max) {
this.FileNameSuffix += 1;
LineNum = 0;
}
// 获取当前文件路径
String curPileDataFilePath = getCurPileDataFilePath();
FSDataOutputStream out = null;
// 判断文件是否存在,如果存在则以追加模式打开文件,否则创建新文件
if (fs.exists(new Path(curPileDataFilePath))) {
out = fs.append(new Path(curPileDataFilePath));
} else {
out = fs.create(new Path(curPileDataFilePath));
}
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
Gson gson = new Gson();
// 循环将数据写入文件,直到达到最大行数或处理完所有数据
for (; curHandledIndex < pileDataList.size() && LineNum < Max; curHandledIndex++) {
PileData pileData = pileDataList.get(curHandledIndex);
writer.write(gson.toJson(pileData) + "\r\n");
LineNum++;
}
writer.close();
}
// 特殊处理:如果当前行数大于0且小于最大行数,则增加文件名后缀并重置当前行数
if (this.LineNum > 0 && this.LineNum < Max) {
this.FileNameSuffix++;
LineNum = 0;