这篇文章介绍如何用hive来分析一个网站访问日志文件。这里假定你已经安装好了一个跟hadoop集群(pseudo mode亦可)协作的hive,如果还没有,看
这里
建表
hive> create table coupon11_log (day string, time string, usernameid string, ip string, url string) row format serde 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' with serdeproperties( "input.regex" = "([^\\s]+)\\s+([^\\s]+)\\s+[^\\s]+\\s+[^\\s]+\\s+[^\\s]+\\s+[^\\s]+\\s+\-\\s+userNameId\-([^\\s]+)\\s+from\\s+IP\-([^\\s]+)\\s+invoked\\s+URL\-([^\\s]+).*" ); -- 这个正则表达式就是访问日志的正则,一共5个括号,对应表里的5列
从HDFS载入数据文件到表中
hive> load data inpath '/user/coupon11log' overwrite into table coupon11_log; --这里其实只会复制文件,不会解析它,所以这一步很快 select * from coupon11_log limit 10; -- 小看一下装载进来的数据
试一个简单的统计查询
hive> select url, count(*) as count from coupon11_log group by url;
观察一下控制台的输出,除了可以看到查询的结果,你还能看到有些MapReduce Job被生成了
保存查询结果
--保存到hdfs中 hive> insert overwrite directory '/tmp/output2012112701' select url, count(*) as count from coupon11_log group by url;
--保存到另一个hive表中 create table coupon11_log_top10 (day string, time string, usernameid string, ip string, url string) ; insert overwrite table coupon11_log_top10 select * from coupon11_log limit 10;
按小时统计访问量:使用用户自定义Hive函数(UDF)
要统计出每个小时的访问量,你首先要搞定如何从day和time这两个字段中搞出yyyyMMdd-HH这种格式的“小时”作为结果字段。 解决办法就是用Java写一个UDF.
<dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-contrib</artifactId> <version>0.9.0</version> <scope>runtime</scope> </dependency>
... import org.apache.hadoop.hive.ql.exec.UDF; ... public class HourFunction extends UDF { ... public Text evaluate(Text day, Text time) { Date date = parseDate(day.toString() + " " + time.toString()); if (date == null) { return null; } Date hour = DateUtils.truncate(date, Calendar.HOUR_OF_DAY); return new Text(DateFormatUtils.format(hour, "yyyyMMdd-HH")); } ... }
打包成jar包
引用
mvn assembly:assembly
在hive中加入这个jar并注册这个UDF
hive> add jar /home/kent/dev/workspace/coupon11log/target/coupon11logs-1.0-SNAPSHOT-jar-with-dependencies.jar; create temporary function hour as 'coupon11log.hive.HourFunction';
最后执行按小时统计
hive> select h as HOUR, count(*) as VISIT from (select hour(day,time) as h from coupon11_log) group by h;
按用户所在国家统计访问量并排序:JOIN和SORT
这里就是Hive的强大之处,它可以让你非常迅速地写好JOIN、SORT等功能,不需要苦哈哈地手写java代码来实现。
这里假定你有”IP-国家”这样的数据文件,并且已经把它装载到一张hive表(ip_country)中。
你要执行的HiveQL是:
hive> insert overwrite directory '/tmp/output2012112703' select * from ( select ip_country.country, count(*) as count from coupon11_log join ip_country on coupon11_log.ip=ip_country.ip group by ip_country.country ) stats order by count desc;