ColumnStoreストレージアーキテクチャー
Contents
ストレージアーキテクチャー
MariaDB ColumnStoreにてテーブルが作られる際、カラムごとに少なくとも1つのファイルが作成されます。例えば、3カラムのテーブルが作成される場合には、最低3個のファイルがSANやディスクに作成されます。
- 各カラムはエクステントと呼ばれる800万行のファイルとして保存されます。1byteのデータ型のエクステントは8MBとなり、2byteなら16MB、4byteなら32MB、8byteなら64MB、また可変データ型の場合も、64MBとなります。Extentがいっぱいになると、新しいエクステントが自動生成されます。
- エクステントは一連のブロックとして物理的に保存されます。
- ブロックは8KBです。全てのデータベースブロックは、論理ブロック識別子(LBID)により一意に識別されます。
- 8文字以上のStringカラムはメインのカラムファイルにインデックスを保存し、実際の値は別の辞書ファイルに格納されます。
- Segmentファイルはカラムのデータを保持するディスク上の物理ファイルです。セグメントファイルがエクステントの最大数に達すると、新しいセグメントファイルが自動的に作られます。セグメントファイル内の最大エクステント数は、ColumnStore.xmlファイル内のExtentsPerSegmentFileに記載されており、Db Rootsの倍数を設定する必要があります。デフォルト値は4です。
- 集合的に、1つ以上のエクステントに相当する全てのカラムセグメントファイルはパーティションとなります。これはカラムストアにおける水平パーティショニングです。
- パーティションはフォルダなどのような階層構造に保存されます。
- MariaDB ColumnStoreメタストアは、パーティションに使用される情報と同様に、DBスキーマへのファイル構造・ファイル一をマップします。パーティションごとの最大ファイル数は、ColumnStore.xmlファイルのFilesPerColumnPartitionに記載しており、デフォルト値は2です。
- デフォルトではデータは圧縮されています。
エクステントマップ
MariaDB ColumnStoreは、論理範囲パーティショニングを実現し、インデックスや手作業によるパーティショニング、マテリアライズドビュー、サマリーテーブル、その他の構造やオブジェクトを不要にするエクステントマップとして知られる、スマートな構造を採用しています。これらの行指向の(通常の)データベースでクエリパフォーマンスを得るためのチューニングは不要です。
エクステントは物理セグメントファイル内に存在する領域の論理ブロックで、8~64MBのサイズとなります。各エクステントは、同じ行数となり、小さなデータタイプではエクステントのサイズも小さくなります。
エクステントマップは全エクステントと関連するブロック(LBID)を、エクステント内のデータの最小値と最大値とともに保持しています。
エクステントマップのマスターデータはメインのパフォーマンスモジュールに存在します。システム起動時にメモリ内に読み込まれ、他のすべてのユーザーモジュールおよびパフォーマンスモジュールにコピーされます。これはディザスターリカバリーおよびフェイルオーバーの目的のためです。全てのノードは高速なアクセスのためにエクステントマップをメモリ内に保持します。エクステントが更新されると、更新情報がすべてのノードへ伝達されます。
エクステントマップの動作の仕組み
エクステントマップは論理範囲によるパーティショニングとクエリ処理に必要なブロックのみへのアクセスを実現します。これはMariaDB ColumnStoreにおいて、いわゆる"エクステント除外"機構により実現されます。"エクステント除外"により、クエリの結合やフィルタに必要のないエクステントを除外し、I/O処理を減らすことが可能となります。
エクステント除外機構はMariaDB ColumnStoreにより、結合やフィルタに必要なカラムのみをスキャンすることにより実現されます。 その後、各エクステントで保持している最大値と最小値の情報を参照し、さらなる除外を行います。フィルタ処理においてカラムをスキャンする際にエクステントを除外するには、フィルタの値と、各エクステントの最大値と最小値を比較することにより実現されます。もしフィルターの値がエクステントの最大値と最小値の範囲外であれば、そのエクステントは除外されることになります。
この自動のエクステント除外機構は、系列データ、整列されたデータ、パターン化されたデータや、時間で頻繁に参照されるような時系列データに非常に適しています。また、グループ化されているような値を保持するカラムにも適しています。
例:
リアルタイム解凍と圧縮
カラム型ストレージは、似たデータがそれぞれのカラムファイルに格納されているため、優れた圧縮性能を実現します。ほとんどのデータは優れた圧縮率を示し、65%から95%のストレージ容量の節約を実現します。ただし、実際の圧縮率は、格納されているデータのランダム性やユニークな値の数に依存します。
MariaDB ColumnStoreの圧縮ストラテジーは、優れた圧縮性能を維持しつつも、読み込みのパフォーマンスを重視しています。圧縮率を向上させるよう調整することで、ディスクからの読み込み時のパフォーマンスを最適化することにもつながります。これにより、I/O限界のあるシステムでもパフォーマンスを改善することが可能となります。
圧縮モード
デフォルトでは圧縮が有効になっています。しかしながら、テーブルごとに、またはカラムごとに制御することも可能です : infinidb_compression_type参照 圧縮が有効な場合、MariaDB ColumnStoreではsnappy圧縮を使用します。
バージョンバッファー
MariaDB ColumnStoreは、修正されるディスクブロックを保持するバージョンバッファーを備えています。これにより、MVCC(multi-version concurrency control)サービスのようなトランザクションのロールバック操作や、データベースのクエリー一貫性のビューを提供可能なデータベースの"スナップショット読み込み"機能を提供します。MariaDB ColumnStoreの全てのステートメントは、データベースのある時点でのバージョン(or スナップショット)で実行される。その番号やシステム変更番号(SCN, System Change Number)と呼ばれます。バージョンバッファーと呼ばれていますが、メモリとディスクの双方で実現されています。
バージョンバッファーファイルの動作の仕組み
バージョンバッファーはメモリ内にハッシュテーブルを展開し、実行中のトランザクション情報へのアクセスを提供します。起動直後の初期サイズは4MBのメモリですが、トランザクションにより修正されるブロックが増えるにしたがって、サイズが大きくなります。ハッシュテーブル内の各エントリーは8Kブロックの修正に対する40バイトの参照データです。
更新される行数はバージョンバッファーを制限する要因ではなく、むしろ、更新されるディスクブロックの数が重要となります。サイズを増やすことはできますが、より多いディスクブロックの更新は、更新や削除の処理に多くの時間を要するようになり、問題発生時のロールバックにもより多くの時間がかかるようになるため注意が必要です。
バージョンバッファーファイルは各DBRootに対して1GBのサイズですが、VersionBufferFileSizeパラメータで設定可能です。バージョンバッファーファイルは、システム内の各DBRootに伝播されます。
メモ: HDFS上のMariaDB ColumnStoreは現在のリリースではまだテストされていません。この機能はInfiniDBから引き継いでおり、HDFS上でHadoopクエリとして動作するよう構成されます。このモードではMVCC機能は(すなわちバージョンバッファーファイルの使用も)無効となります。HDFSは書き込みのみが可能なファイルシステムなため、MVCCモデルにおけるブロックレベルのバージョン管理は実質的ではありません。MariaDB ColumnStoreでは、HDFS上で動作する場合にはDML操作に対してのステートメントレベルの追跡とロールバックをサポートします。HDFS上のクエリーは、更新処理が終了した際にクエリが正しい結果を返すよう"最終的な整合性"モードで動作します。ただし、更新処理と同時に発行されたクエリは、ブロックレベルの実行が発生した時点のブロックの情報を使用します。
トランザクションログ
MariaDB ColumnStoreはMariaDB Serverのbinary logにコミットされたトランザクションのログをサポートします。