すべてのプロダクト
Search
ドキュメントセンター

PolarDB:IMCIの技術アーキテクチャ

最終更新日:May 27, 2024

このトピックでは、PolarDBのインメモリ列インデックス (IMCI) 機能の技術的背景、紹介、および技術アーキテクチャについて説明します。

技術的背景

MySQLエコシステムのHTAPデータベースソリューション

MySQLは、主にオンライントランザクション処理 (OLTP) シナリオ用に設計されたオープンソースデータベースです。 オープンソースコミュニティでの研究開発は、可用性を向上させるために、シングルコアパフォーマンス、マルチコアスケーラビリティ、クラスター機能など、MySQLのトランザクション処理機能を強化することに重点を置いています。 ただし、MySQLコミュニティでは、オプティマイザーベースのサブクエリ処理、高性能演算子Hash Join、SQL並列実行など、大量のデータに対して複雑なクエリを処理するために必要な機能の優先順位が低くなっています。 したがって、MySQLデータ分析機能の改善は遅いです。

MySQLが世界で最も人気のあるオープンソースデータベースシステムになると、ユーザーは大量のデータを保存し、MySQLで主要なビジネスロジックを実行します。 したがって、リアルタイムデータ分析の需要が高まっています。 スタンドアロンMySQLが要件を満たすことができない場合、ユーザーはより良いソリューションを期待します。 たとえば、次のソリューションが利用可能です: 構築ブロックソリューションMySQL + 専用APデータベース複数のレプリカに基づく発散設計方法、および統合ハイブリッド行-列ストアソリューション

MySQL + 専用APデータベースのビルディングブロックソリューション

このソリューションでは、OLTPおよびオンライン分析処理 (OLAP) 要件を満たすために2つのシステムが展開され、データ同期ツールを使用して2つのシステム間でリアルタイムでデータを同期させます。 ユーザーは、トランザクション処理 (TP) ロードをMySQLに、分析処理 (AP) ロードをOLAPデータベースに自動的にルーティングするプロキシのレイヤーを追加できます。 このようにして、ユーザーは基になるデータベースの配置トポロジからアプリケーション層をマスクできます。 次の図は、ソリューションのアーキテクチャを示しています。image.png

アーキテクチャは柔軟です。 例えば、TPデータベース及びAPデータベースに対して最良の方式を選択することができ、TP及びAP負荷は互いに分離される。 ただし、アーキテクチャの欠点も明らかです。 第1に、異なる技術システムを使用する2組のデータベースシステムを維持することが技術的に必要である。 第2に、2つのデータベースシステムの処理メカニズムの違いにより、アップストリームおよびダウンストリームデータのリアルタイムの一貫性を保証することも非常に困難である。 さらに、同期待ち時間のために、下流のAPシステムに格納されるデータはしばしば古くなり、リアルタイム分析の要件を満たすことができない。

複数のレプリカに基づく多様な設計方法

インターネットの台頭とともに出現した新しいデータベース製品の多くは、MySQLプロトコルと互換性があります。 ほとんどの分散データベース製品は、分散共有なしソリューションを採用しています。 このソリューションの主要な機能の1つは、分散整合性プロトコルを使用して、単一のパーティションの複数のレプリカ間でデータの整合性を確保することです。 データの1つのコピーは複数のレプリカ間で完全に独立しているため、異なるクエリ負荷に対応するために異なるレプリカ上のストレージに異なるフォーマットを使用することは容易です。 典型的な例はTiDBである。 バージョン4.0以降、TiDBは、APロードに応答するためにRaftグループ内のレプリカの1つで、列ストアであるTiFlashを使用します。 TiDBは、インテリジェントルーティング機能も使用して、データソースを自動的に選択します。 これにより、1つのデータベースシステムがOLTPとOLAPロードの両方に対応できます。image.png

この方法は、多くの研究および産業分野で使用されており、分散データ分野における統合HTAPの事実上の標準スキームにますますなっている。 ただし、ユーザーは対応するNewSQLデータベースシステムにデータを移行する必要があることを前提としています。 ほとんどの場合、これはさまざまな互換性の問題をもたらします。

統合ハイブリッド行列ストアソリューション

マルチレプリカ分岐設計よりも高度なソリューションは、データベースインスタンスでハイブリッド行と列ストアを使用して、TPとAPの両方の負荷に応答することです。 このソリューションは、Oracle、SQL Server、Db2などのすべての従来の商用データベースで使用されています。

  • Oracle Corporationは、2013年にOracle Database 12cでDatabase In-Memoryスイートをリリースしました。 スイートのコア機能は、インメモリ列ストアです。 これにより、ハイブリッド列ストアやマテリアライズド式またはJoinGroupに基づく高度なクエリ最適化などの手法を使用して、OLAPのパフォーマンスが向上します。

  • Microsoftは、SQL Server 2016 SP1で列ストアインデックス機能の提供を開始しました。 ユーザーは、負荷特性に基づいて、行指向テーブル、列指向テーブル、行指向テーブルと列指向テーブルの組み合わせ、列指向テーブルと行ストアインデックスの組み合わせなど、さまざまなモードを使用できます。

  • 2013年にリリースされたKepler 10.5で、IBMはDb2 BLU Accelerationコンポーネントを追加しました。 このコンポーネントは、列ストア、インメモリコンピューティング、およびDataSkippingテクノロジを使用することにより、分析シナリオのパフォーマンスを大幅に向上させました。

image.png

3つの主要な商用データベースベンダーは、インメモリコンピューティングと同時に組み合わされたハイブリッド行列ストアの技術的ルートを採用しています。 列ストアは、I/O効率 (圧縮、DataSkipping、および列プルーニング) とCPUコンピューティング効率 (キャッシュフレンドリー) が優れています。 したがって、最高の分析パフォーマンスを達成するには、カラムストアを使用する必要があります。 ただし、列ストアのインデックスのスパース性によって引き起こされるインデックスの精度の問題により、列ストアはTPシナリオのストレージ形式にはなりません。 したがって、ハイブリッド行 − 列記憶ソリューションは、必要なソリューションとなる。 しかしながら、ハイブリッド行 − 列ストア・アーキテクチャでは、ランダム・データ更新の処理に関して、行ストア・インデックスと列ストア・インデックスとの間に性能ギャップが存在する。 ダイナミック・ランダム・アクセス・メモリ (DRAM) の低い読取り − 書込み待ち時間の特徴は、列記憶更新の低い効率を補償するために使用されなければならない。 したがって、低レイテンシOLTPと高性能のリアルタイムデータ分析の機能により、インメモリコンピューティングと組み合わせたハイブリッド行列ストアソリューションが最適です。

ビルディングブロックソリューションから発散設計方法および統合されたハイブリッド行-列ストアソリューションまで、統合レベルが向上し、ユーザーエクスペリエンスが向上します。 しかしながら、カーネルを実装する際の課題も増大する。 基本的なソフトウェアの役割は、複雑さをそれ自体に任せ、シンプルさをユーザーに任せることです。 したがって、統合されたハイブリッド行列ストアソリューションは、技術的な傾向に沿ったものです。

PolarDB for MySQLのAP機能の進化

PolarDB for MySQLの機能スタックは、オープンソースMySQLの機能スタックと同様です。 PolarDB for MySQLはTPシナリオを効率的に処理できますが、APシナリオでは弱いです。 PolarDBクラスターは最大100テラバイトのデータを保存でき、トランザクション処理能力は自己管理型MySQLデータベースをはるかに超えています。 したがって、PolarDBユーザーは、より多くのデータを単一のクラスターに格納し、そのデータに対していくつかの複雑な集計クエリを実行する傾向があります。 PolarDBのwrite-once-read-manyアーキテクチャを使用すると、複数の読み取り専用 (RO) ノードを追加して、ビジネス要件に基づいて複雑なクエリを実行できます。 これは、TP負荷に対する分析クエリの干渉を防止する。

APシナリオにおけるMySQLアーキテクチャの欠陥

複雑なクエリの実行におけるMySQLアーキテクチャのパフォーマンスの低下は、多くの理由によって引き起こされます。 専用のOLAPシステムと比較して、MySQLのパフォーマンスのボトルネックは次の点に反映されています

  • MySQLのSQL実行エンジンは、火山イテレータモデルに基づいて実装されています。 このアーキテクチャは、プロジェクトの実装に関して、多数の深いレベルのネストされた関数と仮想関数に大きく依存します。 大量のデータが処理されると、アーキテクチャがCPUパイプラインの効率に影響を与え、CPUキャッシュの効率が低下します。 さらに、イテレータ実行モデルは、実行を加速するためにCPUによって提供される単一命令複数データ (SIMD) 命令を完全に利用することができない。

  • 実行エンジンはシリアルにしか実行できず、マルチコアCPUの並列処理能力をフルに活用することはできません。 MySQLが8.0してから、count(*) などのいくつかの基本クエリに並列実行機能が追加されました。 ただし、複雑なSQLステートメントの並列実行機能には、まだ長い道のりがあります。

  • MySQLの最も頻繁に使用されるストレージエンジンは、行ストア形式を使用します。 データベースが列ごとに大量のデータを分析する場合、データベースが行ごとにディスクからデータを読み取るときに大量のI/O帯域幅が無駄になります。 また、ローストア形式では、大量のデータを処理する際に、不要な列データが大量にコピーされます。 これは、メモリの読み出しおよび書き込み効率に悪影響を及ぼす。

PolarDBの並列クエリフレームワークがCPUボトルネックを突破

PolarDBチームによって開発された並列クエリフレームワークは、クエリされたデータの量が特定のしきい値に達すると、自動的に並列実行を開始できます。 データは、並列計算のためにストレージ層で異なるスレッドに分散され、結果はメインスレッドに集約されます。 次に、メインスレッドは結果を要約してユーザーに返します。 このフレームワークは、クエリ効率の向上に役立ちます。 image.png

並列クエリ機能により、PolarDBはシングルコア実行パフォーマンスの制限を突破できます。 マルチコアCPUの並列処理機能を使用することにより、PolarDBに対する一部のSQLクエリの時間消費は指数関数的に減少します。

PolarDB列ストア

並列実行フレームワークは、CPUスケーラビリティの制限を突破し、パフォーマンスを大幅に向上させます。 しかし、単一コア実行性能は、ロウストアおよびロウエグゼキュータの効率限界のために上限を有する。 ピーク性能は、依然として専用OLAPシステムの性能よりも低い。 PolarDB for MySQLの分析パフォーマンスをさらに向上させるには、列ストアを導入する必要があります。

  • 分析シナリオでは、多くの場合、列内の多数のレコードにアクセスする必要があります。 異なる列にデータを格納することにより、列ストアは不要な列の読み取りを回避します。 さらに、列ストアは、同じ属性を持つ列を継続的に保存します。 列ストアの圧縮効率は、行ストアの圧縮効率よりもはるかに高い。 ほとんどの場合、圧縮効率は10倍以上高くなります。 さらに、MINおよびMAXなどの大まかなインデックス情報と組み合わせて、列ストアの大きなブロックストレージの構造を使用して、広範囲のデータをフィルタリングすることができる。 これらのすべてのプラクティスは、I/O効率を大幅に改善します。 計算ストレージ分離アーキテクチャでは、ネットワークを介して読み取られるデータ量を削減することで、クエリ処理の応答時間を即座に改善できます。

  • Aカラムストアは、データ処理中のCPUの実行効率を向上させることもできます。 第1に、カラムストアのコンパクトな配置は、CPUのメモリアクセス効率を改善し、L1またはL2キャッシュミスによって引き起こされる実行休止を低減することができる。 第2に、SIMD技術を列ストアに適用して、シングルコアスループットをさらに改善することができる。

はじめに

IMCI機能は、PolarDBにカラムストアとインメモリコンピューティング機能を提供します。 これにより、ユーザーは一連のPolarDBデータベースでTPとAPのハイブリッドロードを同時に実行できます。 これにより、PolarDBの現在の優れたOLTPパフォーマンスが保証され、大量のデータに対して複雑なクエリを実行する際のPolarDBのパフォーマンスが大幅に向上します。 次の図は、IMCI機能の回路図を示しています。

image.png

IMCI機能は、ハイブリッド行と列ストアソリューションを使用し、PolarDBの共有ストレージベースのwrite-once-read-manyアーキテクチャを組み合わせています。 IMCI機能には、次の主要な技術革新が含まれます。

  • 列状インデックスのサポートは、PolarDBのストレージエンジンInnoDBに追加されます。 ユーザーはDDLを使用して、テーブルのすべてまたは一部の列を列状インデックスとして作成できます。 列インデックスは列圧縮ストレージを使用し、ストレージスペースの消費は行ストアの消費よりもはるかに小さくなります。 デフォルトでは、カラムインデックスはメモリに存在し、分析パフォーマンスを最大化します。 ただし、メモリ容量が不足している場合は、共有ストレージにカラムインデックスを永続化することもできます。

  • PolarDBのSQLエグゼキューターレイヤーで、PolarDBチームは列指向のエグゼキューターエンジンフレームワークを書き換えます。 フレームワークは、列ストアの利点を最大限に活用します。 たとえば、フレームワークは、4,096行のバッチでストレージ層のデータにアクセスし、SIMD命令を使用して、CPUのシングルコアデータ処理のスループットを向上させることができます。 すべての主要な演算子は並列実行をサポートします。 列ストアでは、新しいエグゼキュータのパフォーマンスは、MySQLの元の行ストアのエグゼキュータのパフォーマンスよりも数桁優れています。

  • ハイブリッド行 /列実行をサポートするオプティマイザーフレームワークが提供される。 オプティマイザーフレームワークは、発行されたSQLステートメントを列内インデックスで実行できる場合は対象クエリを実行し、SQLステートメントが依存する関数と演算子を列エグゼキュータが実行できる場合は列内インデックスを開始します。 オプティマイザーフレームワークは、行ストア実行プランおよび列ストア実行プランのコストを推定し、コストの低い実行プランを選択します。

  • ユーザーは、PolarDBクラスター内のROノードを分析ノードとして使用し、ROノードで列ストアインデックスを設定できます。 複雑なクエリは列ストアインデックスで実行され、使用可能なすべてのCPUの計算能力を使用します。 このようにして、クラスタ内のTP負荷の利用可能なメモリおよびCPUリソースに影響を与えることなく、最大の実行性能が得られる。

いくつかの重要なテクノロジーの組み合わせにより、PolarDBは真のHTAPデータベースシステムになります。

技術アーキテクチャ

ハイブリッド行列オプティマイザ

PolarDBは行指向のオプティマイザを提供します。 エンジン層が列ストアのサポートを追加した後、オプティマイザを強化する必要があります。 オプティマイザは、実行のために行ストアまたは列ストアへのクエリをスケジュールするかどうかを決定できる必要があります。 IMCI機能は、ホワイトリストメカニズムと実行コスト計算のフレームワークを使用することでこれを実現します。 システムは、サポートされているSQL文の高速化を保証し、サポートされていないSQL文と互換性があります。

どのように达成100% MySQL互换性

PolarDBチームは、ホワイトリストメカニズムを使用して互換性の目標を達成します。 ホワイトリストメカニズムは、次の要因を考慮して使用されます。

  • 利用可能なシステムリソース、主にメモリリソースの制限。

    ほとんどの場合、列インデックスはデータベースのすべてのテーブルのすべての列に作成されません。 クエリ文が列ストアに存在しない列を使用する必要がある場合、文は列ストアで実行できません。

  • パフォーマンス。

    PolarDBチームは、すべての物理実行演算子と式コンピューティングを含む列指向のSQL実行エンジンを書き換えます。 サポートされているシナリオのカバレッジは、MySQLのネイティブ行ストアと比較して不十分です。 発行されたSQL文に、IMCI実行エンジンでサポートされていないいくつかの演算子フラグメントまたは列タイプが含まれている場合、実行エンジンはSQL文を識別してインターセプトし、実行のために行ストアに戻すことができる必要があります。

image.png

ホワイトリストメカニズムは、SQL文やその他のシナリオ (複数文がサポートされていないシナリオなど) のデータ型、演算子、式をチェックします。

MySQLは何十年も進化してきました。 MySQLは、さまざまな列タイプと豊富なSQL構文をサポートします。 IMCIでは、最初の焦点は、分析クエリ文で最も一般的なSQLパフォーマンスの問題を最適化することです。 IMCIの適用可能なシナリオが限られている場合でも、IMCIでサポートされているSQL構文は、ほとんどのOLAPシステムよりもMySQLとの互換性があります。 発行されたSQL文を列ストアで実行できない場合、SQL文はMySQLのネイティブ実行エンジンに直接フォールバックされます。 このようにして、MySQLとの100% 互換性が達成される。

クエリプラン変換

プラン変換の目的は、MySQLのネイティブ論理実行プランの抽象構文ツリー (AST) 表現をIMCIの論理プランに変換することです。 IMCIの論理プランが生成された後、一連の最適化の後に物理プランが生成される。

プランの変換はシンプルで直接的です。 ユーザーは、実行プランツリーをトラバースし、MySQLによって最適化されたASTを、IMCIのノードとしてリレーション演算子を持つツリー構造に変換するだけです。 このプロセスでは、MySQLの柔軟なタイプシステムとの互換性を確保するために、暗黙的なタイプの変換が実行されます。

プラン変換プロセスは、同等の論理プランを生成する。 論理プランは、エグゼキュータによって実行することができず、実行のために物理プランに変換されなければならない。 IMCIのオプティマイザは単純なロジックを使用します。 ハッシュ結合またはネストされたループ結合を使用するかどうかの決定など、いくつかの基本的な実行計画の最適化に加えて、オプティマイザは主に、IMCIエグゼキュータによってサポートされていないサブクエリを同等の結合操作に変換するために使用されます。

ハイブリッド行列実行のオプティマイザ

行ストアと列ストアの2つの実行エンジンに基づいて、実行プランが選択された場合、オプティマイザはより多くの選択肢を提供します。 オプティマイザは、行ストア実行計画のコストを列ストア実行計画のコストと比較し、コストの低い実行計画を使用できます。

MySQLのネイティブの行ストアベースのシリアル実行機能に加えて、PolarDBは、マルチコアのコンピューティング能力を最大限に活用できる行ストアベースの並列クエリ機能もサポートしています。 したがって、PolarDBオプティマイザは、行ストアベースのシリアル実行、行ストアベースの並列クエリ、およびIMCIのいずれかを選択します。 現在の反復フェーズでは、PolarDBオプティマイザは次の実行プロセスに従います。

  1. PolarDBオプティマイザはSQL文を解析し、論理プランを生成します。 次に、PolarDBオプティマイザはMySQLのネイティブオプティマイザを呼び出して、結合順序調整などの最適化を実行します。 同時に、得られた論理プランは、IMCI実行プランのコンパイルモジュールに渡される。 モジュールは、カラムストア実行プランの生成を試みます。 SQLステートメントは、ホワイトリストによってブロックされ、実行のために行ストアにフォールバックされる可能性があります。

  2. PolarDBオプティマイザは、行ストア実行プランに基づいて行指向の実行コストを計算します。 コストが特定のしきい値を超えると、PolarDBオプティマイザは、IMCIプランに基づいて実行するために、SQLステートメントをIMCIエグゼキュータにプッシュダウンしようとします。

  3. IMCIエグゼキュータがSQL文を実行できない場合、PolarDBは並列クエリ実行プランのコンパイルとSQL文の実行を試みます。 並列クエリ実行プランを生成できない場合、IMCIおよび並列クエリ機能はSQL文を実行できず、SQL文は実行のために行ストアにフォールバックされます。

前述の戦略は、次の判断に基づいています。実行パフォーマンスの観点から、行ストアの直列実行は、IMCIに劣る行ストアの並列実行に劣ります。 SQL互換性の点では、IMCIは行ストア並列実行よりも劣り、行ストア直列実行よりも劣る。 しかし、実際の状況はより複雑です。 たとえば、場合によっては、行ストアインデックスに基づく並列インデックス結合は、列ストアに基づくソートマージ結合よりもコストが低くなります。 IMCIは、現在の戦略に基づいてSQLステートメントを実行するために選択され得る。

列指向の実行エンジン

IMCI実行エンジンは、列指向の最適化を伴う実装であり、MySQLの既存の行エグゼキュータから完全に独立しています。 エグゼキュータを書き換える目的は、分析SQLステートメントの実行中に既存の行ストア実行エンジンの低効率の問題につながる2つの主要なボトルネックを排除することです。 ボトルネックは、行ベースのアクセスとSQL文を並列に実行できないことによって引き起こされる仮想関数アクセスのオーバーヘッドです。

ベクトル化並列executor

IMCI実行エンジンは、従来の火山モデルを使用し、列ストアとベクトル化実行に基づいて実行パフォーマンスを向上させます。

火山モデルに関して、SQLによって生成された構文木に対応する関係代数では、各演算は演算子に抽象化されます。 実行エンジンは、SQL全体を演算子ツリーに構築する。 クエリツリーはNext() インターフェイスを上から下に呼び出し、データは下から上にプルされます。 この方法の利点は、計算モデルが単純かつ簡単であることである。 これは、異なる物理演算子をイテレータに抽象化することによって実現されます。 各演算子は、独自の内部ロジックのみを気にします。 これにより、演算子間の結合が減り、論理的に正しい実行エンジンの書き込みが容易になります。

  • IMCI実行エンジンでは、各演算子もイテレータ関数を使用してデータにアクセスします。 違いは、イテレータへの各呼び出しがバッチを返しますが、データの行は返しません。 したがって、実行エンジンは、ベクトル化モデルを使用する火山モデルとみなすことができる。

    image.png

  • シリアル実行の機能は、シングルコアコンピューティングの効率、メモリアクセスの待ち時間、I/Oの待ち時間などの要因によって制限されます。 IMCIエグゼキュータのScan、Join、Aggなどのいくつかの主要な物理演算子は、並列実行をサポートしています。 物理演算子は並列処理をサポートする必要があり、IMCIオプティマイザも並列実行プランの生成をサポートする必要があります。 オプティマイザがテーブルのアクセスモードを決定すると、オプティマイザは、アクセスするデータ量に基づいて並列実行を有効にするかどうかを決定します。 オプティマイザが並列実行を有効にすることを決定した場合、オプティマイザは一連の状態データを参照して並列度 (DOP) を決定する。 状態データには、システム内の利用可能なCPU、メモリ、およびI/Oリソース、スケジュールされキューに入れられるタスクに関する情報、統計、クエリの複雑さ、およびユーザーが設定できるパラメーターが含まれます。 これらのデータに基づいて、推奨されるDOP値がオペレータについて計算され、各オペレータは、同じDOP値を内部的に使用する。 ユーザーは、ヒントを使用してDOP値を指定することもできます。

    image.png

前述の2つの最適化のアイデアに基づいて、テーブルスキャン、ハッシュ結合、ネストループ結合、およびグループバイを含むすべての物理実行演算子が再実装されます。 次の例では、実行プログラムの並列化とベクトル化の高速化を示すためにHash Joinを使用します。 IMCIでのHash Joinの実行プロセスを次の図に示します。

image.png

ベクトル化実行は、シングルコアの実行効率が低いという問題を解決しますが、並列実行はシングルコアのコンピューティングのボトルネックを解消します。 この2つの組み合わせにより、IMCIの実行速度は、MySQLの従来の行実行よりも数桁速くなります。

ベクトル化表現システム

APシナリオでは、SQLには多くの場合、1つまたは複数の値、演算子、または関数を含む多くのコンピューティングプロセスが含まれます。 これは、式コンピューティングのカテゴリに属します。 式の評価は計算集約的なタスクであるため、式の計算効率は全体的なパフォーマンスに影響を与える重要な要素です。

MySQLの従来の式コンピューティングシステムは、一般にイテレータモデル実装と呼ばれる行ごとの操作方法を使用します。 イテレータはテーブル全体を抽象化し、式はツリー構造として実装されます。 ただし、この抽象化はパフォーマンスの損失をもたらします。 これは、イテレータの反復中に、データの各行の取得が複数層の関数呼び出しをトリガーするためです。 データの行ごとの取得は、あまりにも多くのI/Oをもたらし、キャッシュにとって友好的ではない。 MySQLはストレージエンジンのアクセス方法によって制約されるため、MySQLはツリーイテレータモデルを使用します。 これは、複雑な計算ロジックを最適化することを困難にする。

列ストアの場合、各列のデータは別々に順番に格納されるため、特定の列での式の計算はバッチで実行できます。 各式の入力と出力の単位はバッチです。 バッチ処理モデルでは、計算プロセスは、SIMD命令を使用することによって加速することができる。

ベクトル化された式システムには、2つのキー最適化があります。

  • ベクトル化された式システムは、列ストアの利点を最大限に活用し、イテレータモデルをバッチ処理モデルに置き換えます。 PolarDBチームは、SIMD命令を使用して、最も一般的なデータ型の式カーネル実装を書き換えます。 たとえば、INT、DECIMAL、およびDOUBLEを含むすべての数値型のすべての基本的な数学演算 (+ 、− 、× 、/、およびabs) は、対応するSIMD命令を使用することによって実装される。 AVX512命令セットの助けによって、単一中心操作の性能は数回改善されます。

    image.png

  • 式の実装は、PostgreSQLの実装に似ています。 SQLコンパイルおよび最適化ステージでは、IMCI式は、既存の行イテレータモデルと同様のツリー構造に格納されます。 しかし、実行前に、式ツリーはポストオーダーでトラバースされ、記憶のために1次元配列に変換される。 後続の計算において、ユーザは、操作を完了するために1次元アレイをトラバースするだけでよい。 計算は、ツリー反復子モデルにおける再帰的プロセスを排除するので、より効率的である。 さらに、この方法は、計算プロセスの簡潔な抽象化を提供し、データを計算から分離します。これは、並列計算に適しています。

ハイブリッド行-列ストア

トランザクションアプリケーションと分析アプリケーションは、ストレージエンジンの要件がまったく異なります。 前者は、インデックスが各行に正確に配置され、効率的な追加、削除、および修正をサポートできることを必要とする。 後者は、効率的なバッチスキャンおよび処理のサポートを必要とする。 これら2つのシナリオにおけるストレージエンジンの設計要件は完全に異なり、時には矛盾することさえあります。 したがって、OLTP負荷とOLAP負荷の両方に対応できる統合ストレージエンジンを設計することは非常に困難です。 研究開発で数十年の経験を持ついくつかの大企業だけがHTAPストレージエンジンでうまくやっています。 たとえば、Oracleにはインメモリ列ストアがあり、SQL Serverにはインメモリ列インデックスがあり、Db2にはBLUがあります。 TiDBは、マルチレプリカクラスター内の1つのレプリカを列ストアに調整することによってのみ、HTAP要件を満たすことができます。

統合型HTAPストレージエンジンは、一般に、ハイブリッド行 − 列ストアソリューションを使用する。 換言すれば、ローストア及びカラムストアの両方がエンジン内に同時に存在する。 行ストアはTPを提供し、列ストアはAPを提供する。 ビジネス要件を満たすためのOLTPデータベースとOLAPデータベースの別々の展開と比較して、単一のHTAPエンジンには次の利点があります。

  • 行指向データと列指向データはリアルタイムで一貫しており、多くの高いビジネス要件を満たすことができます。 すべてのデータは、一度書かれた分析クエリで見つけることができます。

  • HTAPエンジンは費用対効果が高い。 ユーザーは、分析用の列ストア形式に格納するテーブルの列または範囲を簡単に指定できます。 完全なデータは、引き続き行ストアに格納されます。

  • 管理とO&Mは便利です。 ユーザーは、2つのシステム間のデータ同期とデータの一貫性について心配する必要はありません。

PolarDBは、OracleやSQL Serverなどの商用データベースと同様のハイブリッド行-列ストアテクノロジーを使用します。 PolarDBチームはテクノロジーをIMCIと呼んでいます。

  • ユーザーがテーブルを作成するとき、ユーザーはテーブルの一部または一部の列を指定して、列ストア形式を使用できます。 ユーザーは、ALTER TABLEステートメントを使用して、既存のテーブルに列ストア属性を追加できます。 分析クエリは自動的に列ストア形式を使用してクエリを高速化します。

  • デフォルトでは、列指向のデータは圧縮されてディスクに保存され、In-Memory Columbia Store Areaはキャッシュとクエリの高速化に使用できます。 従来の行フォーマットは、OLTPロードが使用するバッファプールに格納されます。

  • トランザクションのすべての追加、削除、および変更は、リアルタイムでカラムストアに反映されます。 これにより、トランザクションレベルのデータの一貫性が保証されます。

    image.png

ハイブリッド行 − 列記憶エンジンを実施することは技術的に困難である。 また、InnoDBなどの成熟したOLTP負荷最適化ストレージエンジンに列ストアのサポートを追加する場合、ユーザーはさまざまな状況に直面します。

  • OLTP要件を満たすことが最優先事項です。 したがって、カラムストアのサポートを追加することは、TPパフォーマンスにあまり影響を与えません。 これには、コラムストアのメンテナンスが十分に軽量でなければならない。 必要に応じて、TPパフォーマンスを確保するためにAPパフォーマンスを犠牲にする必要があります。

  • 列ストアの設計では、トランザクションの同時実行によるデータの変更とデータの一意のチェックを考慮する必要はありません。 これらの問題はロウストアシステムで解決されているが、ClickHouseなどの個々のカラムストアエンジンでは非常に困難である。

  • 実証済みの行ストア・システムでは、列ストア・システムに関する問題は、クエリ要求に応答するために行ストア・システムに切り替えることによって対処することができる。

前述の条件の影響は混在しており、PolarDBのハイブリッド行-列ストアソリューションの設計に影響を与えています。

インデックスとして実装された列ストア

MySQLのプラグインストレージエンジンフレームワークのアーキテクチャでは、列ストアのサポートを追加する最も簡単なソリューションは、InfobrightとMariaDBの列ストアのように、個別のストレージエンジンを実装することです。 PolarDBは、InnoDBのセカンダリインデックスとして列ストアを実装するソリューションを使用します。 これは主に次の考慮事項に基づいています。

  • InnoDBは、複数のインデックスをネイティブにサポートします。 INSERT、UPDATE、およびDELETE操作は、行の粒度で一次インデックスおよびすべての二次インデックスに適用され、トランザクションが保証されます。 カラムストアを二次インデックスとして実装するソリューションは、このトランザクション処理フレームワークを再利用できます。

  • 2次インデックスとして実装された列ストアは、他の行ストアインデックスと同じデータエンコード形式を使用できます。 メモリコピーで十分です。 ユーザーは、文字セットや照合順序などの情報を考慮する必要はありません。

  • セカンダリインデックスは柔軟に管理できます。 ユーザーは、ユーザーがテーブルを作成するときにインデックス内の列を指定できます。 ユーザーは、DDLステートメントを使用して、後続の操作でセカンダリインデックスの列を追加または削除することもできます。 たとえば、解析が必要なINT、FLOAT、DOUBLE列を列インデックスに追加できます。 通常、ポイントクエリにのみ含まれるが、多くのスペースを占めるTEXTおよびBLOBフィールドは、行ストアに保持できます。

  • クラッシュ回復プロセスでは、InnoDBのredoトランザクションログモジュールを再利用して、既存の実装とのシームレスな互換性を確保できます。 これにより、PolarDBの物理レプリケーションプロセスも容易になります。 列ストアインデックスは、分析サービスを提供するために独立したROノードまたはスタンバイノードで生成できます。

  • セカンダリインデックスは、プライマリインデックスと同じライフサイクルを持ちます。 ユーザーは、セカンダリインデックスを便利に管理できます。

    image.png

前の図に示すように、PolarDBのすべてのプライマリインデックスとセカンダリインデックスはB + ツリーとして実装されています。 カラムインデックスは、定義によるインデックスですが、インデックスによってカバーされるカラムに対する追加、削除、および変更操作をキャプチャするために使用される仮想インデックスです。

上の表の場合、プライマリインデックスには5つの列 (C1、C2、C3、C4、およびC5) のデータが含まれ、セカンダリインデックスには2つの列 (C2とC1) のデータが含まれます。 共通の二次インデックスにおいて、C2およびC1は、1つの行に符号化され、B + ツリーに格納される。 カラム・ストア・インデックスは、3つのカラム (C2、C3、およびC4) のデータを含む。 実際の物理ストレージでは、3つの列が分割され、独立して格納されます。 各列は、書き込み順序に基づいて列ストア形式に変換されます。

カラムストアを二次インデックスとして実装する別の利点は、エグゼキュータのエンジニアリング実装が非常に簡単であることです。 カバーインデックスの用語はMySQLにすでに存在します。つまり、クエリに必要なすべての列がセカンダリインデックスに格納されます。 このセカンダリインデックスのデータは、クエリ要件を満たすために直接使用できます。 一次インデックスと比較して、二次インデックスの使用は、読み取られるデータの量を大幅に削減し、したがって、クエリのパフォーマンスを向上させることができる。 クエリに必要なすべての列が列列インデックスでカバーされている場合、列ストアを高速化すると、クエリのパフォーマンスが数十倍または数百倍向上します。

列指向データの整理

列インデックスの各列は、順序付けられていない形式で格納され、追加書き込みモードを使用します。 スペースの再利用は、バックグラウンドでラベル削除と非同期コンパクションを使用することによって達成されます。 特定の実装には、次の重要なポイントがあります。

  • 列インデックスのレコードは、行グループに基づいて整理されます。 各行グループには64,000行が含まれます。 各行グループの異なる列は、データパックを形成するためにパッケージ化される。

  • 各行グループは追加書き込みモードを使用し、各列に属するデータパックも追加書き込みモードを使用します。 列インデックスの場合、アクティブな行グループのみが新しい書き込みを受け入れます。 行グループがいっぱいになると、フリーズします。 行グループに含まれるすべてのデータパックは圧縮されてディスクに格納され、各データブロックの統計はフィルタリングを容易にするために記録されます。

  • 列指向の行グループに書き込まれた各新しい行には、位置決めのための行IDが割り当てられる。 システムは、行IDを使用して、行に属するすべての列の位置を計算します。 同時に、システムは、その後の削除および変更操作をサポートするために、主キーから行IDへのマッピングインデックスを維持する。

  • 更新操作は、ラベル削除に基づいて実施される。 削除操作を実行するために、ユーザーはビットマップを直接指定できます。 更新操作を実行するには、ユーザーは行IDに基づいて元の位置を計算し、削除ラベルを指定してから、アクティブな行グループに新しいデータを書き込みます。

  • 行グループ内の無効なレコードの数が特定のしきい値を超えると、バックグラウンドで非同期コンパクションがトリガーされます。 一方では、非同期コンパクションはスペースを再利用するために使用されます。 一方、非同期コンパクションは、効果的なデータストレージをよりコンパクトにし、分析クエリ順序の効率を向上させることができます。

    image.png

このデータ編成方法は、分析クエリ中のバッチスキャンと列によるフィルタリングの要件を満たします。 さらに、TPトランザクション操作への影響は非常に小さいです。 書き込み操作の場合、ユーザーは列ごとにメモリにデータを追加するだけで済みます。 削除操作の場合、ユーザーは削除ラベルを指定するだけで済みます。 更新操作は、ラベル削除および追加書き込みを含む。 列ストアは、OLTPパフォーマンスを低下させることなく、トランザクションレベルの更新をサポートします。

完全および増分行から列への変換

行から列への操作は、次の場合に実行されます。

  • ケース1: ユーザーが既存のテーブルの分析要件を持っている場合、DDLステートメントを使用して一部の列に列インデックスを作成します。 ユーザーは、テーブル全体のデータをスキャンして列インデックスを作成する必要があります。

  • ケース2: 行から列への操作は、トランザクション操作に含まれる列に対して実行されます。

フルテーブルの行から列への変換の場合、ユーザーは並列スキャンを使用してInnoDBの主キーをスキャンし、関係するすべての列を列ストア形式に順番に変換できます。 この操作は非常に高速で、I/Oスループット速度とサーバー上の利用可能なCPUリソースによってのみ制限されます。 この操作はオンラインDDLプロセスであり、オンラインサービスの実行をブロックしません。

image.png

列インデックスがテーブルに作成された後、すべての更新トランザクションが行指向データと列指向データを同時に更新して、行指向データと列指向データのトランザクションの一貫性を確保します。 次の図は、IMCI機能が無効および有効の場合の違いを示しています。

  • IMCI機能が無効になっている場合、トランザクションによるすべての行への更新が最初にロックされます。 次に、データページが修正される。 すべてのロックされたレコードは、トランザクションがコミットされる前に一度にロック解除されます。

  • IMCI機能を有効にすると、トランザクションシステムは列ストアの更新キャッシュを作成します。 すべてのデータページが変更されると、列ストアの変更操作が記録されます。 トランザクションが終了し、ロックされたレコードがアンロックされる前に、更新キャッシュが列ストアシステムに適用されます。

image.png

一般的なOLTP要求の場合、メモリデータページを更新するのに費やされる時間は、トランザクション動作プロセスのごく一部のみを占める。 したがって、この方法は、TPトランザクションのレイテンシにほとんど影響を与えない。 多数の行で動作する大規模なトランザクションの場合、列インデックスへの更新はリアルタイムで列ストアに直接適用されますが、トランザクションがコミットされる前に更新は公開されません。 これにより、大きなトランザクションのコミット待ち時間が非常に短い時間範囲内で増加することが保証される。 TPパフォーマンスへの影響をさらに減らすために、APクエリにデータの適時性に対する高い要件がない場合、列インデックスの更新を列ストアに非同期に適用できます。

列ストアは、行ストアと同じレベルのトランザクション分離を提供します。 書き込み操作ごとに、行グループの各行は、行を変更するトランザクションのIDを記録します。 削除ビットマップ内のラベル削除操作ごとに、操作のトランザクションIDも記録されます。 トランザクションIDの書き込みと削除により、APクエリは、非常に軽量な方法でグローバルに一貫したスナップショットを取得できます。

円柱状インデックスの大まかなインデックススキーム

前述のストレージフォーマットからわかるように、IMCI内のすべてのデータパックは順序付けされておらず、追加書き込みモードを使用します。 したがって、InnoDBの通常の順序付けられたインデックスほど正確に要件を満たさないデータを除外することは不可能です。 IMCIでは、ユーザーは統計を使用してデータブロックをフィルタリングし、データアクセスの単価を下げることができます。

  • 各アクティブなデータパックの書き込みが完了すると、システムは事前にコンピューティングを実行します。 次に、システムは、最小値、最大値、値の合計、ヌル値の数、およびレコードの総数を含む情報をデータパックに生成する。 全ての情報は、データパックのメタデータ領域に保持され、メモリに存在する。 データ削除操作は凍結されたデータパックに含まれるため、統計の更新と維持はバックグラウンドで実行されます。

  • クエリ要求の場合、データパックは、クエリ条件に基づいて、関連データパック、無関係データパック、および場合によっては関連データパックに分類される。 これにより、実際のデータブロックアクセスが減少する。 カウントや合計などの一部の集計クエリ操作では、ユーザーは事前に計算された統計値に対して簡単な操作を実行できます。 これらのデータブロックは、解凍される必要さえない。

image.png

統計に基づく大まかなインデックススキームは、一部のデータを正確に見つける必要がある一部のクエリにはあまり適していません。 しかしながら、ハイブリッド行 − 列ストアエンジンでは、列インデックスは、大量のデータのスキャンを伴うクエリを加速することを支援するだけでよい。 このシナリオでは、IMCIには大きな利点があります。 少量のデータのみにアクセスするSQLクエリの場合、オプティマイザは通常、コストモデルを使用して、行ストアに基づいてより費用対効果の高いソリューションを計算します。

ハイブリッド行列ストアソリューションでのTPおよびAPリソースの分離

PolarDBのハイブリッド行-列ストアソリューションは、1つのクラスターでAPクエリとTPクエリの両方をサポートします。 しかしながら、多くのサービスは、高いOLTP負荷を有し、突然のOLAP負荷は、TPサービスの応答待ち時間に干渉し得る。 したがって、HTAPデータベースでは負荷分離をサポートする必要があります。 PolarDBのwrite-once-read-manyアーキテクチャにより、ユーザーはAPロードとTPロードを簡単に分離できます。 PolarDBの技術アーキテクチャに基づいて、次の展開モードがサポートされています。

  • モード1: ハイブリッド行-列ストアソリューションは、読み取り /書き込み (RW) ノードで有効になります。 このモードは、軽量APクエリをサポートします。 このモードは、TP負荷が主に使用され、AP要求が比較的少ない場合に適しています。 PolarDBを使用してレポートをクエリし、データがバッチデータのインポートから取得された場合にも、このモードを使用できます。

  • モード2: RWノードはOLTP負荷をサポートし、APタイプROノードは、クエリをサポートするためのハイブリッド行 − 列ストア解決策を有効にするために起動される。 このモードでは、CPUリソースを完全に分離することができ、APタイプのROノードのすべてのメモリを列ストアとエグゼキュータに割り当てることができます。 しかし、同じ共有ストレージが使用されるので、I/Oは影響を受ける。

  • モード3: RWノードとROノードの両方がOLTPロードをサポートし、ハイブリッド行列ストアソリューションは、APクエリをサポートするために別のスタンバイノードで有効になります。 スタンバイノードは独立した共有ストレージクラスターを使用するため、このモードでは、モード2で実現されるCPUとメモリリソースの分離に加えて、I/Oリソースの分離も実現できます。

image.png

さまざまなレベルのリソース分離をサポートする前述のさまざまなデプロイメントアーキテクチャに加えて、PolarDBでは、並列に実行する必要のある大規模なクエリで自動並列度 (Auto DOP) がサポートされています。 このメカニズムは、現在のシステム負荷と利用可能なCPUおよびメモリリソースとを考慮に入れ、単一のクエリで使用できるリソースを制限します。 これにより、1つのクエリが多くのリソースを消費し、他の要求の処理に影響を与えることを防ぎます。

OLAPパフォーマンス

詳細については、「IMCIパフォーマンス」をご参照ください。