背景
OceanBaseでは現在、主に Load Data、obloader、OMS の3つのデータインポート方法が使用されています。いずれも INSERT ステートメントを用いてデータを書き込みます。しかし、INSERT 操作は SQLクエリ、トランザクション処理、LSM-Treeストレージ などのプロセスを経由する必要があります。OceanBaseは LSM-Treeストレージ構造 を採用しているため、INSERT データはまずメモリテーブル(MemTable)に書き込まれ、その後、複数回の ダンプ(Flush) と メジャーコンパクション(Compaction) を経て最終的に SSTable に格納されます。このプロセスでは大量のCPUリソースを消費するため、インポート速度が遅くなります。
この問題を解決するため、OceanBaseは ダイレクトロード技術 を導入し、中間処理のステップをバイパスし、データを直接下層の Major SSTable に書き込みます。この技術はデータインポートだけでなく、大量の書き込みを必要とするSQL操作(例:INSERT INTO SELECT)の高速化にも適用できます。
ClickBench は、ClickHouseが提案したAPベンチマークです。このAPベンチマークを使用して、APシナリオにおけるOceanBaseデータベースのクエリ性能をテストできます。このベンチマークを実行する前に、まずデータをインポートする必要があります。データのインポート というステップで、OceanBaseデータベースのデータインポート性能を体験することができます。もちろん、TPCH、TPCDSなどのAPベンチマークでもダイレクトロードを使用してデータを準備できます。このチュートリアルでは、ダイレクトロード技術を使用して大量データのインポートを高速化し、OceanBaseの高性能を体験する方法を説明します。
適用シナリオ
- APシナリオのデータ準備:ClickHouseベンチマーク、TPC-H/TPC-DSなどの分析系テスト。
- バッチ書き込みの高速化:
INSERT INTO SELECTなどの高スループット書き込み操作に代わる方法。
ダイレクトロード技術により、データインポートの効率を大幅に向上させることができます。大量のデータを迅速に読み込む必要があるシナリオに適しています。
技術アーキテクチャ
データインポートには2つのパスがあります。
従来のパス:青い矢印で示された従来のパスは、SQLクエリ、トランザクション処理、データストレージなど一連のモジュールを経由する必要があります。
ダイレクトロードパス:緑色の矢印で示されたダイレクトロードパスは、主にインポートされるデータの型変換を行い、主キーでソート(存在する場合)、その後ソート済みのデータをメジャーSSTableに書き込みます。ダイレクトロードは短いパスであり、システムリソースの消費を削減し、インポート速度を向上させることができます。
以下の図のように:

前提条件
環境の準備
環境要件:
- OceanBase V4.3以降のバージョンのクラスタがデプロイ済みで、MySQLモードのテナント環境が作成されていることを確認してください。
- この実験では、リソース構成は16c32gを使用します。以降のすべての手順およびテスト結果は、この設定に基づいて実施されます。
OceanBaseクラスタのデプロイ方法については、デプロイの概要を参照してください。デプロイが完了したら、sysテナントで以下のSQLステートメントを実行して、クラスタとテナントの情報を確認できます:
-- クラスタ情報の確認 SELECT * FROM GV$OB_SERVERS; -- テナント情報の確認 SELECT * FROM oceanbase.DBA_OB_TENANTS;権限要件:
作成したテナントが
INSERTおよびSELECT権限を持っていることを確認してください。OceanBaseデータベースの権限の詳細については、MySQLモードの権限分類を参照してください。
データの準備
テストデータのダウンロード
ClickHouse公式Webサイトにアクセスし、hitsデータセットをダウンロードします。
データを指定のパスに解凍します(例:
/path/to/hits.tsv)。
手順
ステップ1:カラムストアテーブルを作成する
テーブル作成ステートメントを実行します(カラムストアテーブルは
WITH COLUMN GROUPで定義します):CREATE TABLE hits ( WatchID BIGINT NOT NULL, JavaEnable SMALLINT NOT NULL, Title TEXT NOT NULL, GoodEvent SMALLINT NOT NULL, EventTime TIMESTAMP NOT NULL, EventDate Date NOT NULL, CounterID INTEGER NOT NULL, ClientIP INTEGER NOT NULL, RegionID INTEGER NOT NULL, UserID BIGINT NOT NULL, CounterClass SMALLINT NOT NULL, OS SMALLINT NOT NULL, UserAgent SMALLINT NOT NULL, URL TEXT NOT NULL, Referer TEXT NOT NULL, IsRefresh SMALLINT NOT NULL, RefererCategoryID SMALLINT NOT NULL, RefererRegionID INTEGER NOT NULL, URLCategoryID SMALLINT NOT NULL, URLRegionID INTEGER NOT NULL, ResolutionWidth SMALLINT NOT NULL, ResolutionHeight SMALLINT NOT NULL, ResolutionDepth SMALLINT NOT NULL, FlashMajor SMALLINT NOT NULL, FlashMinor SMALLINT NOT NULL, FlashMinor2 TEXT NOT NULL, NetMajor SMALLINT NOT NULL, NetMinor SMALLINT NOT NULL, UserAgentMajor SMALLINT NOT NULL, UserAgentMinor VARCHAR(255) NOT NULL, CookieEnable SMALLINT NOT NULL, JavascriptEnable SMALLINT NOT NULL, IsMobile SMALLINT NOT NULL, MobilePhone SMALLINT NOT NULL, MobilePhoneModel TEXT NOT NULL, Params TEXT NOT NULL, IPNetworkID INTEGER NOT NULL, TraficSourceID SMALLINT NOT NULL, SearchEngineID SMALLINT NOT NULL, SearchPhrase TEXT NOT NULL, AdvEngineID SMALLINT NOT NULL, IsArtifical SMALLINT NOT NULL, WindowClientWidth SMALLINT NOT NULL, WindowClientHeight SMALLINT NOT NULL, ClientTimeZone SMALLINT NOT NULL, ClientEventTime TIMESTAMP NOT NULL, SilverlightVersion1 SMALLINT NOT NULL, SilverlightVersion2 SMALLINT NOT NULL, SilverlightVersion3 INTEGER NOT NULL, SilverlightVersion4 SMALLINT NOT NULL, PageCharset TEXT NOT NULL, CodeVersion INTEGER NOT NULL, IsLink SMALLINT NOT NULL, IsDownload SMALLINT NOT NULL, IsNotBounce SMALLINT NOT NULL, FUniqID BIGINT NOT NULL, OriginalURL TEXT NOT NULL, HID INTEGER NOT NULL, IsOldCounter SMALLINT NOT NULL, IsEvent SMALLINT NOT NULL, IsParameter SMALLINT NOT NULL, DontCountHits SMALLINT NOT NULL, WithHash SMALLINT NOT NULL, HitColor CHAR NOT NULL, LocalEventTime TIMESTAMP NOT NULL, Age SMALLINT NOT NULL, Sex SMALLINT NOT NULL, Income SMALLINT NOT NULL, Interests SMALLINT NOT NULL, Robotness SMALLINT NOT NULL, RemoteIP INTEGER NOT NULL, WindowName INTEGER NOT NULL, OpenerName INTEGER NOT NULL, HistoryLength SMALLINT NOT NULL, BrowserLanguage TEXT NOT NULL, BrowserCountry TEXT NOT NULL, SocialNetwork TEXT NOT NULL, SocialAction TEXT NOT NULL, HTTPError SMALLINT NOT NULL, SendTiming INTEGER NOT NULL, DNSTiming INTEGER NOT NULL, ConnectTiming INTEGER NOT NULL, ResponseStartTiming INTEGER NOT NULL, ResponseEndTiming INTEGER NOT NULL, FetchTiming INTEGER NOT NULL, SocialSourceNetworkID SMALLINT NOT NULL, SocialSourcePage TEXT NOT NULL, ParamPrice BIGINT NOT NULL, ParamOrderID TEXT NOT NULL, ParamCurrency TEXT NOT NULL, ParamCurrencyID SMALLINT NOT NULL, OpenstatServiceName TEXT NOT NULL, OpenstatCampaignID TEXT NOT NULL, OpenstatAdID TEXT NOT NULL, OpenstatSourceID TEXT NOT NULL, UTMSource TEXT NOT NULL, UTMMedium TEXT NOT NULL, UTMCampaign TEXT NOT NULL, UTMContent TEXT NOT NULL, UTMTerm TEXT NOT NULL, FromTag TEXT NOT NULL, HasGCLID SMALLINT NOT NULL, RefererHash BIGINT NOT NULL, URLHash BIGINT NOT NULL, CLID INTEGER NOT NULL, PRIMARY KEY (CounterID, EventDate, UserID, EventTime, WatchID) ) with column group (each column);
ステップ2:ダイレクトロードを実行する
ダイレクトロード
LOAD DATA
/*+
query_timeout(10000000000)
parallel(32)
direct(true, 0) -- ダイレクトロードモードを有効にする
*/
INFILE '/path/to/hits.tsv'
INTO TABLE hits
FIELDS TERMINATED BY '\t'
ENCLOSED BY ''
ESCAPED BY '';
実行が完了すると、ダイレクトロードの実行時間を確認できます。
非ダイレクトロードの比較
LOAD DATA
/*+
query_timeout(10000000000)
parallel(32)
*/
INFILE '/path/to/hits.tsv'
INTO TABLE hits
FIELDS TERMINATED BY '\t'
ENCLOSED BY ''
ESCAPED BY '';
実行が完了すると、非ダイレクトロードの実行時間を確認できます。
パフォーマンスの比較
シナリオ |
実行時間(秒) |
|---|---|
| ダイレクトロード | 249 |
| ダイレクトロード以外 | 767 |
説明
本実験では、リソース構成は16c32gを使用しました。実行環境によって実行時間に差異が生じる場合があります。上記の表に記載されている実行時間は参考値です。
結論:ダイレクトロードにより速度が 3倍以上 向上し、大規模なデータインポートシナリオ(例:TPC-H/TPC-DSテストデータ準備)に適しています。