学习hadoop有几天了,记录一下心得。
初期的目标是:
1:数据采集的方式,以shell脚本为主,系统配置某一些文件夹,每个文件夹是一个采集器,这样的话,一旦发现有对应的文件,那么就调用shell去进行文件上传。
2:map reduce计算,也是以shell为主。当有数据时,就自动对该数据进行计算,汇总成对应的批量入库文件。
3:调用批量入库脚本,将数据批量执行到数据库中。
安装的过程:
先下载hadoop到本地,解压后。
设置环境变量:
export HADOOP_HOME=/app/data/hadoop/hadoop export PATH=.:$HADOOP_HOME/bin:$JAVA_HOME/bin:$PATH
设置完成后,就可以调用hadoop的命令了。
然后配置,环境变量,路径为:
etc/hadoop/
我主要配置五个文件:hdfs-site.xml,core-site.xml,hadoop-env.sh,yarn-env.sh,mapred-site.xml
这几个文件的作用没有完全搞清楚:
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> </configuration> core-site.xml <configuration> <property> <name>fs.default.name</name> <value>hdfs://localhost:9000</value> </property> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/app/data/hadoop/hadoop/tmp</value> </property> </configuration> hadoop-env.sh export JAVA_HOME=/usr/java/default/ yarn-env.sh export JAVA_HOME=/usr/java/default/ mapred-site.xml <configuration> <property> <name>mapred.job.tracker</name> <value>localhost:9001</value> </property> </configuration>
一个简单的配置,配置完成后即可启动服务:
格式化分布式文件系统./hadoop namenode -format
基本上就可以了。
对于数据的采集,这里是从别人那里拿了一个shell
#!/bin/bash ################################ #2015/07/15 #作者 董磊 #hadoop数据文件采集 ############################### date ROOT=`dirname $0` CONF=./test.conf #可以利用读取配置方法加载多个服数据 #for conf in `cat $CONF` #do # echo $conf #done #是用SCP采集1,WGET采集0 is_scp=1 #scp [email protected]:/data/resin/aclocal.m4 /data/test1.m4 nowtime=`date "+%s"` startTime=$(($nowtime-7200)) #hadoop保存地址 hadoopPath=/usr/hdfs/log_kpi #采集的服务器地址 urlserver=http://service.uwan.com #采集账号地址 IPserver=######## #采集服务器保存数据地址 getPath=/app/mspsys/msplatform/log/ #日志保存目录 LOG=/app/bigdata/collectiondata/log/ #采集后保存的地址 savePath=/app/bigdata/collectiondata/ #检查LOCK LOCK=.lock if [ -f $LOCK ] then echo 'error!app is run!' exit fi #上锁 touch $LOCK #判断地址是否已经创建 if [ -d $savePath ] then echo 'file is Ok!' else mkdir $savePath fi #检查日志目录 if [ -d $LOG ] then echo 'log path is ok!' else mkdir $LOG fi #记录运行日志2>&1记录所有日志 #exec >> $LOG/gather_`date +%Y%m%d`.log 2>&1 #执行采集 while [ $startTime -le $nowtime ] do #拼凑采集文件的名称 filename=`date +%Y%m%d%H -d "@$nowtime"`.log echo aaa$filename savefilename=$savePath$filename #判断文件是否已经存在 if [ -f $savefilename ] then is_repeat=1 else is_repeat=0 fi if [ $is_scp -eq 1 ] then scp $IPserver$getPath$filename $savefilename else url=$urlserver$getPath$filename wget -O $savefilename $url fi #如果文件存在,推送到hadoop服务器 if [ -f $savefilename ] then if [ $is_repeat -eq 1 ] then $HADOOP_HOME/bin/hadoop fs -rm $hadoopPath/$filename fi $HADOOP_HOME/bin/hadoop fs -put $savefilename $hadoopPath/$filename fi nowtime=$(($nowtime-3600)) done #解除锁 rm -rf $LOCK
从hadoop的管理页面中可以查看一下:
http://10.136.2.14:50070/explorer.html#/
有了这个数据后,就可以编写mapreduce程序了。我这边一开始是要用maven的,但好多的jar包找不到,只能是使用了一种比较笨的办法,将例子中的jar拿过来用。
代码如下:
package org.conan.myhadoop.mr.kpi; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class KPIPV { public static class KPIPVMapper extends Mapper<Object, Text, Text, IntWritable>{ private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(Object key, Text value, Context context ) throws IOException, InterruptedException { KPI kpi = KPI.filterPVs(value.toString()); if (kpi.isValid()) { word.set(kpi.getRequest()); context.write(word, one); } } } public static class KPIPVReducer 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) { try { sum += Integer.parseInt(String.valueOf(val.get())); } catch (Exception ex) { ex.printStackTrace(); sum += 0; } } result.set(sum); context.write(key, result); } } public void start() throws IOException, ClassNotFoundException, InterruptedException { String input = "hdfs://127.0.0.1:9000/usr/hdfs/log_kpi/"; String output = "hdfs://127.0.0.1:9000/usr/hdfs/outlog"; Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "word count"); job.setJarByClass(KPIPV.class); job.setMapperClass(KPIPVMapper.class); job.setCombinerClass(KPIPVReducer.class); job.setReducerClass(KPIPVReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(input)); FileOutputFormat.setOutputPath(job, new Path(output)); System.exit(job.waitForCompletion(true) ? 0 : 1); } }
好了,执行完成后,在对应的目录中就可以查看到处理结果了。
接下来准备用这个玩意来分析一下实际的日志文件,然后把结果生成一个批量入库的数据文件,批量写到mysql数据库中。未完待续。