显示标签为“Hive”的博文。显示所有博文
显示标签为“Hive”的博文。显示所有博文

2016年4月5日星期二

Hive中使用first_value和max等窗口函数

遇到一个需求,统计不同的phone_device_id最近的event_timestamp的status值出现的次数,原始数据距离(phone_device_id, status, event_timestamp):
a 0 10
a 1 20
b 1 10
c 1 20
b 0 30
c 0 10
需要的结果:
0 1
1 2
因为a最新的状态是1,b最新的状态是0,c最新的状态是1,所以0总共有1个,1总共有2个。

可以使用以下语句实现,主要是max() over()和first_value() over():
select get_json_object(s2.first_value_window_1, '$.status'), count(distinct(phone_device_id)) from (select phone_device_id, max(event_timestamp) over (partition by phone_device_id), first_value(properties) over (partition by phone_device_id order by event_timestamp desc) from watch_upload_info where event_date = '2016-04-04' and get_json_object(properties, '$.action') = 'aw_status' and event = 'click') s2 group by get_json_object(s2.first_value_window_1, '$.status');

还可以使用另外一个方法:
先根据phone_device_id来分组取出event_timestamp最大的那条记录存到一张临时表中,然后和原表进行join得到status字段,然后再分组。

2016年2月17日星期三

Hive远程客户端配置

准备一台新的客户机,拷贝hive使用的hadoop及hadoop的配置,设置HADOOP_HOME。拷贝已配置好的hive文件夹到新的机器,设置HIVE_HOME,修改PATH增加hadoop和hive。确保$HIVE_HOME/conf/hive-site.xml配置中的hive.aux.jars.path的hive文件夹路径正确。
如果已经设置了HADOOP_HOME或者将hadoop添加到了PATH中,执行hive确依然说没有找到hadoop,不妨看一下$HIVE_HOME/conf/hive-env.sh中有没有已经设置了错误的HADOOP_HOME路径,删掉即可。

将hadoop目录下的jline改为高版本:
cp $HIVE_HOME/lib/jline-2.12.jar $HADOOP_HOME/share/hadoop/yarn/lib/
rm $HADOOP_HOME/share/hadoop/yarn/lib/jline-0.9.94.jar

执行hive,完成。

将HDFS中JSON格式日志以日期分区导入Hive

下面看一个实例,按天进行分区。

数据格式如下,需要解析其中的部分字段:
{"version_name":"3.2.0","phone_system_fingerprint":"Xiaomi/libra/libra:5.1.1/LMY47V/V7.1.6.0.LXKCNCK:user/release-keys","phone_device_id":"ac614a689cdbb1ecd2713a4dbc008682","phone_device_type":"Mi-4c","watch_device_id":"7664e1b6eba4abc542ad5db0ce892fb7","properties":{"address":"中国,北京市,北京市,海淀区,海淀北二街,8号,39.989566,116.316318"},"type":"watch","version":"12600","deviceid":"ac614a689cdbb1ecd2713a4dbc008682","timestamp":"1455512510381","sys_version":"5.1.1","address":"中国,河北省,唐山市,路北区,和平路,,39.630073,118.136363","net_state":"","event":"user_connect","user_id":"ac614a689cdbb1ecd2713a4dbc008682","ticwear_version":"tic_3.2.1","watch_device_type":"Ticwatch","sys_model":"Mi-4c","channel":"main"}

1、首先用pig解析JSON,脚本如下:
REGISTER elephant-bird-pig.jar;
REGISTER elephant-bird-core.jar;
REGISTER elephant-bird-hadoop-compat.jar;
REGISTER json-simple.jar;

%default WATCH_UPLOAD_LOG /path/*.json

raw_log = LOAD '$WATCH_UPLOAD_LOG'
                USING com.twitter.elephantbird.pig.load.JsonLoader('-nestedLoad');

tic_log = FOREACH raw_log GENERATE
                 (chararray)$0#'version_name' AS version_name,
                 (chararray)$0#'phone_device_id' AS phone_device_id,
                 (chararray)$0#'watch_device_id' AS watch_device_id,
                 (chararray)$0#'phone_device_type' AS phone_device_type,
                 (chararray)$0#'properties'#'address' AS address,
                 (chararray)$0#'type' AS type,
                 (chararray)$0#'event' AS event,
                 (chararray)$0#'user_id' AS user_id,
                 (chararray)$0#'deviceid' AS device_id,
                 (chararray)$0#'ticwear_version' AS ticwear_version,
                 (chararray)$0#'watch_device_type' AS watch_device_type,
                 (chararray)$0#'sys_model' AS sys_model,
                 (chararray)$0#'timestamp' AS timestamp;

STORE tic_log INTO '/path/tic_log';

2、使用Hive导入数据:
create external table watch_upload_info_temp(version_name string, phone_device_id string, watch_device_id string, phone_device_type string, address string, type string, event string, user_id string, device_id string, ticwear_version string, watch_device_type string, sys_model string, `timestamp` bigint) row format delimited fields terminated by '\t' stored as textfile location '/path/tic_log';

create table watch_upload_info(version_name string, phone_device_id string, watch_device_id string, phone_device_type string, address string, type string, event string, user_id string, device_id string, ticwear_version string, watch_device_type string, sys_model string, `timestamp` bigint) partitioned by (time string);

set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.max.dynamic.partitions = 10000;
set hive.exec.max.dynamic.partitions.pernode = 1000;

insert into table watch_upload_info partition(time) select *, from_unixtime(floor(`timestamp`/1000), "yyyy-MM-dd") time from watch_upload_info_temp where `timestamp` > 1417363200000;  -- 这里1417363200000是2014-12-01,timestamp是以ms为单位。

2016年2月16日星期二

Hive查看已存在的表是内部表或外部表

两种方法:
1) hive> desc formatted tbl_name
2) hive> desc extended tbl_name

Table Type是MANAGED_TABLE表示内部表,EXTERNAL_TABLE是外部表。

2015年12月22日星期二

生成应用商店的用户数据文件

Select with concat:
hive> select concat(device_id, ',', appid, ',', apk_url) from download_log where device_id is not NULL;
hive> select concat(device_id, ',', package_name) from detail_log where device_id is not NULL;
Above data is too large to save.

For the huge number of detail log, I group them first:
hive> select device_id, package_name, count(package_name) rank from detail_log where length(device_id) > 0 and length(package_name) > 0 group by device_id, package_name order by rank desc;

If you want to split each entry by comma instead of tab, you can use awk (assume that your filename is test):
$ cat test | awk '{print $1“,"$2","$3}' > test_commma

For the download log, also I group them:
hive> select device_id, appid, count(appid) rank from download_log where length(device_id) > 0 group by device_id, appid order by rank desc;

Save results into local file:
insert overwrite local directory 'your_path'
row format delimited
fields terminated by '\t'
stored as textfile
select * from table where ...;

2015年11月30日星期一

使用Hive统计应用商店数据

Download log:
{
    "device_id":"5d9e295b8705895f8c6de5420eb1973b",
    "download_log":
    {
        "apk_url":"http://res.appstore.ticwear.com/com.broadlink.rmt_3.5.9-1.1.9.apk",
        "appid":1000
    },
    "message_type":3,
    "remote_ip":"220.200.5.247",
    "time":1441571407,
    "uid":"29716727"
}

Count the number of devices:
hive> select count(distinct device_id) from download_log;

Count the download times of different users:
hive> select device_id, count(device_id) rank from download_log group by device_id order by rank desc;
or: hive> select uid, device_id, count(device_id) rank from download_log group by uid, device_id order by rank desc;

Count the download times of different apps:
hive> select apk_url, appid, count(appid) rank from download_log group by apk_url, appid order by rank desc;

Detail log:
{
    "detail_log":
    {
        "from":"",
        "package_name":"com.stmp.minimalface",
        "query":""
    },
    "device_id":"a5147789062ba29b06562bca6cbb3cc1",
    "message_type":0,
    "remote_ip":"61.239.223.125",
    "time":1441331302,
    "uid":"29728861"
}

Count the detail times of different users:
hive> select device_id, count(device_id) rank from detail_log group by device_id order by rank desc;

Count the detail times of different apps:
hive> select package_name, count(package_name) rank from detail_log group by package_name order by rank desc;

Save the result into local file system:
hive> insert overwrite local directory '$your_path'
select device_id, count(device_id) rank from download_log group by device_id order by rank desc;

Save the result into HDFS:
hive> insert overwrite directory '$your_path'
select device_id, count(device_id) rank from download_log group by device_id order by rank desc;

Save the result into other table:
hive> insert into table test
select device_id, count(device_id) rank from download_log group by device_id order by rank desc;

2015年11月25日星期三

在Hive中根据Json格式的日志创建用户数据表

PART 1
If your JSON file is not in nested structures, please see this link.Or you can also use the method in part 2.

PART 2
As this method does not support nested structures, there is another way to parse json files: link.

We need to parse the json file in the following format:
{
 "detail_log":
 {
 "from":"",
 "package_name":"com.aggro.wearappmanager",
 "query":""
 },
 "device_id":"2fc35dde39093c78302ed45b287ae81e",
 "message_type":0,
 "remote_ip":"39.169.9.107",
 "time":1446268416,
 "uid":"29737982"
}

As listed in the official document, we can use get_json_object or json_tuple to parse json string.

At first, I wanted to create a app_log table with struct but I cannot keep going to extract json object, keep it unfinished:
hive> create table app_log (detail_log struct<`from`:string, package_name:string, query:string>, device_id string, message_type int, remote_ip string, time bigint, uid string);

Attention: Never load data from HDFS! See link1 and link2.

Below are my steps:
1. hive> create table src_json(json string);
hive> load data local inpath '/home/chenxiaoyu/data/app.log.2015-11-01.1446328474758' into table src_json;
2. hive> create table app_log as select get_json_object(src_json.json, '$.detail_log.from'), get_json_object(src_json.json, '$.detail_log.package_name'), get_json_object(src_json.json, '$.detail_log.query'), get_json_object(src_json.json, '$.device_id'), get_json_object(src_json.json, '$.message_type'), get_json_object(src_json.json, '$.remote_ip'), get_json_object(src_json.json, '$.time'), get_json_object(src_json.json, '$.uid') from src_json;
3. hive> alter table app_log change `_c0` `from` string;
hive> alter table app_log change `_c1` package_name string;
hive> alter table app_log change `_c2` query string;
hive> alter table app_log change `_c3` device_id string;
hive> alter table app_log change `_c4` message_type int;
hive> alter table app_log change `_c5` remote_ip string;
hive> alter table app_log change `_c6` time bigint;
hive> alter table app_log change `_c7` uid string;
done.

Till now the work has been finished, but for step 3, I have something to say.
I wanted to use json_tuple, but it seems that "select json_tuple(src_json.json, 'detail_log.package_name') from src_json;" doesn't work. Only "select json_tuple(src_json.json, 'detail_log') from src_json" works.
So I tried to create another table to save detail_log:
hive> create table src_json2 as select json_tuple(src_json.json, 'detail_log') from src_json;
hive> alter table src_json2 change c0 detail string;
But then "select json_tuple(src_json2.detail, 'from', 'package_name', 'query'), json_tuple(src_json.json, 'device_id', 'message_type', 'remmote_ip', 'time', 'uid') from src_json, src_json2" failed, this error occurs:
Only a single expression in the SELECT clause is supported with UDTF's.
So I don't know how to do with that, keep this unsolved.

PART 3
We encounter this problem: In the same file, we have two different types of JSON as shown below:
{
    "detail_log":
    {
        "from":"",
        "package_name":"com.mapelf",
        "query":""
    },
    "device_id":"897ee392eaec9eeac0e9de069ab3aac5",
    "message_type":0,
    "remote_ip":"120.207.151.129",
    "time":1446268421,
    "uid":"29752894"
}

{
    "device_id":"42f89c8deb5decd55380205cd6decaf6",
    "download_log":
    {
        "apk_url":"http://res.appstore.ticwear.com/net.ddroid.aw.watchface.mv08_5.4.3.apk",
        "appid":911
    },
    "message_type":3,
    "remote_ip":"106.39.192.55",
    "time":1446268426,
    "uid":"29754909"
}

We can use a trick to deal with this case.
As the first JSON has the 'package_name' field and is not NULL and the second JSON has the 'apk_url' field and is not NULL, so we can distinguish between the two of them.
We save the two JSON logs into two tables: detail_log and download_log.

My steps:
If you want to use data in HDFS, try this step 1:
1. hive> create external table src_json(json string) stored as textfile location '<hdfs_location>';
Otherwise you can follow this step 1:
1. hive> create table src_json(json string);
hive> load data local inpath '/home/chenxiaoyu/data/app.log.2015-11-01.1446328474758' into table src_json;
2. hive> create table detail_log as select get_json_object(src_json.json, '$.detail_log.from'), get_json_object(src_json.json, '$.detail_log.package_name'), get_json_object(src_json.json, '$.detail_log.query'), get_json_object(src_json.json, '$.device_id'), get_json_object(src_json.json, '$.message_type'), get_json_object(src_json.json, '$.remote_ip'), get_json_object(src_json.json, '$.time'), get_json_object(src_json.json, '$.uid') from src_json where get_json_object(src_json.json, '$.detail_log.package_name') is not NULL;
3. hive> alter table detail_log change `_c0` `from` string;
hive> alter table detail_log change `_c1` package_name string;
hive> alter table detail_log change `_c2` query string;
hive> alter table detail_log change `_c3` device_id string;
hive> alter table detail_log change `_c4` message_type int;
hive> alter table detail_log change `_c5` remote_ip string;
hive> alter table detail_log change `_c6` time bigint;
hive> alter table detail_log change `_c7` uid string;
4. hive> create table download_log as select get_json_object(src_json.json, '$.device_id'), get_json_object(src_json.json, '$.download_log.apk_url'), get_json_object(src_json.json, '$.download_log.appid'), get_json_object(src_json.json, '$.message_type'), get_json_object(src_json.json, '$.remote_ip'), get_json_object(src_json.json, '$.time'), get_json_object(src_json.json, '$.uid') from src_json where get_json_object(src_json.json, '$.download_log.apk_url') is not NULL;
5. hive> alter table download_log change `_c0` device_id string;
hive> alter table download_log change `_c1` apk_url string;
hive> alter table download_log change `_c2` appid int;
hive> alter table download_log change `_c3` message_type int;
hive> alter table download_log change `_c4` remote_ip string;
hive> alter table download_log change `_c5` time bigint;
hive> alter table download_log change `_c6` uid string;
done.

2015年11月21日星期六

Hive

Install and configure Hive:
Please see this doc.

Hive operations:
Please see this doc.

A video tutorial of Hive: link.