溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時(shí)間:2021-12-10 10:17:17 來源:億速云 閱讀:298 作者:小新 欄目:云計(jì)算

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

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,單個(gè)的字符可以通過

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

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

解決辦法:

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

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

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

1、利用RegexSe:

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

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

下面給出一個(gè)完整的范例:

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來實(shí)現(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;
        }
    }
}
//這時(shí)候的建表語句是:

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)在存儲(chǔ)時(shí)被轉(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:

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

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 里的分隔符沖突,

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

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

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

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í)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI