スタンドアロンで数万の QPS! Apache Doris の高同時実行機能の解釈

66d953140f4e037c020c5c08b776011f.png300万語!ネットワーク全体で最も完全なビッグデータ学習インタビュー コミュニティがあなたを待っています!

2df205ff2932da85b7216963b6b47787.gif

e0c361cb380c2635a3ab965a52af0ba5.png

ユーザー規模の急速な拡大に伴い、企業内で統合分析基盤を構築するためにApache Dorisを利用するユーザーが増えている一方で、Apache Dorisには大規模なビジネスを含むより大きなビジネス規模の処理や分析を行うことが求められています。一方で、これまでの統計レポート、アドホッククエリ、インタラクティブ分析などの典型的なOLAPシナリオから、レコメンデーション、リスクコントロールなど、より多くのビジネスシーンへの拡大など、企業のより多様なデータ分析需要に応える必要があることも意味しています。 、タグ ポートレート、IoT、データ サービス (Data Serving) は代表的な要件の 1 つです。

データ サービスとは通常、ユーザーまたは企業顧客にデータ アクセス サービスを提供することを指します。ユーザーがより頻繁に使用するクエリ モードは、キーに従って 1 つ以上のデータ行をクエリすることです。次に例を示します。

  • 注文内容照会

  • 商品詳細のお問い合わせ

  • 物流状況照会

  • お取引内容照会

  • ユーザー情報の問い合わせ

  • ユーザーのポートレート属性のクエリ

  • ...

大規模なデータのスキャンと計算を目的としたアドホックとは異なり、データ サービングは通常、実際のビジネスでは同時実行ポイントの高いクエリとして表されます。クエリによって返されるデータの量は少なく、通常は 1 行または少数のデータのみです。のデータ行が返されますが、クエリを使用するため、時間に非常に敏感で、ミリ秒以内にクエリ結果を返すことが期待されており、超高同時実行性という課題に直面しています。

以前は、このようなビジネス要件に直面した場合、通常、対応するクエリ アクセスを実行するためにさまざまなシステム コンポーネントが使用されていました。OLAP データベースは通常、列指向ストレージ エンジンに基づいて構築されており、ビッグ データ シナリオ向けに設計されたクエリ フレームワークです。システム機能は通常、データ スループットによって測定されます。そのため、データ サービングの同時実行性の高いポイントクエリ シナリオのパフォーマンスは、多くの場合それほど良くありません。ユーザーの期待として。これに基づいて、ユーザーは通常、ポイント クエリを処理するために Apache HBase などの KV システムを導入し、高い同時実行性によって引き起こされるシステムの負荷を共有するためにキャッシュ レイヤーとして Redis を導入します。ただし、このようなアーキテクチャは複雑であることが多く、ストレージの冗長化やメンテナンスコストの高さといった問題があります。

統合分析パラダイムの統合により、Apache Doris が実行できるワークロードに課題が生じました。また、このようなシナリオでユーザーのビジネス ニーズをより適切に満たす方法について、より体系的に考えることができるようになりました。上記の考慮事項に基づいて、次期バージョン 2.0 では、オリジナルの機能に基づいた一連のポイント指向のクエリ最適化手法を導入し、単一ノードで数万 QPS の超高同時実行に達することができ、大幅に拡張されます。適用可能なシナリオの能力境界。

# 同時実行クエリ数が多い場合はどのように対処すればよいでしょうか?

高い同時実行性は、常に Apache Doris の利点の 1 つです。同時実行性の高いクエリの場合、中核となるのは、限られたシステム リソースの消費と同時実行によって生じる高負荷のバランスをとる方法です。つまり、単一の SQL 実行時の CPU、メモリ、IO のオーバーヘッドを最小限に抑える必要があります。重要なのは、基になるデータのスキャンとその後のデータ計算を減らすことにあります。主な最適化方法は次のとおりです。

   パーティションバケットのプルーニング

Apache Doris は 2 レベルのパーティション分割を採用しており、最初のレベルはパーティションであり、通常は時間をパーティション キーとして使用できます。2 番目のレベルはバケットで、読み取りの並列性を向上させ、読み取りスループットをさらに向上させるために、ハッシュを通じてデータを各ノードに分散します。バケットを合理的に分割することでクエリのパフォーマンスを向上させることができます。例として次のクエリ ステートメントを取り上げます。

select * from user_table where id = 5122 and create_date = '2022-01-01'

ユーザーはcreate_time、ID をパーティションキーとして、ID をバケットキーとして使用し、10 個のバケットを設定し、パーティション分割とバケット化を行った後、不要なパーティションデータをすばやくフィルタリングし、最後に少量のデータのみを読み込むだけで済みます。 1 つのパーティションの 1 つのバケットなど、バケットはクエリ結果をすばやく見つけて、スキャンされるデータの量と 1 つのクエリの遅延を最小限に抑えることができます。

   索引

Doris は、パーティショニング、バケット化、プルーニングに加えて、データの読み取りとフィルタリングを高速化するための豊富なインデックス構造も提供します。インデックスの種類はスマート インデックスとセカンダリ インデックスに大別され、スマート インデックスは Doris データの書き込み時にユーザーの介入なしに自動的に生成されます。

スマート インデックスには、プレフィックス インデックスとゾーンマップ インデックスが含まれます。

  • 接頭辞スパース インデックス (ソートされたインデックス) は、ソートされた構造に基づいて構築されたインデックスです。Doris によってファイルに保存されたデータは、ソート列に従って順番に保存され、Doris はソートされたデータに対して 1024 行ごとにスパース インデックス アイテムを作成します。インデックスのキーは、現在の 1024 行の最初の行のプレフィックス ソート列の値です。ユーザーのクエリ条件にこれらのソート列が含まれる場合、プレフィックス スパース インデックスを通じて開始行をすぐに見つけることができます。

  • ZoneMap インデックスは、セグメント レベルとページ レベルで構築されるインデックスです。ページ内の各列の最大値と最小値が記録され、同様にセグメントレベルでも各列の最大値と最小値が記録されます。このようにして、同等のクエリまたは範囲クエリを実行するときに、MinMax インデックスを使用して、読み取る必要のない行を迅速に除外できます。

セカンダリ インデックスは、ブルーム フィルター インデックス、ビットマップ インデックス、バージョン 2.0 で新しく追加された反転反転インデックスと NGram ブルーム フィルター インデックスなど、手動で作成する必要があるインデックスです。ここでは詳しく説明しませんが、次のことを学ぶことができます。最初に公式ウェブサイトのドキュメントからそれを参照し、その後に解釈のための一連の記事があります。

公式ウェブサイトのドキュメント:

  • 逆索引: https://dris.apache.org/zh-CN/docs/dev/data-table/index/inverted-index

  • NGram BloomFilter インデックス: https://dris.apache.org/zh-CN/docs/dev/data-table/index/ngram-bloomfilter-index

例として次のクエリを考えてみましょう。

 
  
select * from user_table where id > 10 and id < 1024

テーブル作成時に指定したキーとしてIDを指定すると、MemtableとディスクがIDに従って整然と整理され、クエリ時にフィルター条件にプレフィックスフィールドが含まれる場合、プレフィックスインデックスを使用できます素早くフィルタリングします。主要なクエリ条件はストレージ層で複数の Range に分割され、プレフィックス インデックスに従って二分探索が実行され、対応する行番号の範囲が取得されますが、プレフィックス インデックスはスパースであるため、大まかな移動範囲しか特定できません。次に、ZoneMap、Bloom Filter、Bitmap などのインデックスを使用して、スキャンする必要がある行の数をさらに減らします。インデックス作成により、スキャンする必要がある行の数が大幅に減り、CPU と IO への負荷が軽減され、システム全体の同時実行能力が大幅に向上します。

   マテリアライズドビュー

マテリアライズド ビューは、空間を時間に交換するという典型的なアイデアであり、その本質は、事前定義された SQL 分析ステートメントに基づいて事前計算を実行し、計算結果をユーザーには透過的だが実際のストレージを持つ別のテーブルに永続化することです。集計データと詳細データを同時にクエリする必要があり、異なるプレフィックス インデックスを照合する必要があるシナリオでは、マテリアライズド ビューに到達したときにより高速なクエリ応答を取得でき、オンサイトで大量の計算を実行できます。回避できるため、パフォーマンスが向上し、リソースの消費が削減されます

// 对于聚合操作, 直接读物化视图预聚合的列
create materialized view store_amt as select store_id, sum(sale_amt) from sales_records group by store_id;
SELECT store_id, sum(sale_amt) FROM sales_records GROUP BY store_id;

// 对于查询, k3满足物化视图前缀列条件, 走物化视图加速查询
CREATE MATERIALIZED VIEW mv_1 as SELECT k3, k2, k1 FROM tableA ORDER BY k3;
select k1, k2, k3 from table A where k3=3;

   ランタイムフィルター

クエリ データのフィルタリングを高速化するための上記のインデックスに加えて、Doris は動的フィルタリング メカニズム、つまりランタイム フィルタも追加しました。マルチテーブル関連付けクエリでは、通常、右側のテーブルを BuildTable、左側のテーブルを ProbeTable と呼びますが、左側のテーブルのデータ量は右側のテーブルのデータ量よりも多くなります。実装に関しては、最初に右のテーブルのデータが読み取られ、メモリ上に HashTable (Build) が構築されます。次に、左側のテーブルの各行のデータの読み取りを開始し、HashTable で接続マッチングを実行して、接続条件を満たすデータ (プローブ) を返します。ランタイム フィルターは、右側のテーブルでハッシュ テーブルを構築する際に、接続列のフィルター構造を生成します。これには、最小/最大、IN、その他のフィルター条件を指定できます。次に、フィルター列構造を左側のテーブルにプッシュダウンします。このようにして、左側のテーブルはこのフィルタリング構造を使用してデータをフィルタリングすることができるため、プローブ ノードが送信および比較する必要があるデータの量が削減されます。ほとんどの結合シナリオでは、ランタイム フィルターは自動ノード ペネトレーションを実現し、フィルター ペネトレーションを最下位のスキャン ノードまたは分散シャッフル結合にプッシュ ダウンできます。

関連するクエリ ランタイム フィルターのほとんどは、データ読み取りの影響を大幅に軽減できるため、クエリ全体が高速化されます。

   TOPN最適化テクノロジー

特定の条件が満たされた場合に最後の 100 個のデータをクエリする、複数の商品の最高または最低価格をクエリするなど、データベース内の最大または最小のデータをクエリするための幅広いアプリケーション シナリオがあります。パフォーマンスこのようなクエリをどのように分析するかは、リアルタイム分析にとって非常に重要です。TOPN 最適化は、ビッグ データ シナリオにおける高い IO、CPU、メモリ リソースの消費を解決するために Doris に導入されました。

  • まず、スキャナー層からソートフィールドとクエリフィールドを読み取り、ヒープソートを使用して TOPN 個のデータを保持し、現在既知の最大または最小のデータ範囲をリアルタイムで更新し、動的にスキャナーにプッシュダウンします。

  • スキャナー層はインデックスを使用して、範囲条件に応じてファイルとデータ ブロックのスキップを高速化し、読み取られるデータ量を大幅に削減します。

  • 幅の広いテーブルでは、ユーザーは通常、多数のフィールドをクエリする必要があります。TOPN シナリオでは、実際に有効なデータは N 個だけです。読み取りを 2 つの段階に分割することで、最初の段階では少数のフィールドに基づいて行番号を見つけます。列と条件列のソートとソートの第 2 段階では、ソートと TOPN の結果に従って、行番号逆引きクエリ データを取得でき、スキャンのオーバーヘッドを大幅に削減できます。

上記の一連の最適化手法により、不要なデータを削除し、読み取ってソートするデータ量を削減し、システム IO、CPU、メモリ リソースの消費を大幅に削減できますさらに、SQL キャッシュ、パーティション キャッシュ、結合の最適化メソッドなどのキャッシュ メカニズムを使用して同時実行性をさらに向上させることもできますが、スペースの都合上、ここでは詳しく説明しません。

# Apache Doris 2.0 の新機能が明らかに

前の段落で紹介した内容を通じて、Apache Doris は単一ノード上で数千の QPS の同時サポートを実現しました。ただし、超高同時実行要件 (数万 QPS など) を伴う一部のデータ サービス シナリオでは、依然としてボトルネックが存在します。

  • 列指向ストレージ エンジンは行レベルのデータの読み取りには適しておらず、ワイド テーブル モデルの列指向ストレージ形式はランダム読み取り IO を大幅に増幅します。

  • OLAP データベースの実行エンジンとクエリ オプティマイザーは、一部の単純なクエリ (ポイント クエリなど) には重すぎるため、そのようなクエリを処理するにはクエリ プランニングで短いパスを計画する必要があります。

  • SQL リクエストへのアクセスとクエリ プランの解析と生成は、Java 言語を使用する FE モジュールによって処理されます。同時実行性の高いシナリオで多数のクエリ実行プランを解析して生成すると、CPU オーバーヘッドが高くなります。

  • ……

上記の問題を念頭に置いて、Apache Doris は、SQL メモリ IO オーバーヘッドの削減、クエリ実行効率の向上、SQL 解析オーバーヘッドの削減という 3 つの設計ポイントに基づいて一連の最適化を実行します。

   行ストア形式

列指向のストレージ形式とは異なり、行ベースのストレージ形式はデータ サービス シナリオでより使いやすいです。データは行に格納され、一度にデータ行全体を取得する方が効率的であり、データ数を大幅に削減できます。ディスクアクセスの数。したがって、Apache Doris バージョン 2.0 では、行ストレージをエンコードして別の列に格納し、追加のスペースに格納する行ストレージ形式を導入しましたユーザーは、テーブル作成ステートメントのプロパティで次のプロパティを指定して、行ストレージを有効にすることができます。

"store_row_column" = "true"

主に次の考慮事項により、行ストレージのエンコード形式として JSONB を選択します。

  • スキーマの変更は柔軟です。データが変更されると、それに応じてテーブルのスキーマも変更される可能性があります。行ストレージ形式がこれらの変更を処理する柔軟性を提供することは非常に重要です。たとえば、ユーザーがフィールドを削除したり、フィールド タイプを変更したりする場合、データの変更は適時に行ストレージに同期される必要があります。エンコード方式として JSONB を使用し、列を JSONB フィールドとしてエンコードすると、フィールドの拡張や属性の変更が非常に便利になります。

  • パフォーマンスの向上: 行ストア形式での行へのアクセスは、データが単一行に格納されるため、列ストア形式よりも高速になります。これにより、同時実行性が高いシナリオでのディスク アクセスのオーバーヘッドを大幅に削減できます。さらに、各列 ID を JSONB 内の対応する値にマッピングすることで、個々の列への高速アクセスを実現できます。

  • ストレージ スペース: 行ストレージ形式としての JSONB のコーデックも、ディスク ストレージ コストの削減に役立ちます。コンパクトなバイナリ形式では、ディスクに保存されるデータの合計サイズを削減できるため、コスト効率が高くなります。

JSONB エンコードおよびデコード行ストレージ形式を使用すると、同時実行性の高いシナリオで直面するパフォーマンスとストレージの問題を解決できます。行はストレージ エンジンの非表示列 ( )DORIS_ROW_STORE_COLとして保存され、Memtable フラッシュ中に各列が JSONB でエンコードされ、この非表示列にキャッシュされます。データを読み取るときは、列 ID で列を特定し、行番号で特定の行を特定し、各列を逆シリアル化します。

関連PR: https://github.com/apache/dris/pull/15491

   ポイントクエリのショートパス最適化(ショートサーキット)

通常、SQL ステートメントの実行には 3 つのステップを経る必要があります。まず、SQL パーサーによってステートメントを解析し、抽象構文ツリー (AST) を生成し、次にクエリ オプティマイザーによって実行可能プラン (Plan) を生成し、最後に計算を取得します。計画を実行することによって結果が得られます。大量のデータを含む複雑なクエリの場合、クエリ オプティマイザーによって生成された実行プランは間違いなくより効率的な実行効果をもたらしますが、待ち時間が短く同時実行性の要件が高いポイント クエリの場合、クエリ オプティマイザーの最適化プロセスを経るのは適していません。クエリ オプティマイザー全体で、不必要な追加のオーバーヘッドが発生します。

この問題を解決するために、クエリ オプティマイザーと PlanFragment をバイパスして SQL 実行プロセスを簡素化し、高速かつ効率的な読み取りパスを直接使用して必要なデータを取得する、ポイント クエリのショート パス最適化を実装しました。

5d60d709104c97d9631e153b2182c343.png

クエリが FE によって受信されると、プランナによってポイント クエリの物理計画として適切な短絡計画が生成されます。Plan は非常に軽量であり、同等の変換、論理最適化、物理最適化を必要とせず、AST ツリー上でいくつかの基本的な分析を実行し、対応する固定プランを構築し、オプティマイザーのオーバーヘッドを削減するだけです。

たとえば、単純なプライマリ キー ポイント クエリの場合、select * from tbl where pk1 = 123 and pk2 = 456単一のタブレットのみが関与するため、軽量の RPC インターフェイスを使用して StorageEngine と直接対話できるため、複雑なフラグメント プランの生成が回避され、MPP クエリ フレームワークのパフォーマンスに基づいてスケジューリングを実行する必要がなくなります。オーバーヘッド。RPC インターフェースの詳細は次のとおりです。

message PTabletKeyLookupRequest {
    required int64 tablet_id = 1;
    repeated KeyTuple key_tuples = 2;
    optional Descriptor desc_tbl = 4;
    optional ExprList  output_expr = 5;
}

message PTabletKeyLookupResponse {
    required PStatus status = 1;
    optional bytes row_batch = 5;
    optional bool empty_batch = 6;
}
rpc tablet_fetch_data(PTabletKeyLookupRequest) returns (PTabletKeyLookupResponse);

上記の table_id は、主キーの文字列形式である主キー条件列から計算されます。key_tuples上記の例では、key_tuples['123', '456'] に似ており、主キーのストレージとしてエンコードされます。 key_tuplesBE がリクエストを受信した後、主キー インデックスに従ってセグメント ファイル内のキーの行番号を識別し、対応する行がその中にあるかどうかを確認しdelete bitmap、存在する場合はその行番号を返し、存在しない場合は返しますNotFoundこの行番号は、__DORIS_ROW_STORE_COL__列に対して直接ポイント クエリを実行するために使用されます。そのため、必要なのは、その列内の行を見つけて、生の値を JSONB 形式で取得し、後続の出力関数によって計算された値として逆シリアル化することだけです。

関連PR: https://github.com/apache/dris/pull/15491

   プリペアドステートメントの最適化 (PreparedStatement)

同時実行性の高いクエリの CPU オーバーヘッドは、FE 層の分析と SQL 解析のための CPU 計算に部分的に起因する可能性があります。この問題を解決するために、FE 側で MySQL プロトコルと完全に互換性のあるプリペアド ステートメント (Prepared Statements) を提供します。CPU が主キー列挙のパフォーマンスのボトルネックになった場合、Prepared Statement が効果的に役割を果たし、4 倍を超えるパフォーマンスの向上を実現します

5c5d086cf112f4c2dad4fc8f9be81d29.png

Prepared Statement の動作原理は、事前に計算された SQL と式をセッション メモリのハッシュマップにキャッシュし、キャッシュされたオブジェクトを後続のクエリで直接再利用することです。

Prepared Statement は、トランスポート プロトコルとしてMySQL バイナリ プロトコル(https://dev.mysql.com/doc/dev/mysqlserver/latest/page_protocol_binary_resultset.html#sect_protocol_binary_resultset_row) を使用します。プロトコルはmysql_row_buffer.[h|cpp] ファイルに実装されており、標準の MySQL バイナリ エンコーディングに準拠しています。JDBC クライアントなどのこのプロトコル クライアントを通じて、最初の段階でPREPAREMySQL コマンドを送信して、プリコンパイルされたステートメントを FE に送信し、FE が解析し、ステートメントを分析してキャッシュします。それを上図の HashMap に変換すると、クライアントはEXECUTEMySQL コマンドを使用してプレースホルダーを置き換え、バイナリ形式にエンコードして FE に送信します。このとき、FE は MySQL プロトコルに従ってデシリアライズして、プレースホルダー内の値を取得します対応するクエリ条件を生成します。

aa3126fc60539e8e4008abad6f80fa69.png

FE でステートメントをキャッシュすることに加えて、事前に割り当てられた計算ブロック、クエリ記述子、出力式など、再利用された構造を BE でキャッシュする必要もあります。これらの構造はシリアル化および逆シリアル化中に CPU ホットスポットを引き起こすため、これらの構造はキャッシュされた。クエリされた PreparedStatement ごとに、CacheID と呼ばれる UUID が付加されます。BE がポイント クエリを実行すると、関連する CacheID に従って対応する再利用クラスが検索され、BE で式を計算および実行するときに上記の構造が再利用されます。

JDBC で PreparedStatement を使用する例を次に示します。

1. JDBC URLを設定し、サーバー側でPreparedStatementを有効にします。

 
  
url = jdbc:mysql://127.0.0.1:9030/ycsb?useServerPrepStmts=true

2. 準備済みステートメントの使用

 
  
// use `?` for placement holders, readStatement should be reused
PreparedStatement readStatement = conn.prepareStatement("select * from tbl_point_query where key = ?");
...
readStatement.setInt(1234);
ResultSet resultSet = readStatement.executeQuery();
...
readStatement.setInt(1235);
resultSet = readStatement.executeQuery();
...

関連PR: https://github.com/apache/dris/pull/15491

   ラインキャッシュ

Doris にはページレベルのキャッシュがあり、各ページには特定の列のデータが格納されるため、ページ キャッシュは列のキャッシュです。

3c2802f154674a66a7696bbc71c06f67.png

上記の行キャッシュは、行に複数列のデータが含まれており、大規模なクエリによってキャッシュがフラッシュされる可能性があるため、行キャッシュのヒット率を高めるためには、別途行キャッシュ(Row Cache)を導入する必要があります。 。

ライン キャッシュは、Doris の LRU キャッシュ メカニズムを再利用します。メモリしきい値は起動時に初期化され、メモリしきい値を超えると古いキャッシュ ラインが削除されます。主キーのクエリ ステートメントの場合、ストレージ レイヤー上の行キャッシュにヒットする場合とヒットしない場合との間には、数十倍のパフォーマンス ギャップ (ディスク IO とメモリ アクセスの間のギャップ) が存在する可能性があるため、行キャッシュを導入すると、ポイント クエリのパフォーマンスが大幅に向上します(特にキャッシュ ヒットが多いシナリオで)。

9ac3b8772c5286c86188df3053a79af2.png

ライン キャッシュを有効にするには、BE で次の設定項目を設定して有効にします。

 
  
disable_storage_row_cache=false //是否开启行缓存, 默认不开启
row_cache_mem_limit=20% // 指定row cache占用内存的百分比, 默认20%内存

関連PR: https://github.com/apache/dris/pull/15491

# 基準

上記の一連の最適化に基づいて、データ提供シナリオにおける Apache Doris のパフォーマンスがさらに向上しました。Yahoo! Cloud Serving Benchmark (YCSB) の標準パフォーマンステストツールに基づいてベンチマークテストを実施しました。環境構成とデータ規模は次のとおりです。

  • マシン環境: シングル 16 コア 64G メモリ 4*1T ハードディスク クラウド サーバー

  • クラスターサイズ: 1 FE + 3 BE

  • データ規模: 合計 1 億個のデータ (1 行あたり平均約 1K) がテスト前にウォームアップされました。

  • 対応するテスト テーブルの構造とクエリ ステートメントは次のとおりです。

 
  
// 建表语句如下:

CREATE TABLE `usertable` (
  `YCSB_KEY` varchar(255) NULL,
  `FIELD0` text NULL,
  `FIELD1` text NULL,
  `FIELD2` text NULL,
  `FIELD3` text NULL,
  `FIELD4` text NULL,
  `FIELD5` text NULL,
  `FIELD6` text NULL,
  `FIELD7` text NULL,
  `FIELD8` text NULL,
  `FIELD9` text NULL
) ENGINE=OLAP
UNIQUE KEY(`YCSB_KEY`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`YCSB_KEY`) BUCKETS 16
PROPERTIES (
"replication_allocation" = "tag.location.default: 1",
"in_memory" = "false",
"persistent" = "false",
"storage_format" = "V2",
"enable_unique_key_merge_on_write" = "true",
"light_schema_change" = "true",
"store_row_column" = "true",
"disable_auto_compaction" = "false"
);

// 查询语句如下:

SELECT * from usertable WHERE YCSB_KEY = ?

最適化を有効にした場合 (つまり、ライン ストレージ、ショート パス、および PreparedStatement を同時にチェックした場合) と有効にしていない場合のテスト結果は次のとおりです。

da38bd65026e6196e70c20f8632f17b2.png

上記の最適化項目を有効にした後、平均クエリ時間消費量は 96% 削減され、99 パーセンタイルのクエリ時間消費量は前のクエリ時間のわずか 1/28 になりました。QPS 同時実行数は1400 から 3w に増加し、さらに増加し​​ました。全体的なパフォーマンスと同時負荷の実現データは、飛躍的な進歩を遂げました

# ベストプラクティス

現在の段階で実装されているポイント クエリの最適化はすべて Unique Key 主キー モデルで実行され、使用前に Merge-on-Write と Light Schema Change を有効にする必要があることに注意してください。ポイントクエリシナリオのテーブル作成ステートメント:

 
  
CREATE TABLE `usertable` (
  `USER_KEY` BIGINT NULL,
  `FIELD0` text NULL,
  `FIELD1` text NULL,
  `FIELD2` text NULL,
  `FIELD3` text NULL
) ENGINE=OLAP
UNIQUE KEY(`USER_KEY`)
COMMENT 'OLAP'
DISTRIBUTED BY HASH(`USER_KEY`) BUCKETS 16
PROPERTIES (
"enable_unique_key_merge_on_write" = "true",
"light_schema_change" = "true",
"store_row_column" = "true",
);

知らせ:

  • オンにする

    light_schema_change

    JSONB 行ストレージ エンコーディングをサポートするには ColumnID

  • store_row_column を有効にする 

    行フォーマットを保存するには

テーブル作成操作の完了後、行の格納形式とショート パスの実行により、次のような主キーに基づくクエリ SQL のパフォーマンスが大幅に向上します。

 
  
select * from usertable where USER_KEY = xxx;

同時に、JDBC のプリペアド ステートメントを通じてポイント クエリのパフォーマンスをさらに向上させることができます。十分なメモリがある場合は、BE 構成ファイルでライン ストレージ キャッシュを有効にすることもできます。使用例は上に示したので、ここでは繰り返しません。

# 要約する

行ベースのストレージ形式、ポイントクエリのショートパス最適化、プリペアドステートメント、および行ストアキャッシュを導入することで、Apache Doris はノードあたり数万 QPS という超高同時実行性を実現し、数十倍のパフォーマンス向上を達成しました。クラスター規模の水平方向の拡張とマシン構成の改善により、Apache Doris はハードウェア リソースを使用してコンピューティングの高速化を実現することもでき、独自の MPP アーキテクチャーも水平方向および線形に拡張する機能を備えています。したがって、Apache Doris は、単一のアーキテクチャの下で高スループットの OLAP 分析と同時実行性の高いデータ提供オンライン サービスを同時に満たす能力を真に備えており、混合ワークロードの下で技術アーキテクチャを大幅に簡素化し、複数のシナリオ

上記の機能の実現は、Apache Doris コミュニティの開発者の共同の努力と、SelectDB エンジニアの継続的な貢献の恩恵を受けており、現在本格的にリリースが進められており、近い将来バージョン 2.0 がリリースされる予定です。

この記事が参考になったら「いいね」 「いいね」 「お気に入り」を3回忘れずに  !

f48c7cd63ec08dcafd22f4e7714859ce.png

56b0a36f6cced3200d76a0cb24406a70.jpeg

2022 年にネットワーク全体でリリース予定 | ビッグデータの専門家レベルのスキル モデルと学習ガイド (Shengtian Banzi)

インターネット最悪の時代が本当に到来するかもしれない

私はBilibiliの大学でビッグデータを専攻しています。

Flink を学習するとき、私たちは何を学んでいるのでしょうか?

193 の記事がフリンクを激しく打ち負かしました、このコレクションに注意を払う必要があります

Flink 本番環境の TOP 問題と最適化、アリババ チベット経典パビリオン YYDS

フリンク CDC きっとイエス様を引き留めることはできないでしょう!| Flink CDC オンライン問題インベントリ

Spark を学習するとき、私たちは何を学んでいるのでしょうか?

すべての Spark モジュールの中で、私は SparkSQL が最強だと呼びたいと思います。

Hard Gang Hive | 40,000 語の基本チューニング インタビューの要約

データ ガバナンスの方法論と実践に関する小さな百科事典

ラベル システムの下でのユーザー ポートレート構築に関する小さなガイド

40,000 ワードの長文 | ClickHouse の基礎と実践とチューニングの完全なパースペクティブ分析

【インタビュー&自己成長】2021年半分以上、ソーシャルリクルーティングとスクール採用の経験

ビッグデータの方向へ新たな10年が始まる | 「ハードギャングシリーズ」第1弾が終了

成長/面接/キャリアアップについて書いた記事

Hive を学習するとき、私たちは何を学んでいるのでしょうか? 「ハードハイブ続編」

おすすめ

転載: blog.csdn.net/u013411339/article/details/131345864