java web调用mapreduce算法-Day2&4(更新)

 哈哈 在这千钧一发的时刻,居然好用了~时刻:22:37

1.第一个问题,由于昨天启动Tomcat次数过多,有很多日志留在/tmp目录下,可能还有别的原因,导致今天一来启动Tomcat就不行了,因为磁盘空间不足,后来师兄删了日志,并且告诉我记得自己删日志,还挪了11G磁盘空间给这个分区,这样就顺畅了~

2.MySQL报错:MySQL: Can't create/write to file '/tmp/#sql_3c6_0.MYI' (Errcode: 2)这种

https://stackoverflow.com/questions/11997012/mysql-cant-create-write-to-file-tmp-sql-3c6-0-myi-errcode-2-what-does

也是在stackoverflow的这个帖子下找到方法,那就是,重启MySQL哈哈,其中一个人说自己每个月遇到两三次这种情况,每次重启一下就好了,我就又麻烦师兄帮忙重启下MySQL,果然,OK了,原因大概是师兄删tmp目录的时候把什么东西也删掉了吧

3.然后就是昨天的查询慢的问题了,先说今天试MySQL查询,在小表上第一条是慢的,第二条之后就稳定了,但是在大数据集上,1G+就还是10min+今天,就先不管它了,昨天比较加上框架在集群上跑就卡在map11%了,今天调好了一跑还是卡在那;同时昨天和今天我都注意到一个问题,那就是启动的是localjobrunner,job的名称也是job_local***,那就说明这是本地模式啊,很可能因为这个所以才特别慢并且还占了很多磁盘空间,之后就baiduHadoop集群模式启动,我的代码通过调用类的main方法,就相当于eclipse直接运行main函数提交任务到Hadoop集群是一样的,一般我们使用命令行hadoop jar [jar-path][mainclass-name][input][output],这个命令行实现的就是将jar包提交到集群的各个节点上,所以用eclipse提交也必须完成这个功能,让集群需要知道这四个参数(命令行提供的),我的main函数代码如下:

Configuration conf = new Configuration();
conf.set("mapreduce.job.jar","/home/user/***.jar");  //change
conf.set("fs.defaultFS", "hdfs://master:9000/");          //change
conf.set("mapreduce.framework.name", "yarn");               //change
conf.set("yarn.resourcemanager.hostname", "master.cluster"); 
Job job = Job.getInstance(conf, "springboot");
job.setJarByClass(WordCount.class); 
 job.setMapperClass(TokenizerMapper.class);
 job.setReducerClass(IntSumReducer.class);
 job.setOutputKeyClass(LongWritable.class);
 job.setOutputValueClass(Text.class);
 FileInputFormat.addInputPath(job, new Path(args[0]));
 FileOutputFormat.setOutputPath(job, new Path(args[1]));
 job.waitForCompletion(true);


mapred.jar就是命令行提供的jar-path参数了,放在本地的那种;

fs.defaultFS这个就是HDFS的配置,想操作HDFS也要提供的,网上很多讲解了;

mapreduce.framework.name写死的,yarn模式就是集群模式;

yarn.resourcemanager.hostname也是在配置文件里的,去集群的配置文件看一看就好了;

关于命令行提供的[input][output]两个参数,是我调用这个main时指定的;[mainclass-name]这个参数,是我们打jar包时指定的(用eclipse的export打包,不是maven那种哦~)。



然鹅,和网上贴的代码不一样的就是,去掉了setjarbyclass,弄了一天终于跑起来了。因为我把springboot打成一个jar包ssh远程登录集群运行的工程,mapreduce.job.jar的路径是本地路径,所以我这里面涉及了两个jar!我实验了多种觉得mapreduce.job.jar参数应该是不能用jar包里的相对路径,所以jar不用打在工程里面(之前报ClassNotFound我想可能是运行的是jar就不能引用外部jar的class了?所以尝试把要跑的jar打进maven工程里,为了maven添加进本地jar包,我也卡了大半天,解决思路是把jar包install进本地仓库,然后dependency依赖加上就行,scope写runtime就打进去了),放在本地就行。所以我理解可能是由于setjarbyclass在conf设置mapreduce.job.jar后面,把之前的覆盖了,而mapreduce.job.jar才是我们要跑的jar,然后我就验证了一下我的想法,终于不报ClassNotFound了(幸运之神眷顾我啊……毕竟我也准备好了还有其它可能一个一个试呢,看见这“激动人心”的结果,真是幸运~)。(但是跑的很慢,卡在了数据库查询上,在本地模式跑也遇到过这种情况反正,重启大法反正就好了,可能文件什么的太多了又没空间了??)现在能跑起来的“环境”是:要运行的jar有setjarbyclass,springboot中调用的main里去掉。

http://www.aboutyun.com/thread-9366-1-1.html 讲的比较深,说是setjarbyclass方法就是找到class所属的jar以后赋值给mapreduce.job.jar,于是我就想到可能被覆盖了的问题。

因为我在本地运行main里和jar的main里都有setjarbyclass,但是可以运行并且结果正确,所以觉得setjarbyclass是问题根源的可能性很低,只是顺手试一试,没想到居然真的跟它有关系……

我想应该是放在集群上的时候main本身就在我打成的jar里,而且还有一个真正运行的jar,就两个了,而本地只有一个,毕竟本地的main在eclipse里运行所以不会有误会/覆盖吧,所以集群上的main才要去掉setjarbyclass。

因为我是远程ssh操作集群,所以把Mapreduce算法的jar包打好,放到集群我的用户目录下,不用上传到HDFS上啦,然后把我的springboot工程用maven build好出jar包,放到集群上,java -DServer.port=8090 -jar ***.jar启动,试着访问以下该方法,不仅Mapreduce成功,操作HDFS成功,数据也返回到浏览器上了~搞定~


说两个昨天落下忘讲了的小问题:

1.Java web调用Mapreduce的时候,main里面写的是System.exit(job.waitForcompletion(true)),这就导致什么呢,导致Mapreduce运行完JVM就关闭了,然后会导致Tomcat重启啥的而且重启会失败,具体我忘了,所以去掉System.exit就好~

2.“cd /”命令,师兄今天来我这帮我解决问题,我才知道还有这个目录呢,我之前以为只有我的主目录也就是“cd ~”访问到的那个,“cd /”就是root目录了吧,很厉害,想Hadoop_home还有我要定时清理的/tmp都在下面了,厉害厉害。


贴个图片纪念我这一晚的……推理秀!






### Hadoop 数据上传与清洗的最佳实践 #### 1. 数据上传至 HDFS 在 Hadoop 中,数据通常存储在分布式文件系统(HDFS)中。为了进行后续的数据处理和清洗操作,首先需要将原始数据从本地或其他外部源上传到 HDFS。 可以使用 `hdfs dfs` 命令来完成这一过程。以下是常见的命令示例: ```bash hdfs dfs -put /path/to/local/file /path/in/hdfs/ ``` 如果目标路径不存在,则可以通过以下命令创建目录结构: ```bash hdfs dfs -mkdir -p /path/in/hdfs/ ``` 对于大规模数据集,建议分批次上传并验证其完整性[^1]。此外,还可以利用脚本自动化批量上传任务,例如 Shell 脚本或 Python 脚本调用 Hadoop API 完成复杂场景下的数据迁移工作。 --- #### 2. 使用 MapReduce 进行数据清洗 数据清洗是大数据预处理的重要环节之一。基于 Hadoop 的 MapReduce 编程模型能够高效地对海量数据实施过滤、转换等操作。具体实现如下所示: ##### (1)编写 Mapper 程序 Mapper 是负责读取输入数据并对每条记录应用自定义逻辑的核心组件。下面是一个典型的 Python 版本的 Mapper 示例代码片段: ```python #!/usr/bin/env python import sys for line in sys.stdin: try: fields = line.strip().split('\t') # 根据实际需求调整字段分割符 if len(fields) != EXPECTED_COLUMNS: # 替换为预期列数 continue # 自定义清洗规则 cleaned_data = process_record(fields) # 需自行实现该函数 print("\t".join(cleaned_data)) except Exception as e: pass # 忽略异常记录 ``` 注意:当仅需执行映射阶段而无需规约时,应显式禁用 Reduce Task 设置以优化性能[^3]: ```java Configuration conf = new Configuration(); Job job = Job.getInstance(conf); ... job.setNumReduceTasks(0); // 关闭 Reducer ``` ##### (2)提交作业 构建好 Mapper 和必要的配置参数之后,可通过官方提供的 Streaming 工具启动整个流程。假设已准备好名为 `mapper.py` 的脚本以及待处理的日志文件 `/web/nginx/log/` ,则对应的 CLI 指令形式如下: ```bash hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-*.jar \ -input /web/nginx/log/ \ -output /result1 \ -mapper "/root/word/mapper.py" ``` 此处需要注意的是输出路径不可预先存在以免引发冲突;另外记得授予所有参与节点访问权限以便顺利加载依赖资源。 --- #### 3. Hive 表辅助数据分析 除了直接运用低级接口外,借助高级抽象层如 Apache Hive 可进一步简化开发难度同时增强灵活性。比如针对已完成初步净化后的日志建立关联型视图便于查询统计: ```sql CREATE EXTERNAL TABLE IF NOT EXISTS g6_access ( cdn STRING, region STRING, level STRING, time STRING, ip STRING, domain STRING, url STRING, traffic BIGINT ) PARTITIONED BY (day STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LOCATION '/g6/hadoop/access/clear'; MSCK REPAIR TABLE g6_access; ``` 上述语句定义了一个分区表结构用于容纳按日期分类的结果集合,并允许动态扩展新时段内的增量更新[^2]。 --- #### 总结 综上所述,在 Hadoop 平台上开展有效的数据管理活动涉及多个方面考量因素,包括但不限于合理规划物理布局设计模式选取恰当算法框架等等。遵循这些指导原则有助于提升整体效率降低运维成本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值