Hiveアーキテクチャ(四)注意事項と拡張特性


Hiveアーキテクチャ(一)アーキテクチャと基本構成Hiveアーキテクチャ(二)Hiveの実行原理、関係型データベースとの比較Hiveアーキテクチャ(三)メタデータベースと基本操作Hiveアーキテクチャ(四)注意事項と拡張特性

1.HIVE使用上の注意点

  • 文字セットHadoopとHiveはUTF-8で符号化されているので、すべての中国語はUTF-8で符号化しなければ正常に使用できません.備考:中国語のデータloadは表の中に入っていて、文字セットが異なると、文字が文字化されている可能性がありますが、hive自体には関数がありません.
  • 圧縮hive.exec.compress.outputというパラメータは、デフォルトではfalseですが、単独で明示的に設定することが多いようです.そうしないと、結果が圧縮されます.このファイルの後ろにhadoopで直接操作する場合は、圧縮できません.
  • count(distinct)現在のHiveでは、クエリ文に複数のDistinctがあることはサポートされていません.Hiveクエリ文でマルチDistinctを実装する場合は、少なくともn+1個のクエリ文(nはdistinctの数)を使用して、前のn個のクエリがそれぞれn個の列に対して除算され、最後のクエリ文がn個の除算後の列に対してJoin操作を行い、最終結果を得る必要がある.
  • JOINは等値接続
  • のみをサポートする.
  • DML動作はINSERT/LOAD動作のみをサポートし、UPDATEおよびDELTE
  • はない.
  • HAVINGはHAVING操作をサポートしていません.この機能が必要な場合、サブクエリをネストするにはwhere制限
  • を使用します.
  • サブクエリHiveはwhere句のサブクエリ
  • をサポートしていません.
  • Joinでnull値を処理する意味区別SQL規格では、nullに対する操作(数値比較、文字列操作など)の結果はnullとなります.Hiveはnull値処理の論理と標準がほぼ一致し,Join時の特殊な論理を除く.ここでの特殊論理とは,HiveのJoinにおいて,Join keyのフィールドと比較してnull=nullが有意義であり,戻り値がtrueであることを意味する.
  • セミコロン文字セミコロンはSQL文終了フラグであり、HiveQLでもあるが、HiveQLではセミコロンの識別にそれほど知恵がない.例えば、
  • select concat(cookie_id,concat(';',’zoo’)) from c02_clickstat_fatdt1 limit 2;
    FAILED: Parse Error: line 0:-1 cannot recognize input '<EOF>' in function specification

    Hiveが文を解析するとき,引用符で含めるかどうかにかかわらず,セミコロンに遭遇すると文が終了すると推測できる.解決策は、セミコロンの8進数のASCIIコードを使用してエスケープすることです.では、上記の文は次のように書きます.
    select concat(cookie_id,concat('\073','zoo')) from c02_clickstat_fatdt1 limit 2;

    なぜ8進ASCIIコードなのですか?16進数のASCIIコードを使ってみましたが、Hiveは文字列処理がエスケープされていないと見なし、8進数しかサポートされていないようです.理由は不明です.この規則は他の非SELECT文にも適用され、CREATE TABLEで区切り記号を定義する必要がある場合、非可視文字を区切り記号にするには8進数のASCIIコードで変換する必要があります.10.Insert構文に従ってInsertは「OVERWRITE」キーを付けなければならない.つまり、挿入するたびに書き換えられる.

    2.Hiveの拡張特性


    Hiveはオープンなシステムで、多くのコンテンツがユーザーカスタマイズをサポートしています.*ファイルフォーマット:Text File,Sequence File*メモリのデータフォーマット:Java Integer/string,Hadoop Intwritable/Text*ユーザーが提供するmap/reduceスクリプト:どんな言語でもstdin/stdoutでデータを転送する*ユーザーカスタマイズ関数:Substr,Trim,1–1*ユーザーカスタマイズ集約関数:Sum,Average......n–1

    2.1データファイル形式


    TextFile
    SequenceFIle
    RCFFile
    Data type
    Text Only
    Text/Binary
    Internal Storage Order
    Row-based
    Row-based
    Compression
    File Based
    Block Based
    Splitable
    YES
    YES
    Splitable After Compression
    No
    YES
    たとえば、作成したテーブルをファイル形式で保存します.
    CREATE TABLE mylog ( user_id BIGINT, page_url STRING, unix_time INT) STORED AS TEXTFILE;

    ユーザのデータファイルフォーマットが現在のHiveで認識されない場合、ファイルフォーマットをカスタマイズできます.contrib/src/java/org/apache/hadoop/hive/contrib/fileformat/base64の例を参照してください.カスタムフォーマットを書き終えたら、テーブルを作成するときに適切なファイルフォーマットを指定します.
    CREATE TABLE base64_test(col1 STRING, col2 STRING) STORED AS INPUTFORMAT 'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.contrib.fileformat.base64.Base64TextOutputFormat';

    2.2 SerDe


    SerDeはSerialize/deserilizeの略称で、シーケンス化と逆シーケンス化を目的としている.シーケンス化されたフォーマットには、セパレータ(tab、カンマ、CTRL-A)、Thriftプロトコルが含まれる.逆シーケンス化(メモリ内):Java Integer/string/ArrayList/HashMap、Hadoop Writableクラス、ユーザーカスタムクラス.ただし、LazyObjectはカラムにアクセスしたときのみ逆シーケンス化されます.BinarySortableは、ソートのバイナリフォーマットを保持します.以下の場合、新しいSerDe:*ユーザのデータを追加することは、現在のHiveではサポートされていないが、ユーザはHiveにデータをロードする前にデータフォーマットを変換したくないという特殊なシーケンス化フォーマットを考慮することができる.*ユーザーは、ディスク・データをより効率的にシーケンス化する方法があります.
    ユーザがTextデータにカスタムSerdeを追加したい場合は、contrib/src/java/org/apache/hadoop/hive/contrib/serde2/RegexSerDe.javaの例を参照してください.RegexSerDeは、ユーザが提供する正規テーブルを用いて、データを逆シーケンス化します.たとえば、次のようになります.
    CREATE TABLE apache_log(
    host STRING,
    identity STRING,
    user STRING,
    time STRING,
    request STRING,
    status STRING,
    size STRING,
    referer STRING,
    agent STRING)
    ROW FORMAT
    SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
    WITH SERDEPROPERTIES
    ( "input.regex" = "([^ ]*) ([^ ]*) ([^ ]*) (-|\\[[^\\]]*\\]) ([^ \"]*|\"[^\"]*\") (-|[0-9]*) (-|[0-9]*)(?: ([^ \"]*|\"[^\"]*\")
    ([^ \"]*|\"[^\"]*\"))?", "output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s";) STORED AS TEXTFILE;

    ユーザがBinaryデータに対してカスタムSerDeを追加したい場合、例serde/src/java/org/apache/hadoop/hive/serde2/binarysortable、例えば、
    CREATE TABLE mythrift_table ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.thrift.ThriftSerDe' WITH SERDEPROPERTIES ( "serialization.class" = "com.facebook.serde.tprofiles.full", "serialization.format" = "com.facebook.thrift.protocol.TBinaryProtocol";);

    2.3 Map/Reduceスクリプト(Transform)


    ユーザーはHiveで使用するMap/Reduceスクリプトをカスタマイズできます.たとえば、次のようになります.
    FROM (
    SELECT TRANSFORM(user_id, page_url, unix_time) USING 'page_url_to_id.py' AS (user_id, page_id, unix_time) FROM mylog DISTRIBUTE BY user_id SORT BY user_id, unix_time) mylog2 SELECT TRANSFORM(user_id, page_id, unix_time) USING 'my_python_session_cutter.py' AS (user_id, session_info);

    Map/Reduceスクリプトはstdin/stdoutでデータの読み書きを行い、デバッグ情報はstderrに出力されます.

    2.4 UDF(User-Defined-Function)


    ユーザーは、次のような関数をカスタマイズしてデータを処理できます.
    add jar build/ql/test/test-udfs.jar;
    CREATE TEMPORARY FUNCTION testlength AS 'org.apache.hadoop.hive.ql.udf.UDFTestLength';
    SELECT testlength(src.value) FROM src;
    DROP TEMPORARY FUNCTION testlength;

    UDFTestLength.JAvaは次のとおりです.
    package org.apache.hadoop.hive.ql.udf;
    
    public class UDFTestLength extends UDF {
      public Integer evaluate(String s) {
        if (s == null) {
          return null;
        }
        return s.length();
      }
    }

    UDFには*javaでUDFを書くのが簡単な機能があります.*HadoopのWritables/Textは高性能です.*UDFはリロードできます.*Hiveは暗黙的なタイプ変換をサポートします.*UDFは、長くなるパラメータをサポートします.*genericUDFは、反射を回避する優れたパフォーマンスを提供します.

    2.5 UDAF(User-Defined Aggregation Funcation)


    例:
    SELECT page_url, count(1), count(DISTINCT user_id) FROM mylog;

    UDAFCount.JAvaコードは次のとおりです.
    public class UDAFCount extends UDAF {
      public static class Evaluator implements UDAFEvaluator {
        private int mCount;
    
        public void init() {
          mcount = 0;
        }
    
        public boolean iterate(Object o) {
          if (o!=null)
            mCount++;
          return true;
        }
    
        public Integer terminatePartial() {
          return mCount;
        }
    
        public boolean merge(Integer o) {
          mCount += o;
          return true;
        }
    
        public Integer terminate() {
          return mCount;
      }
    }