Azure HDInsight での Apache Hive クエリの最適化Optimize Apache Hive queries in Azure HDInsight

この記事では、Apache Hive クエリのパフォーマンスを向上させるために使用できる、最も一般的なパフォーマンスの最適化について説明します。This article describes some of the most common performance optimizations that you can use to improve the performance of your Apache Hive queries.

クラスターの種類の選択Cluster type selection

Azure HDInsight では、いくつかの異なるクラスター タイプに対して、Apache Hive クエリを実行できます。In Azure HDInsight, you can run Apache Hive queries on a few different cluster types.

ワークロードのニーズに合わせてパフォーマンスを最適化するには、次のように適切なクラスター タイプを選択します。Choose the appropriate cluster type to help optimize performance for your workload needs:

  • ad hoc 対話型クエリ用に最適化するには、 Interactive Query クラスター タイプを選択します。Choose Interactive Query cluster type to optimize for ad hoc, interactive queries.
  • バッチ処理として使用される Hive クエリ用に最適化するには、Apache Hadoop クラスター タイプを選択します。Choose Apache Hadoop cluster type to optimize for Hive queries used as a batch process.
  • Spark および HBase クラスター タイプでも、Hive クエリを実行でき、これらのワークロードを実行している場合は、適切な場合があります。Spark and HBase cluster types can also run Hive queries, and might be appropriate if you are running those workloads.

Hive クエリを実行するための各種 HDInsight クラスター タイプについて詳しくは、「Azure HDInsight における Apache Hive と HiveQL」をご覧ください。For more information on running Hive queries on various HDInsight cluster types, see What is Apache Hive and HiveQL on Azure HDInsight?.

ワーカー ノードのスケール アウトScale out worker nodes

HDInsight クラスター内のワーカー ノードの数を増やすと、並列に実行される mapper や reducer を作業でより多く使用できるようになります。Increasing the number of worker nodes in an HDInsight cluster allows the work to use more mappers and reducers to be run in parallel. HDInsight でのスケール アウトを向上させる方法が 2 つあります。There are two ways you can increase scale out in HDInsight:

  • クラスターを作成する場合は、Azure portal、Azure PowerShell、またはコマンド ライン インターフェイスを使用してワーカー ノードの数を指定できます。When you create a cluster, you can specify the number of worker nodes using the Azure portal, Azure PowerShell, or command-line interface. 詳細については、HDInsight クラスターの作成に関するページを参照してください。For more information, see Create HDInsight clusters. 次のスクリーンショットは、Azure Portal 上に表示されたワーカー ノード構成を示しています。The following screenshot shows the worker node configuration on the Azure portal:

    Azure portal のクラスター サイズ ノードAzure portal cluster size nodes

  • 作成後にワーカー ノードの数を編集して、クラスターを再作成せずにスケールアウトすることもできます。After creation, you can also edit the number of worker nodes to scale out a cluster further without recreating one:

    Azure portal のスケール クラスター サイズAzure portal scale cluster size

HDInsight のスケーリングについて詳しくは、HDInsight クラスターのスケーリングに関するページをご覧くださいFor more information about scaling HDInsight, see Scale HDInsight clusters

Map Reduce の代わりに Apache Tez を使用するUse Apache Tez instead of Map Reduce

Apache Tez は、MapReduce エンジンに代わる実行エンジンです。Apache Tez is an alternative execution engine to the MapReduce engine. Linux ベースの HDInsight クラスターでは、Tez は既定で有効になっています。Linux-based HDInsight clusters have Tez enabled by default.

HDInsight Apache Tez の概要図

Tez はより高速です。それは次の理由によります。Tez is faster because:

  • MapReduce エンジンで、有向非巡回グラフ (DAG) を 1 つのジョブとして実行しますExecute Directed Acyclic Graph (DAG) as a single job in the MapReduce engine. DAG では、mapper の各セットの後に 1 セットの reducer が続く必要があります。The DAG requires each set of mappers to be followed by one set of reducers. この要件により、Hive クエリごとに複数の MapReduce ジョブがスピンオフされます。This requirement causes multiple MapReduce jobs to be spun off for each Hive query. Tez にはこのような制約がなく、複雑な DAG を 1 つのジョブとして処理できるため、ジョブ起動のオーバーヘッドが最小限に抑えられます。Tez doesn't have such constraint and can process complex DAG as one job minimizing job startup overhead.
  • 不要な書き込みを回避できますAvoids unnecessary writes. MapReduce エンジンでは、同じ Hive クエリを 処理するために複数のジョブが使用されます。Multiple jobs are used to process the same Hive query in the MapReduce engine. 各 MapReduce ジョブの出力は、中間データとして HDFS に書き込まれます。The output of each MapReduce job is written to HDFS for intermediate data. Tez によって各 Hive クエリのジョブの数が最小限に抑えられるので、不要な書き込みを回避することができます。Since Tez minimizes number of jobs for each Hive query, it's able to avoid unnecessary writes.
  • 起動時の遅延を最小限に抑えられますMinimizes start-up delays. Tez は、開始に必要な mapper の数を削減することによって、また全体的な最適化を向上させることによって、起動時の遅延を最小限に抑えることができます。Tez is better able to minimize start-up delay by reducing the number of mappers it needs to start and also improving optimization throughout.
  • コンテナーを再利用できますReuses containers. コンテナーの起動からの待ち時間が確実に削減されるように、Tez では可能なときは常にコンテナーを再利用します。Whenever possible Tez will reuse containers to ensure that latency from starting up containers is reduced.
  • 継続的な最適化手法を使用しますContinuous optimization techniques. これまで、最適化はコンパイル フェーズで行われていました。Traditionally optimization was done during compilation phase. しかし最適化を向上させるための入力に関する詳細は、実行時に入手できます。However more information about the inputs is available that allow for better optimization during runtime. Tez は、実行時フェーズでプランをさらに最適化する継続的な最適化手法を使用します。Tez uses continuous optimization techniques that allow it to optimize the plan further into the runtime phase.

この概念の詳細については、Apache TEZ のサイトを参照してください。For more information on these concepts, see Apache TEZ.

次の set コマンドでクエリにプレフィックスを付けることで、Hive クエリで Tez を有効にできます。You can make any Hive query Tez enabled by prefixing the query with the following set command:

set hive.execution.engine=tez;

Hive パーティション分割Hive partitioning

I/O 操作は、Hive クエリを実行するための主なパフォーマンスのボトルネックです。I/O operations are the major performance bottleneck for running Hive queries. 読み取る必要があるデータの量を削減することで、パフォーマンスを向上することができます。The performance can be improved if the amount of data that needs to be read can be reduced. 既定では、Hive クエリは、全 Hive テーブルをスキャンします。By default, Hive queries scan entire Hive tables. 少量のデータのみのスキャンが必要なクエリ (フィルターを使用するクエリなど) では、不要なオーバーヘッドが発生します。However for queries that only need to scan a small amount of data (for example, queries with filtering), this behavior creates unnecessary overhead. Hive パーティション分割では、Hive クエリは Hive テーブルの必要な量のデータだけにアクセスします。Hive partitioning allows Hive queries to access only the necessary amount of data in Hive tables.

Hive パーティション分割は、生データを新しいディレクトリに再編成することによって実装されます。Hive partitioning is implemented by reorganizing the raw data into new directories. 各パーティションには、独自のファイル ディレクトリが編成されます。Each partition has its own file directory. パーティション分割はユーザーによって定義されます。The partitioning is defined by the user. 次の図は、列 Year による Hive テーブルのパーティション分割を示しています。The following diagram illustrates partitioning a Hive table by the column Year. 年ごとに新しいディレクトリが作成されます。A new directory is created for each year.

HDInsight Apache Hive のパーティション分割

パーティション分割に関するいくつかの考慮事項:Some partitioning considerations:

  • パーティションの数を少なくしすぎない - 少数の値しかない列をパーティション分割すると、パーティションの数が少なくなる場合があります。Don't under partition - Partitioning on columns with only a few values can cause few partitions. たとえば、性別をパーティション分割すると 2 つのパーティション (男性と女性) しか作成されないため、待ち時間は最大で半分しか短縮されません。For example, partitioning on gender only creates two partitions to be created (male and female), so reduce the latency by a maximum of half.
  • パーティションの数を多くしすぎない - もう一方の極端な例として、一意の値 (userid など) を含む列でパーティションを作成すると、複数のパーティションが生成されます。Don't over partition - On the other extreme, creating a partition on a column with a unique value (for example, userid) causes multiple partitions. これでは、多数のディレクトリを処理する必要があるため、クラスター namenode に多大なストレスを与えることになります。Over partition causes much stress on the cluster namenode as it has to handle the large number of directories.
  • データのスキューを回避する - すべてのパーティションのサイズが均等になるよう、注意深くパーティショニング キーを選択します。Avoid data skew - Choose your partitioning key wisely so that all partitions are even size. たとえば、 State 列をパーティション分割すると、データの分布が偏る可能性があります。For example, partitioning on State column may skew the distribution of data. カリフォルニア州の人口はバーモント州の約 30 倍なので、パーティションのサイズが偏り、パフォーマンスの差が大きくなる可能性があります。Since the state of California has a population almost 30x that of Vermont, the partition size is potentially skewed and performance may vary tremendously.

パーティション テーブルを作成するには、 Partitioned By 句を使用します。To create a partition table, use the Partitioned By clause:

CREATE TABLE lineitem_part
      (L_ORDERKEY INT, L_PARTKEY INT, L_SUPPKEY INT,L_LINENUMBER INT,
      L_QUANTITY DOUBLE, L_EXTENDEDPRICE DOUBLE, L_DISCOUNT DOUBLE,
      L_TAX DOUBLE, L_RETURNFLAG STRING, L_LINESTATUS STRING,
      L_SHIPDATE_PS STRING, L_COMMITDATE STRING, L_RECEIPTDATE STRING,
      L_SHIPINSTRUCT STRING, L_SHIPMODE STRING, L_COMMENT STRING)
PARTITIONED BY(L_SHIPDATE STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE;

パーティション テーブルが作成されれば、静的パーティションまたは動的パーティションのいずれかを作成できるようになります。Once the partitioned table is created, you can either create static partitioning or dynamic partitioning.

  • 静的パーティション分割 とは、データを適切なディレクトリに既にシャード化していることを意味します。Static partitioning means that you have already sharded data in the appropriate directories. 静的パーティションでは、ディレクトリの場所に基づいて Hive パーティションを手動で追加します。With static partitions, you add Hive partitions manually based on the directory location. 次のコード スニペットに例を示します。The following code snippet is an example.

    INSERT OVERWRITE TABLE lineitem_part
    PARTITION (L_SHIPDATE = '5/23/1996 12:00:00 AM')
    SELECT * FROM lineitem
    WHERE lineitem.L_SHIPDATE = '5/23/1996 12:00:00 AM'
    
    ALTER TABLE lineitem_part ADD PARTITION (L_SHIPDATE = '5/23/1996 12:00:00 AM')
    LOCATION 'wasb://sampledata@ignitedemo.blob.core.windows.net/partitions/5_23_1996/'
    
  • 動的パーティション分割 では、Hive に自動的にパーティションを作成させます。Dynamic partitioning means that you want Hive to create partitions automatically for you. ステージング テーブルからパーティショニング テーブルを既に作成しているので、あとはパーティション テーブルにデータを挿入するだけです。Since you've already created the partitioning table from the staging table, all you need to do is insert data to the partitioned table:

    SET hive.exec.dynamic.partition = true;
    SET hive.exec.dynamic.partition.mode = nonstrict;
    INSERT INTO TABLE lineitem_part
    PARTITION (L_SHIPDATE)
    SELECT L_ORDERKEY as L_ORDERKEY, L_PARTKEY as L_PARTKEY,
         L_SUPPKEY as L_SUPPKEY, L_LINENUMBER as L_LINENUMBER,
         L_QUANTITY as L_QUANTITY, L_EXTENDEDPRICE as L_EXTENDEDPRICE,
         L_DISCOUNT as L_DISCOUNT, L_TAX as L_TAX, L_RETURNFLAG as L_RETURNFLAG,
         L_LINESTATUS as L_LINESTATUS, L_SHIPDATE as L_SHIPDATE_PS,
         L_COMMITDATE as L_COMMITDATE, L_RECEIPTDATE as L_RECEIPTDATE,
         L_SHIPINSTRUCT as L_SHIPINSTRUCT, L_SHIPMODE as L_SHIPMODE,
         L_COMMENT as L_COMMENT, L_SHIPDATE as L_SHIPDATE FROM lineitem;
    

詳細については、「Partitioned Tables (パーティション テーブル)」を参照してください。For more information, see Partitioned Tables.

ORCFile 形式の使用Use the ORCFile format

Hive は、さまざまなファイル形式をサポートしています。Hive supports different file formats. 次に例を示します。For example:

  • テキスト : 既定のファイル形式で、ほとんどのシナリオで使用できます。Text : the default file format and works with most scenarios.
  • Avro : 相互運用性シナリオで使用できます。Avro : works well for interoperability scenarios.
  • ORC/Parquet : 最も高いパフォーマンスを発揮します。ORC/Parquet : best suited for performance.

ORC (最適化行多桁式) 形式は、Hive データを格納する非常に効率的な方法です。ORC (Optimized Row Columnar) format is a highly efficient way to store Hive data. 他の形式と比べて、ORC には次の利点があります。Compared to other formats, ORC has the following advantages:

  • 複合型 (DateTime、複合構造化型、および半構造化型を含む) のサポート。support for complex types including DateTime and complex and semi-structured types.
  • 最大で 70% の圧縮。up to 70% compression.
  • 10,000 行ごとのインデックス作成 (これにより行のスキップが可能)。indexes every 10,000 rows, which allow skipping rows.
  • 実行時の実行の大幅な削除。a significant drop in run-time execution.

ORC 形式を有効にするにはまず、 Stored as ORC 句でテーブルを作成します。To enable ORC format, you first create a table with the clause Stored as ORC :

CREATE TABLE lineitem_orc_part
      (L_ORDERKEY INT, L_PARTKEY INT,L_SUPPKEY INT, L_LINENUMBER INT,
      L_QUANTITY DOUBLE, L_EXTENDEDPRICE DOUBLE, L_DISCOUNT DOUBLE,
      L_TAX DOUBLE, L_RETURNFLAG STRING, L_LINESTATUS STRING,
      L_SHIPDATE_PS STRING, L_COMMITDATE STRING, L_RECEIPTDATE STRING,
      L_SHIPINSTRUCT STRING, L_SHIPMODE STRING, L_COMMENT      STRING)
PARTITIONED BY(L_SHIPDATE STRING)
STORED AS ORC;

次に、データをステージング テーブルから ORC テーブルに挿入します。Next, you insert data to the ORC table from the staging table. 次に例を示します。For example:

INSERT INTO TABLE lineitem_orc
SELECT L_ORDERKEY as L_ORDERKEY,
         L_PARTKEY as L_PARTKEY ,
         L_SUPPKEY as L_SUPPKEY,
         L_LINENUMBER as L_LINENUMBER,
         L_QUANTITY as L_QUANTITY,
         L_EXTENDEDPRICE as L_EXTENDEDPRICE,
         L_DISCOUNT as L_DISCOUNT,
         L_TAX as L_TAX,
         L_RETURNFLAG as L_RETURNFLAG,
         L_LINESTATUS as L_LINESTATUS,
         L_SHIPDATE as L_SHIPDATE,
         L_COMMITDATE as L_COMMITDATE,
         L_RECEIPTDATE as L_RECEIPTDATE,
         L_SHIPINSTRUCT as L_SHIPINSTRUCT,
         L_SHIPMODE as L_SHIPMODE,
         L_COMMENT as L_COMMENT
FROM lineitem;

ORC 形式の詳細については、Apache Hive 言語マニュアルで説明されています。You can read more on the ORC format in the Apache Hive Language manual.

ベクター化Vectorization

ベクター化により、Hive は、一度に 1 行を処理する代わりに、1024 行を一括処理することができます。Vectorization allows Hive to process a batch of 1024 rows together instead of processing one row at a time. つまり、単純な操作では、実行に必要な内部コードが少なくなるため、処理が速くなります。It means that simple operations are done faster because less internal code needs to run.

Hive クエリのベクター化プレフィックスを有効にするには、次の設定を使用します。To enable vectorization prefix your Hive query with the following setting:

set hive.vectorized.execution.enabled = true;

詳細については、「Vectorized query execution (ベクター化されたクエリ実行)」を参照してください。For more information, see Vectorized query execution.

その他の最適化の方法Other optimization methods

その他にも考慮できる最適化の方法がいくつかあります。たとえば、次のような方法です。There are more optimization methods that you can consider, for example:

  • Hive のバケット: 大きなデータ セットをクラスター化またはセグメント化してクエリのパフォーマンスを最適化するための手法です。Hive bucketing: a technique that allows to cluster or segment large sets of data to optimize query performance.
  • 結合の最適化: 結合の効率を向上させユーザー ヒントの必要性を少なくするための Hive のクエリ実行プランの最適化です。Join optimization: optimization of Hive's query execution planning to improve the efficiency of joins and reduce the need for user hints. 詳しくは、「Join optimization (結合の最適化)」を参照してください。For more information, see Join optimization.
  • Reducer の増加Increase Reducers.

次のステップNext steps

この記事ではいくつかの一般的な Hive クエリの最適化方法を説明しました。In this article, you have learned several common Hive query optimization methods. 詳細については、以下の記事をお読みください。To learn more, see the following articles: