Hive自定义函数的使用——useragent解析

标签: hive 定义 函数 | 发表时间:2014-10-31 00:56 | 作者:ozhaohuafei
出处:http://blog.csdn.net

想要从日志数据中分析一下操作系统、浏览器、版本使用情况,但是hive中的函数不能直接解析useragent,于是可以写一个UDF来解析。useragent用于表示用户的当前操作系统,浏览器版本信息,形如:

Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 180.173.196.29

其中解析ua可以用一个开源的工具包,叫做useragentutils.jar来处理,但是不能直接引入这个包,因为hadoop和hive都不支持直接引用第三方的包,要导入源码。项目结构应该如下图


下面的代码用来打印出操作系统、浏览器版本信息:

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

import eu.bitwalker.useragentutils.UserAgent;

public class ParseUserAgent_UDF extends UDF{
	public Text evaluate(final Text userAgent){
		StringBuilder builder = new StringBuilder();
		UserAgent ua = new UserAgent(userAgent.toString());
		builder.append(ua.getOperatingSystem()+"\t"+ua.getBrowser()+"\t"+ua.getBrowserVersion());
		return new Text(builder.toString());
	}
}
使用:打成jar包,hive中add jar xx.jar;

create temporary function ua_parse as 'com.xx.ParseUserAgent_UDF';

select ua_parse(ua) from table_name limit 3;

结果:

WINDOWS_7       CHROME21        21.0.1180.89
WINDOWS_7       CHROME33        33.0.1750.146
WINDOWS_7       CHROME21        21.0.1180.89

此种方式只能处理一行,生成一行,无法进行统计分析。

下面使用UDTF(User Defined Table Generating Function),处理一行,生成多列。

import java.util.ArrayList;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

import eu.bitwalker.useragentutils.UserAgent;

public class ParseUserAgent_UDTF extends GenericUDTF{
	@Override
	public StructObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException {
		if (args.length != 1) {
			throw new UDFArgumentLengthException("ExplodeMap takes only one argument");
		}
		if (args[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {
			throw new UDFArgumentException("ExplodeMap takes string as a parameter");
		}
		ArrayList<String> fieldNames = new ArrayList<String>();
		ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
		fieldNames.add("system");
		fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
		fieldNames.add("browser");
		fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
		fieldNames.add("version");
		fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
		return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
	}
	@Override
	public void process(Object[] arg){
		try {
			if(arg == null || arg.length == 0)
				return;
			String input = arg[0].toString();
			String result[] = ua_parse(input).split("\t");
			forward(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void close() throws HiveException {
		
	}
	public String ua_parse(String userAgent){
		StringBuilder builder = new StringBuilder();
		UserAgent ua = new UserAgent(userAgent.toString());
		builder.append(ua.getOperatingSystem()+"\t"+ua.getBrowser()+"\t"+ua.getBrowserVersion());
		return builder.toString();
	}
}
select t.browser,count(*) c from (select ua_parse(ua) as (system,browser,version) from table_name) t group by t.browser order by c desc;
前十名:

CHROME31        987220571
UNKNOWN 708890045
IE8     420021677
IE7     411500373
MOBILE_SAFARI   291920740
IE6     217574865
IE11    179582201
IE9     165160040
CHROME30        158623163
CHROME21        155192489

未识别的还是很多!


参考:http://blog.csdn.net/ruidongliu/article/details/8791865

http://computerdragon.blog.51cto.com/6235984/1288567


作者:ozhaohuafei 发表于2014-10-30 16:56:34 原文链接
阅读:65 评论:0 查看评论

相关 [hive 定义 函数] 推荐:

Hive自定义函数的使用——useragent解析

- - CSDN博客云计算推荐文章
想要从日志数据中分析一下操作系统、浏览器、版本使用情况,但是hive中的函数不能直接解析useragent,于是可以写一个UDF来解析. useragent用于表示用户的当前操作系统,浏览器版本信息,形如:. 其中解析ua可以用一个开源的工具包,叫做useragentutils.jar来处理,但是不能直接引入这个包,因为hadoop和hive都不支持直接引用第三方的包,要导入源码.

自定义 Hibernate 的 HQL 函数

- - CSDN博客互联网推荐文章
 有时候我们使用一些数据库特有的SQL语法跟HQL有冲突怎么办,看看这个. 标签: HQL  Dialect  MySQL  Hibernate. [1].[代码] MySQLExtendDialect.java  跳至  [1]. * 作者: Winter Lau. * 时间: 2009-4-13.

hive调优

- - 互联网 - ITeye博客
一、    控制hive任务中的map数: . 1.    通常情况下,作业会通过input的目录产生一个或者多个map任务. 主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M, 可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改);.

hive 优化 tips

- - CSDN博客推荐文章
一、     Hive join优化. 也可以显示声明进行map join:特别适用于小表join大表的时候,SELECT /*+ MAPJOIN(b) */ a.key, a.value FROM a join b on a.key = b.key. 2.     注意带表分区的join, 如:.

Hive中的join

- - CSDN博客云计算推荐文章
select a.* from a join b on a.id = b.id select a.* from a join b on (a.id = b.id and a.department = b.department). 在使用join写查询的时候有一个原则:应该将条目少的表或者子查询放在join操作符的左边.

hive优化(2)

- - 开源软件 - ITeye博客
Hive是将符合SQL语法的字符串解析生成可以在Hadoop上执行的MapReduce的工具. 使用Hive尽量按照分布式计算的一些特点来设计sql,和传统关系型数据库有区别,. 所以需要去掉原有关系型数据库下开发的一些固有思维. 1:尽量尽早地过滤数据,减少每个阶段的数据量,对于分区表要加分区,同时只选择需要使用到的字段.

hive优化

- - 开源软件 - ITeye博客
hive.optimize.cp=true:列裁剪. hive.optimize.prunner:分区裁剪. hive.limit.optimize.enable=true:优化LIMIT n语句. hive.limit.optimize.limit.file=10:最大文件数.   1.job的输入数据大小必须小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB).

Hive优化

- - 互联网 - ITeye博客
     使用Hive有一段时间了,目前发现需要进行优化的较多出现在出现join、distinct的情况下,而且一般都是reduce过程较慢.      Reduce过程比较慢的现象又可以分为两类:. 情形一:map已经达到100%,而reduce阶段一直是99%,属于数据倾斜. 情形二:使用了count(distinct)或者group by的操作,现象是reduce有进度但是进度缓慢,31%-32%-34%...一个附带的提示是使用reduce个数很可能是1.

hive bucket 桶

- - CSDN博客推荐文章
对于每一个表(table)或者分区,Hive可以进一步组织成桶. Hive也是针对某一列进行桶的组织. Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶当中. 采用桶能够带来一些好处,比如JOIN操作. 对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作. 那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量.

hive mapjoin使用

- - 淘剑笑的博客
今天遇到一个hive的问题,如下hive sql:. 该语句中B表有30亿行记录,A表只有100行记录,而且B表中数据倾斜特别严重,有一个key上有15亿行记录,在运行过程中特别的慢,而且在reduece的过程中遇有内存不够而报错. 为了解决用户的这个问题,考虑使用mapjoin,mapjoin的原理:.