Pig、Hive如何解決自定義輸入輸出分隔符以及Map、Array嵌套分隔符沖突問題

這篇文章主要為大家展示了“Pig、Hive如何解決自定義輸入輸出分隔符以及Map、Array嵌套分隔符沖突問題”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“Pig、Hive如何解決自定義輸入輸出分隔符以及Map、Array嵌套分隔符沖突問題”這篇文章吧。

成都創(chuàng)新互聯(lián)公司主營白水網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,成都APP應(yīng)用開發(fā),白水h5微信小程序搭建,白水網(wǎng)站營銷推廣歡迎白水等地區(qū)企業(yè)咨詢

PIG中輸入輸出分隔符默認(rèn)是制表符\t,而到了hive中,默認(rèn)變成了八進(jìn)制的\001,

也就是ASCII: ctrl - A

Oct   Dec   Hex   ASCII_Char 

001   1       01     SOH (start of heading)

官方的解釋說是盡量不和文中的字符重復(fù),因此選用了 crtrl - A,單個的字符可以通過

row format delimited fields terminated by '#'; 指定,PIG的單個分隔符的也可以通過 PigStorage指定,

但是多個字符做分隔符呢?PIG是直接報錯,而HIVE只認(rèn)第一個字符,而無視后面的多個字符。

解決辦法:

PIG可以自定義加載函數(shù)(load function):繼承LoadFunc,重寫幾個方法就ok了,

詳見:http://my.oschina.net/leejun2005/blog/83825

而在hive中,自定義多分隔符(Multi-character delimiter strings),有2種方法可以實現(xiàn):

1、利用RegexSe:

RegexSerDe是hive自帶的一種序列化/反序列化的方式,主要用來處理正則表達(dá)式。

RegexSerDe主要下面三個參數(shù):
input.regex
output.format.string
input.regex.case.insensitive

下面給出一個完整的范例:

add jar /home/june/hadoop/hive-0.8.1-bin/lib/hive_contrib.jar;
CREATE TABLE b(
c0 string,
c1 string,
c2 string)
ROW FORMAT
SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES
( 'input.regex' = '([^,]*),,,,([^,]*),,,,([^,]*)',
'output.format.string' = '%1$s %2$s %3$s')
STORED AS TEXTFILE;

cat b.txt
1,,,,2,,,,3
a,,,,b,,,,c
9,,,,5,,,,7
load data local inpath 'b.txt' overwrite into table b;
select * from b

REF:

http://www.oratea.net/?p=652

http://grokbase.com/t/hive/user/115sw9ant2/hive-create-table

2、重寫相應(yīng)的  InputFormat和OutputFormat方法:

//使用多字符來分隔字段,則需要你自定義InputFormat來實現(xiàn)。

package org.apache.hadoop.mapred;

import java.io.IOException;

import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.FileSplit;
import org.apache.hadoop.mapred.InputSplit;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.LineRecordReader;
import org.apache.hadoop.mapred.RecordReader;
import org.apache.hadoop.mapred.Reporter;
import org.apache.hadoop.mapred.TextInputFormat;

public class MyDemoInputFormat extends TextInputFormat {

    @Override
    public RecordReader<LongWritable, Text> getRecordReader(
            InputSplit genericSplit, JobConf job, Reporter reporter)
            throws IOException {
        reporter.setStatus(genericSplit.toString());
        MyDemoRecordReader reader = new MyDemoRecordReader(
                new LineRecordReader(job, (FileSplit) genericSplit));
        return reader;
    }

    public static class MyDemoRecordReader implements
            RecordReader<LongWritable, Text> {

        LineRecordReader reader;
        Text text;

        public MyDemoRecordReader(LineRecordReader reader) {
            this.reader = reader;
            text = reader.createValue();
        }

        @Override
        public void close() throws IOException {
            reader.close();
        }

        @Override
        public LongWritable createKey() {
            return reader.createKey();
        }

        @Override
        public Text createValue() {
            return new Text();
        }

        @Override
        public long getPos() throws IOException {
            return reader.getPos();
        }

        @Override
        public float getProgress() throws IOException {
            return reader.getProgress();
        }

        @Override
        public boolean next(LongWritable key, Text value) throws IOException {
            Text txtReplace;
            while (reader.next(key, text)) {
                txtReplace = new Text();
                txtReplace.set(text.toString().toLowerCase().replaceAll("\\|\\|\\|", "\001"));
                value.set(txtReplace.getBytes(), 0, txtReplace.getLength());
                return true;

            }
            return false;
        }
    }
}
//這時候的建表語句是:

create external table IF NOT EXISTS  test(
id string,
name string
)partitioned by (day string) 
STORED AS INPUTFORMAT  
  'org.apache.hadoop.mapred.MyDemoInputFormat'  
OUTPUTFORMAT  
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION '/log/dw_srclog/test';

采集日志到Hive  http://blog.javachen.com/2014/07/25/collect-log-to-hive/

參考:

hive處理日志,自定義inputformat

http://running.iteye.com/blog/907806

http://superlxw1234.iteye.com/blog/1744970

原理很簡單:hive 的內(nèi)部分隔符是“ \001 ”,只要把分隔符替換成“\001 ”即可。

3、順便提下如何定制hive中NULL的輸出,默認(rèn)在存儲時被轉(zhuǎn)義輸出為\N,

如果我們需要修改成自定義的,例如為空,同樣我們也要利用正則序列化:

hive> CREATE TABLE sunwg02 (id int,name STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
'field.delim'='\t',
'escape.delim'='\\',
'serialization.null.format'='
) STORED AS TEXTFILE;
OK
Time taken: 0.046 seconds

hive> insert overwrite table sunwg02 select * from sunwg00;
Loading data to table sunwg02
2 Rows loaded to sunwg02
OK
Time taken: 18.756 seconds

查看sunwg02在hdfs的文件
[hjl@sunwg src]$ hadoop fs -cat /hjl/sunwg02/attempt_201105020924_0013_m_000000_0
mary
101 tom

NULL值沒有被轉(zhuǎn)寫成’\N’

PS:

其實話說回來這個功能很簡單,但不知為何作者沒有直接支持,或許未來的版本會支持的。

4、Hive Map、Array嵌套分隔符沖突問題

1|JOHN|abu1/abu21|key1:1'\004'2'\004'3/key12:6'\004'7'\004'8
2|Rain|abu2/abu22|key2:2'\004'2'\004'3/key22:6'\004'7'\004'8
3|Lisa|abu3/abu23|key3:3'\004'2'\004'3/key32:6'\004'7'\004'8

Pig、Hive如何解決自定義輸入輸出分隔符以及Map、Array嵌套分隔符沖突問題

針對上述文件可以看到, 紫色方框里的都是 array,但是為了避免 array 和 map嵌套array 里的分隔符沖突,

采用了不同的分隔符,一個是 / , 一個是 \004,為什么要用 \004 呢?

因為 hive 默認(rèn)支持 8 級分隔符:\001~\008,用戶只能重寫覆蓋 \001~\003,其它級別的分隔符 hive 會自己識別解析。

所以以本例來看,建表語句如下:

create EXTERNAL table IF NOT EXISTS testSeparator(
    id string, 
    name string,
    itemList array<String>,
    kvMap map<string, array<int>>
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '|'
COLLECTION ITEMS TERMINATED BY '/'
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\n'
LOCATION '/tmp/dsap/rawdata/ooxx/3';

hive 結(jié)果如下:

Pig、Hive如何解決自定義輸入輸出分隔符以及Map、Array嵌套分隔符沖突問題

以上是“Pig、Hive如何解決自定義輸入輸出分隔符以及Map、Array嵌套分隔符沖突問題”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

文章題目:Pig、Hive如何解決自定義輸入輸出分隔符以及Map、Array嵌套分隔符沖突問題
文章起源:http://bm7419.com/article8/igicip.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、、網(wǎng)站營銷、網(wǎng)站改版、小程序開發(fā)、網(wǎng)站設(shè)計

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

微信小程序開發(fā)