源数据文件部分行:222.68.172.190 - - [18/Apr/2020:06:49:57 +0000] "GET /images/my.jpg HTTP/1.1" 200 19939 "http://www.angularjs.cn/A00n" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36"
拿到源数据access.log之后,准备工作如下:
1.数据进行预处理,加载hive表之前
>>MR程序处理
>>正则表达式(企业推荐)
>>python脚本
2.表拆分,源数据不变,创建对应业务需求的字表
3.基于子表的基础之上:
3-1.数据文件存储格式:orc/parquet
3-2.数据文件压缩:snappy
3-3.map output:中间结果数据压缩snappy
3-4.外部表
3-5.分区表
3-6.UDF数据处理
一、创建Hive表,匹配正则表达式:

//创建Hive总表CREATE TABLE access_log (host STRING,identity STRING,userid STRING,visitdate STRING,request STRING,status STRING,size STRING,referer STRING,agent STRING)ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'WITH SERDEPROPERTIES ("input.regex" = "([^ ]*) (-|[^ ]*) (-|[^ ]*) (-|\\[[^\\]]*\\]) (\"[^\"]*\") ([0-9]*) ([0-9]*) (\"[^\"]*\") (\"[^\"]*\")?")STORED AS TEXTFILE;//加载数据load data local inpath '/opt/datas/access.log' into table access_log;
二、创建优化后部分字段Hive表:
//取部分字段CREATE TABLE access_log_comm (host STRING,visitdate STRING,status STRING,referer STRING)ROW FORMAT DELIMITEDFIELDS TERMINATED BY ','STORED AS ORC tblproperties ("orc.compress"="SNAPPY");//加载数据insert into table access_log_commselect host,visitdate,status,referer from access_log;
三、自定义UDF并打包上传编辑函数
// 时间格式转换// 18/Apr/2020:06:49:57 +0000 -> 20200418064957import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.io.Text;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;public class DateTransform extends UDF{SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss",Locale.ENGLISH);SimpleDateFormat outputsimpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");public Text evaluate(final Text s){if(s == null){return null;}String strDate = null;try{Date date = simpleDateFormat.parse(s.toString());strDate = outputsimpleDateFormat.format(date);}catch (Exception e){e.printStackTrace();}return new Text(strDate);}//测试public static void main(String[] args) {System.out.println(new DateTransform().evaluate(new Text("18/Apr/2020:06:49:57 +0000")));}}
//删除特殊字符“[]”// [18/Apr/2020:06:49:57 +0000] -> 18/Apr/2020:06:49:57 +0000import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.io.Text;public class RemoveSquare extends UDF {public Text evaluate(final Text s){if(s == null){return null;}String str = s.toString();return new Text(str.replaceAll("\\[|\\]",""));}//测试public static void main(String[] args) {System.out.println(new RemoveSquare().evaluate(new Text("[18/Apr/2020:06:49:57 +0000]")));}}
//删除特殊字符“""”// "-" -> -import org.apache.hadoop.hive.ql.exec.UDF;import org.apache.hadoop.io.Text;public class RemoveQuotes extends UDF {public Text evaluate(final Text s){if(s == null){return null;}String str = s.toString();return new Text(str.replaceAll("\"",""));}//测试public static void main(String[] args) {System.out.println(new RemoveQuotes().evaluate(new Text("\"-")));}}
打成Jar包上传到本地,加载到Hive中:
add jar /opt/jars/student.jar;
创建UDF函数:
create temporary function kfk_removeSquare as 'com.kfk.hive.RemoveSquare';create temporary function kfk_removeQuotes as 'com.kfk.hive.RemoveQuotes';create temporary function kfk_dateTransform as 'com.kfk.hive.DateTransform';
查看UDF函数:
show functions;

四、创建并加载清洗过的Hive表
//创建表并加载数据CREATE TABLE access_log_optROW FORMAT DELIMITEDFIELDS TERMINATED BY ','STORED AS ORC tblproperties ("orc.compress"="SNAPPY")AS select host,kfk_dateTransform(kfk_removeSquare(visitdate)) time,status,kfk_removequotes(referer) referer from access_log_comm;//数据查询select referer,count from (select referer,count(1) count from apache_log_opt group by referer) a order by count desc limit 5;
打印结果:

五、基于Python数据预处理
数据部分行:1,31,2.5,12607591441,1029,3.0,12607591791,1061,3.0,1260759182
//创建Hive表CREATE TABLE u_data (userid INT,movieid INT,rating INT,unixtime STRING)ROW FORMAT DELIMITEDFIELDS TERMINATED BY ','STORED AS TEXTFILE;//加载数据LOAD DATA LOCAL INPATH '/opt/datas/ratings.txt'OVERWRITE INTO TABLE u_data;
本地创建Python脚本:weekday_mapper.py
import sysimport datetimefor line in sys.stdin:line = line.strip()userid, movieid, rating, unixtime = line.split(',')weekday = datetime.datetime.fromtimestamp(float(unixtime)).isoweekday()print '\t'.join([userid, movieid, rating, str(weekday)])
将执行过py脚本的数据加载到新的表里:
//创建新表CREATE TABLE u_data_new (userid INT,movieid INT,rating DOUBLE,weekday INT)ROW FORMAT DELIMITEDFIELDS TERMINATED BY ',';//添加脚本add FILE /opt/jars/weekday_mapper.py;//将时间戳转换成星期的数据插入新表INSERT OVERWRITE TABLE u_data_newSELECTTRANSFORM (userid, movieid, rating, unixtime)USING 'python weekday_mapper.py'AS (userid, movieid, rating, weekday)FROM u_data;//执行查询SELECT weekday, COUNT(*)FROM u_data_newGROUP BY weekday;
六、隐藏列
//INPUT__FILE__NAME:文件数据路径//BLOCK__OFFSET__INSIDE__FILE:文件块的偏移量select INPUT__FILE__NAME, userid, BLOCK__OFFSET__INSIDE__FILE from order_part;

文章转载自数据信息化,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




