Lindorm 列指向ストレージは、データを列単位で格納および処理するカラムナ分散ストレージサービスです。行指向ストレージと比較して、クエリ応答時間を短縮し、I/O リソースを節約します。Lindorm コンピュートエンジンを使用して、名前空間とテーブルの作成、データの読み書き、ファイルのコンパクション、階層化ストレージの設定を行います。
概要
列指向ストレージは、車両インターネット(IoV)、モノのインターネット(IoT)、注文、およびログなどのシナリオにおいて、大量の半構造化データおよび構造化データに適しています。主な機能には以下が含まれます:
コンピューティングと分析:列指向データに対してインタラクティブな分析とオンラインコンピューティングを実行します。豊富なインデックス機能により、データの特定を高速化します。SQL ステートメントを使用して、大量のプライマリキーデータの追加、削除、変更、クエリを実行します。
高スループット:水平スケーリングをサポートし、毎分テラバイト規模のデータを読み書きする能力を備えています。これは、迅速な IoV データインポート、モデル訓練データセットへのアクセス、大規模なレポート分析に適しています。
コスト効率:カラムナ高圧縮率アルゴリズム、高密度低コストメディア、コールド・ホットデータ分離、圧縮エンコーディング、コールドデータアーカイブストレージを使用して、ストレージコストを削減します。
高可用性:イレイジャーコーディングを使用して、分散データセットの高可用性を確保し、単一障害点 (SPOF) のリスクを排除します。
オープンソース互換性:Iceberg API と互換性があり、Spark や Flink などのコンピュートエンジンに接続して、主流のデータエコシステムにシームレスに統合できます。
コールド・ホットデータ分離:ビジネス要件に基づいて、コールドデータとホットデータを異なるストレージメディアに格納することで、パフォーマンスのオーバーヘッドを削減し、ストレージコストを低減します。
前提条件
開始する前に、次のことを確認してください:
注意事項をお読みください
ご利用のジョブモードに合わせて接続設定を完了してください:
JDBC ジョブ:「アプリケーション開発での JDBC の使用」
JAR ジョブ:「Java でのジョブの作成」
Python ジョブ:「Python でのジョブの作成」
(任意) コールド・ホットデータ分離を使用する場合:「容量ストレージの有効化」
DDL
名前空間
テーブル
パーティション
DML
テーブル
パーティション管理
時間の経過とともに、増分書き込みによって多数の小規模ファイルが生成されます。これらのファイルをより大きなファイルにコンパクションすることで、データとメタデータの冗長性が減り、クエリパフォーマンスが向上します。rewrite_data_files または rewrite_manifest を使用してコンパクションをトリガーします。
どちらのコマンドもデータベースリソースを消費します。オフピーク時間に実行してください。
テーブル内のすべてのファイルをコンパクションします:
USE lindorm_columnar;
CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable');特定のパーティション内のファイルをコンパクションします:
USE lindorm_columnar;
CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable', where => 'city=\"beijing\"');テーブルマニフェストを再書き込みします:
USE lindorm_columnar;
CALL lindorm_columnar.system.rewrite_manifest('mydb.mytable');完全なコマンドリファレンスについては、「rewrite_data_files」および「rewrite_manifest」をご参照ください。
ホットデータおよびコールドデータのストレージ
Lindorm は、3レベル (L1、L2、L3) のコールド・ホットデータ分離をサポートしています。頻繁にアクセスされるデータは高性能ストレージに保持され、古いデータは自動的に低コストのストレージに移動されます。データレイクサービスは非同期にダンプを処理します。このプロセス中もクエリは利用可能ですが、アクセスパフォーマンスはストレージ階層によって異なります。
列指向データのコールド・ホット自動変換を有効にするには、Lindorm のテクニカルサポート (DingTalk ID: s0s3eg3) にご連絡ください。
コールド・ホット分離ポリシーは、時間パーティションにのみ基づいています。
CHS パラメーター
テーブルを作成または変更する際に、TBLPROPERTIES でコールド/ホットストレージ (CHS) 属性を設定します。
| パラメーター | 説明 | フォーマット | デフォルト |
|---|---|---|---|
CHS | データがストレージレベル間を移動するタイミングを決定する時間しきい値 (秒単位)。値が 1 つの場合は L1/L2 の分割。値が 2 つ (num0, num1、ただし num0 < num1) の場合は L1/L2/L3 の分割。 | 長整数、単位:秒 | — |
CHS_L1 | L1 (ホット) 階層のストレージタイプ | 'CHS_L1'='storagetype=<storage type>' | CAPACITY_CLOUD_STORAGE |
CHS_L2 | L2 階層のストレージタイプ。CHS が設定されている場合に必須です。 | CHS_L1 と同じフォーマットとして CHS_L1 | — |
CHS_L3 | L3 (最もコールドな) 階層のストレージタイプ。CHS に 2 つの値が設定されている場合に必須です。 | 形式はCHS_L1 | — |
CHS_EXP | CHS しきい値と比較するために、時間パーティションフィールドからデータ時間を抽出する式。 | toSec(col0, pattern0, col1, pattern1, ...) | — |
サポートされるストレージタイプ
クラウドストレージの場合:CAPACITY_CLOUD_STORAGE (デフォルト)、STANDARD_CLOUD_STORAGE、PERFORMANCE_CLOUD_STORAGE、CLOUD_ARCHIVE_STORAGE
アーカイブストレージ (CLOUD_ARCHIVE_STORAGE) は内部プレビュー段階です。有効にするには、Lindorm のテクニカルサポート (DingTalk ID: s0s3eg3) にご連絡ください。ローカルディスクの場合:CAPACITY_CLOUD_STORAGE (デフォルト)、LOCAL_SSD_STORAGE、LOCAL_HDD_STORAGE、LOCAL_EBS_STORAGE
`CHS_EXP` パターントークン
| パターントークン | 意味 |
|---|---|
yyyy | 年 |
MM | 月 |
dd | 日 |
HH | 時 |
mm | 分 |
toSec() 関数は、一致するパーティションの最大データ時間を計算します。たとえば、パーティション year=2023, month=10, day=2 の場合:
toSec(year, yyyy)は2023-12-31 23:59:59を返しますtoSec(year, yyyy, month, MM)は2023-10-31 23:59:59を返しますtoSec(year, yyyy, month, MM, day, dd)は2023-10-02 23:59:59を返します
単一の結合された日付フィールド、たとえば date=2023-10-02 の場合:
toSec(date, yyyy-MM-dd)は2023-10-02 23:59:59を返します
例
例 1:1 か月 (2,592,000 秒) より古いデータを容量ストレージ (L2) に移動します:
CREATE TABLE table0 (col0 INT, year STRING, month STRING, day STRING)
PARTITIONED BY (year, month)
TBLPROPERTIES (
'CHS' = '2592000',
'CHS_L2' = 'storagetype=CAPACITY_CLOUD_STORAGE',
'CHS_EXP'= 'toSec(year,yyyy,month,MM,day,dd)'
);例 2:table0 のポリシーを更新します。1 か月より古いデータを容量ストレージに移動し、3 か月 (5,184,000 秒) より古いデータをアーカイブストレージに移動します:
ALTER TABLE table0
SET TBLPROPERTIES (
'CHS' = '2592000,5184000',
'CHS_L2' = 'storagetype=CAPACITY_CLOUD_STORAGE',
'CHS_L3' = 'storagetype=CLOUD_ARCHIVE_STORAGE',
'CHS_EXP'= 'toSec(year,yyyy,month,MM,day,dd)'
);例 3:単一の dt パーティションフィールド (フォーマット:yyyy/MM/dd、例:2020/12/1) を持つテーブルを作成します。1 か月より古いデータを容量ストレージに移動し、3 か月より古いデータをアーカイブストレージに移動します:
CREATE TABLE table1 (col0 INT, dt STRING)
PARTITIONED BY (dt)
TBLPROPERTIES (
'CHS' = '2592000,5184000',
'CHS_L2' = 'storagetype=CAPACITY_CLOUD_STORAGE',
'CHS_L3' = 'storagetype=CLOUD_ARCHIVE_STORAGE',
'CHS_EXP'= 'toSec(dt,yyyy/MM/dd)'
);注意事項
テーブルの作成時に
CHSを設定するか、後でALTER TABLE ... SET TBLPROPERTIESを使用して更新します。CHSが正しく設定されていない場合、テーブルは正常に作成または更新されますが、データはストレージ階層間で自動的に移動されません。ダンプは非同期で実行されます。このプロセス中もデータはアクセス可能ですが、アクセスパフォーマンスはストレージ階層によって異なる場合があります。
コールド・ホット分離は、時間ベースのパーティションでのみサポートされます。
ベストプラクティス
ポイントクエリのためのプライマリキーの指定
プライマリキールックアップは最速のクエリパスです。大規模なテーブルでは、最高のパフォーマンスを得るために、プライマリキーを指定し、狭いキー範囲内でクエリを実行してください。
サンプルテーブル:
USE lindorm_columnar;
CREATE TABLE orders (
o_orderkey INT NOT NULL,
o_custkey INT,
o_orderstatus STRING,
o_totalprice DOUBLE,
o_orderdate STRING,
o_orderpriority STRING,
o_clerk STRING,
o_shippriority INT,
o_comment STRING)
PARTITIONED BY (bucket(1024, o_orderkey))
TBLPROPERTIES (
'primary-key' = 'o_orderkey');ポイントルックアップ:
USE lindorm_columnar;
SELECT * FROM orders WHERE o_orderkey = 18394;範囲スキャン (狭い範囲の方がパフォーマンスが向上します):
USE lindorm_columnar;
SELECT count(*) FROM orders WHERE o_orderkey > 100000 AND o_orderkey < 200000;データの分離のためのパーティションの追加
列指向ストレージエンジン内のパーティションは物理的に分離されています。パーティションキーでフィルター処理するクエリは、関連のないパーティションを完全にスキップします。
日付パーティションを持つサンプルテーブル:
USE lindorm_columnar;
CREATE TABLE orders (
o_orderkey INT NOT NULL,
o_custkey INT,
o_orderstatus STRING,
o_totalprice DOUBLE,
o_orderdate STRING NOT NULL,
o_orderpriority STRING,
o_clerk STRING,
o_shippriority INT,
o_comment STRING)
PARTITIONED BY (o_orderdate, bucket(1024, o_orderkey))
TBLPROPERTIES (
'primary-key' = 'o_orderdate,o_orderkey');1 日分のデータをクエリします:
USE lindorm_columnar;
SELECT o_orderdate, count(*) FROM orders WHERE o_orderdate = '2022-01-01' GROUP BY o_orderdate;日付範囲をクエリします:
USE lindorm_columnar;
SELECT o_orderdate, count(*)
FROM orders
WHERE o_orderdate >= '2022-01-01' AND o_orderdate <= '2022-01-07'
GROUP BY o_orderdate;データコンパクションによるスキャンパフォーマンスの向上
rewrite_data_files によるコンパクション後、データは各パーティション内でプライマリキーによってソートされ、スキャンパフォーマンスが大幅に向上します。コンパクションされたデータのみをクエリし、増分書き込みをスキップするには、read.scan-major-rewritten-files-only を true に設定します。
サンプルテーブル:
CREATE TABLE mydb.mytable (
id INT NOT NULL,
city STRING NOT NULL,
name STRING,
score INT)
PARTITIONED BY (city, bucket(4, id))
TBLPROPERTIES (
'primary-key' = 'id,city');テーブル全体をコンパクションします:
CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable');特定のパーティションをコンパクションします:
CALL lindorm_columnar.system.rewrite_data_files(table => 'mydb.mytable', where => 'city=\"beijing\"');クエリをコンパクションされたデータのみに制限します:
ALTER TABLE mydb.mytable SET TBLPROPERTIES ('read.scan-major-rewritten-files-only' = true);| 値 | 動作 |
|---|---|
true | コンパクションされたデータのみをクエリします。増分データは除外されます |
false (デフォルト) | 増分書き込みを含むすべてのデータをクエリします |
ソートキーによる非プライマリキーのクエリの高速化
コンパクション後、データはプライマリキーによってソートされます。非プライマリキー列に対するクエリを高速化するには、ソートキーを指定してからデータを再コンパクションします。
ソートキーを指定した後、高速化のパフォーマンスを確保するためにパーティション内のデータを再書き込みする必要があります。再書き込みされたデータのみがクエリ可能で、増分データはクエリできません。
サンプル表:
USE lindorm_columnar;
CREATE TABLE orders (
o_orderkey INT NOT NULL,
o_custkey INT,
o_orderstatus STRING,
o_totalprice DOUBLE,
o_orderdate STRING,
o_orderpriority STRING,
o_clerk STRING,
o_shippriority INT,
o_comment STRING)
PARTITIONED BY (bucket(1024, o_orderkey))
TBLPROPERTIES (
'primary-key' = 'o_orderkey',
'read.scan-major-rewritten-files-only' = 'true');ソートキーを設定する:
ALTER TABLE orders WRITE ORDERED BY o_shippriority, o_totalprice;ソート順を適用するには、[Compact]:
CALL lindorm_columnar.system.rewrite_data_files(table => 'orders');ソートキーを使用したクエリ:
USE lindorm_columnar;
SELECT count(*) FROM orders WHERE o_shippriority = 0;USE lindorm_columnar;
SELECT count(*) FROM orders WHERE o_shippriority = 0 AND o_totalprice > 999.9;