1 项目需求
1.1 项目目标
实训项目目标在于熟练Hadoop技术架构核心软件产品的搭建以及使用,熟悉实际项目生产过程中集群分布式大数据软件环境的搭建以及大数据应用的基本开发使用流程。
项目通过使用Hadoop大数据架构体系中的HDFS、HBase以及Spark软件,完成大数据处理的典型案例:文件词频统计的实现。
大数据应用的基本实现过程包括数据的采集、数据的存储、数据的处理和分析以及数据可视化四个典型步骤,实训中通过HDFS存储数据文件,使用Spark进行数据的处理完成词频统计,之后将文件存储到Hbase中,最终通过D3实现词频的统计。
1.2项目环境
操作系统环境:CentOS-7-x86_64-DVD-2207-02
软件产品:VMware-workstation-full-16.0.0-16894299
编程工具:vim
1.3项目中使用的文件准备
1.3.1 项目环境配置文件
①jdk-8u171-linux-x64.tar.gz
②hadoop-3.1.0.tar.gz
③hbase-1.2.4-bin.tar.gz
④zookeeper-3.4.9.tar.gz
⑤spark-3.5.0-bin-hadoop3.tgz
1.3.2 词频统计文件内容
2 项目实现步骤与结果
2.1 搭建Linux分布式集群
1.编辑hosts文件
在master节点中切换root用户执行命令gedit /etc/hosts,分别将master节点、slave0节点、slave1节点的ip地址与主机名添加到文件然后保存退出。
图2-1 修改hosts文件
2.配置JAVA环境
master节点root用户/usr/java目录执行tar -zxcf jdk-8u171-linux-x64.tar.gz命令解压安装包,切换普通用户gjw执行gedit ~/.bash_profile命令配置环境变量,配置完后保存退出,最后执行source ~/.bash_profile,使修改生效。
图2-2 JAVA环境配置文件
3.免密匙登录配置
master节点普通用户下执行ssh-keygen -t rsa生成密匙对,一次执行cd .ssh,ll查看执行结果,而后执行ssh-copy-id命令复制密钥到slave0与slave1节点。
2.2 搭建Hadoop体系集群软件环境
2.2.1安装配置Hadoop软件环境
1.配置Hadoop环境变量
普通用户gjw执行gedit ~/.bash_profile命令配置环境变量,配置完后保存退出,最后执行source ~/.bash_profile,使修改生效。然后在hadoop安装目录下的etc/hadoop/hadoop-env.sh文件中添加JDK路径变量。
图2-3 hadoop环境变量配置
2.配置核心组件
3.配置文件系统HDFS
hadoop安装目录下执行gedit ./etc/hadoop/hdfs-site.xml。
图2-4 HDFS配置
4.配置YARN站
hadoop安装目录下执行gedit ./etc/hadoop/yarn-site.xml。
图2-5 YARN站点配置
5.配置MapReduce
hadoop安装目录下执行gedit ./etc/hadoop/mapred-site.xml配置如图所
6.分布式集群节点配置
hadoop安装目录下执行gedit ./etc/hadoop/workers配置节点信息
图2-6 分布式集群节点配置
7.格式化文件系统
hadoop安装目录下执行hdfs namenode -format 进行文件系统的格式化。
8.启动Hadoop
hadoop安装目录下执行sbin/start-all.sh脚本启动hadoop的所有服务,命令执行完毕,输入jps查看hadoop是否配置成功,服务是否正常运行。启动完成后通过http://master:9870访问hadoop的Web页面,通过http://master:9870访问hadoop yarn的Web页面。
图2-7 启动hadoop服务
图2-8 hadoop的Web页面
图2-9 hadoop yarn的Web页面
2.2.2安装配置HBase软件环境
1.修改hbase-env.sh文件
进入HBase安装目录下的conf子目录,执行gedit hbase-env.sh,编辑hbase-env.sh文件。
图2-10 hbase-env.sh配置
2.配置hbase-site.xml
图2-11 hbase-site.xml配置
3.配置regionservers
图2-12 regionservers配置
4.配置linux环境变量
普通用户gjw在家目录下执行gedit ~/.bash_profile命令配置环境变量,配置完后保存退出,最后执行source ~/.bash_profile,使修改生效。
5.分布式集群节点拷贝
普通用户gjw在家目录下执行scp -r ~/hbase-1.2.4 slave0:~/命令分别将master节点的配置复制给slave0和slave1节点中。
6.启动Hbase
HBase安装目录下,执行bin/start-hbase.sh命令启动HBase服务,待程序启动完毕,分别在master节点与slave0节点输入jps查看服务是否启动成功,最后通过http://master:60010地址查看HBase的Web管理界面。
2.2.3安装配置Spark软件环境
1.Scala下载安装
2.Spark下载安装
3.配置linux环境变量
普通用户gjw在家目录下执行gedit ~/.bash_profile命令配置环境变量,配置完后保存退出,最后执行source ~/.bash_profile,使修改生效。
4.配置spark-env.sh环境文件
进入Spark安装目录下,执行gedit conf/spark-env.sh,编辑spark-env.sh文件,配置如下。
5.分布式集群节点拷贝
普通用户gjw在家目录下执行scp -r ~/hbase-1.2.4 slave0:~/命令分别将master节点的配置复制给slave0和slave1节点中。
6.启动Hbase
在master上,进入Spark安装目录,执行sbin/start-all.sh命令启动Spark,待程序启动完毕,输入jps查看服务是否启动成功,最后通过http://master:8080地址查看Spark的Web管理界面。
图2-13 启动Spark服务
图2-14 Spark的Web管理页面
2.3 HDFS存储文件
在master节点普通用户gjw家目录下,输入gedit my.txt编辑个人信息并保存退出,输入cat my.txt查看信息。执行hdfs dfs -mkdir -p /user/GuoJiaWei命令,在hadoop中 /user目录下,创建一个自己名字的文件夹,然后再执行命令hdfs -put ~/my.txt /user/GuoJiaWei,将本地创建的文件my.txt上传的hadoop,执行hdfs dfs -ls /user/GuoJiaWei 命令,查看上传到hadoop中的文件属性,最后执行hdfs dfs -cat /user/GuoJiaWei/my.txt命令查看上传到hadoop上的my.txy文件信息。
在master节点普通用户gjw家目录下,输入gedit my.txt编辑个人信息并保存退出,输入cat my.txt查看信息。执行hdfs dfs -mkdir -p /user/GuoJiaWei命令,在hadoop中 /user目录下,创建一个自己名字的文件夹,然后再执行命令hdfs -put ~/my.txt /user/GuoJiaWei,将本地创建的文件my.txt上传的hadoop,执行hdfs dfs -ls /user/GuoJiaWei 命令,查看上传到hadoop中的文件属性,最后执行hdfs dfs -cat /user/GuoJiaWei/my.txt命令查看上传到hadoop上的my.txy文件信息。
2.4 编程实现词频统计与HBase存储
2.4.1 Spark RDD实现词频统计
1.创建项目引入依赖
使用maven完成项目的依赖构建管理,创建maven项目后,使用与服务器集群安装的spark一致的依赖版本。
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>3.5.0</version>
</dependency>
2.设置Hadoop集群启动使用的用户
System.setProperty("HADOOP_USER_NAME", "gjw");
//设置spark连接对象
//设置连接的主节点url,默认通信端口7077
SparkConf sparkConf=new SparkConf().setMaster("spark://192.168.6.128:7077")
.setAppName("Word Count")//设置sparkDriver程序的主机地址
.set("spark.driver.host","192.168.0.109").setJars
(newString[]{"E:\\IdeaProjects\\swxy\\bdpro\\out\\artifacts\\bdpro_jar\\bdpro.jar"});
3. MapReduce 词频统计代码
①WordCountMapper.java
import java.io.IOException;
import java.util.StringTokenizer;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
②WordCountReducer.java
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
2.4.2 Hbase数据存储
1.引入依赖
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.1.9</version>
</dependency>
Configuration hBaseConf = HBaseConfiguration.create();
//设置hbase的连接路径
hBaseConf.set("hbase.rootdir","hdfs://192.168.6.128:9000/hbase");
//设置zookeper连接路径
hBaseConf.set("hbase.zookeeper.quorum","192.168.6.128:2181");
//建立连接并创建管理员账户
Connection connection = ConnectionFactory.createConnection(hBaseConf);
Admin admin=connection.getAdmin();
//创建wordCount表构造器
TableDescriptorBuilder wordCountBuilder= TableDescriptorBuilder
.newBuilder(TableName.valueOf("wordCount"));
//创建列族“词频”
ColumnFamilyDescriptor countCF = ColumnFamilyDescriptorBuilder
.newBuilder(familyName.getBytes()).build();
wordCountBuilder.setColumnFamily(countCF);
//创建wordCount表
TableDescriptor wordCountTable = wordCountBuilder.build();
admin.createTable(wordCountTable);
//获取创建好的表
Table wordTable = connection.getTable(TableName.valueOf("wordCount"));
//创建put对象,生成行键mytxt进行数据插入
public void put(String tableName,String rowKey,String family,String column,String value)
{
Configuration conf=init();
try {
HTable table=new HTable(conf,TableName.valueOf(tableName));
HBaseAdmin admin=new HBaseAdmin(conf);
//判断表是否存在,如果不存在进行创建
if(!admin.tableExists(Bytes.toBytes(tableName)))
{
HTableDescriptor tableDescriptor = new HTableDescriptor
(Bytes.toBytes(tableName));
HColumnDescriptor columnDescriptor=new HColumnDescriptor
(Bytes.toBytes(family));
tableDescriptor.addFamily(columnDescriptor);
admin.createTable(tableDescriptor);
}
table.setAutoFlush(true);
//进行数据插入
Put put=new Put(Bytes.toBytes(rowKey));
put.add(Bytes.toBytes(family),Bytes
.toBytes(column),Bytes.toBytes(value));
table.put(put);
table.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//往put对象中加入spark统计出的词频结果
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
public class WordCountJava {
public static void main(String[] args){
SparkConf conf = new SparkConf().setMaster("local")
.setAppName("WordCountJava");
JavaSparkContext sc = new JavaSparkContext(conf);
System.out.println(sc.textFile("./GoneWithTheWind").first());
}
}
//通过put实现批量插入一行数据
wordTable.put(put);
//释放资源
admin.close();
wordTable.close();
connection.close();
2.WordCountHBase.java
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.mapreduce.TableOutputFormat;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class WordCountHBase extends Configured implements Tool {
public static void main(String[] args) throws Exception {
int exitCode = ToolRunner.run(new WordCountHBase(), args);
System.exit(exitCode);
}
public int run(String[] args) throws Exception {
Job job = Job.getInstance(getConf(), "word count to HBase");
job.setJarByClass(getClass());
job.setMapperClass(WordCountMapper.class);
job.setCombinerClass(WordCountReducer.class);
job.setReducerClass(WordCountReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
job.setInputFormatClass(org.apache.hadoop.mapreduce.lib.input.TextInputFormat.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.getConfiguration().set(TableOutputFormat.OUTPUT_TABLE, args[2]);
job.setOutputFormatClass(TableOutputFormat.class);
return job.waitForCompletion(true) ? 0 : 1;
}
}
3. 执行以下命令运行MapReduce任务:
hadoop jar WordCountHBase.jar ~/my.txt ~/data wordCount
2.5 HBase命令行查询存储结果
2-15 查询存储结果图
3 实训结论与总结
在本次实训中,我学习并应用了Hadoop和Spark技术,探索了大数据的处理和分析方法。通过这次实训,我对大数据的概念和应用有了更深入的了解,并且掌握了一些基本的大数据处理工具和技术。
首先,Hadoop技术是本次实训的一个重点。Hadoop是一个大型分布式文件系统和数据处理框架,它的核心是HDFS(Hadoop分布式文件系统)和MapReduce计算模型。通过Hadoop,我学会了如何搭建一个分布式数据存储系统,以及如何使用MapReduce来进行大规模数据的处理和计算。在实训中,我使用Hadoop搭建了一个小规模的集群,并且通过编写MapReduce程序来完成一些简单的数据处理任务。这个过程中,我深刻体会到了大数据处理的特点,即海量数据的分布式存储和并行计算。
其次,Spark技术也是本次实训的一个重要内容。Spark是一个快速而通用的大数据处理引擎,它支持高效的分布式数据处理,并且提供了丰富的API和工具,以便更方便地进行数据分析和机器学习。通过实际操作,我学会了使用Spark来处理大规模数据,并且进行一些基本的数据分析和可视化。Spark的强大之处在于其快速的计算速度和优化的内存管理,这使得它成为当前大数据处理的首选引擎之一。
在实训过程中,我还深入学习了大数据的相关概念和技术,如数据清洗、数据挖掘、数据仓库等。我了解到,在大数据的背后,有着庞大的数据生态系统和复杂的数据处理流程。大数据的挖掘和分析不仅仅依赖于技术手段,还需要对业务需求和数据模型的理解。因此,要想在大数据领域取得进一步的突破,需要不断探索和学习,并将技术与实际应用相结合。
通过这次实训,我得到了很多实践经验,也发现了自身的不足之处。首先,我发现在实际操作中,对于大数据的处理流程和数据模型的设计需要更加深入的理解和思考。只有搞清楚数据的结构和业务需求,才能选择合适的处理技术和工具。其次,我意识到在大数据处理过程中,性能和效率是非常重要的指标。因此,我需要更深入地学习和掌握各种优化技术,以尽可能提高计算效率和减少资源消耗。
总的来说,本次实训让我对大数据的概念和技术有了更深入的认识,也为我未来在大数据领域的发展打下了良好的基础。大数据技术的发展将会给各行各业带来更多的机遇和挑战,我希望通过不断学习和实践,能够在这个领域中找到自己的定位,为数据驱动的决策和创新做出贡献。