背景紹介
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データベースへのデータインポートの機能を体験することができます。当然のことながら、TPC-H、TPC-DSなどのAPベンチマーク上にダイレクトロードを使用してデータを準備することもできます。本チュートリアルでは、ダイレクトロード技術を使用する大量データの高速インポートによる、OceanBaseの効率的な機能を体験する方法を説明します。
適用シナリオ
- APシナリオデータの準備:例:ClickHouseベンチマーク、TPC-H/TPC-DSなどの分析型テスト。
- 一括書き込みの高速化:
INSERT INTO SELECTなどの高スループット書き込み操作に代わります。
ダイレクトロード技術を用いることで、データインポートの効率を大幅に向上させることができます。膨大な量のデータを迅速に読み込む必要があるシナリオに適しています。
技術アーキテクチャ
データをインポートする方法は2つあります。
従来のパス:従来のパスは、SQLクエリ、トランザクション処理、データストレージなどの一連のモジュールを経由します。
ダイレクトロードパス:一方、ダイレクトロードパスは、主にインポートされたデータのタイプを変換し、主キー(存在する場合)に基づいてソートし、最後にソートされたデータを Major SSTable に書き込みます。ダイレクトロードは一種のショートカットであり、システムリソースの消費を削減し、インポートの速度を向上させることができます。
前提条件
環境の準備
環境要件:
- OceanBase V4.3以降のバージョンのクラスタをデプロイし、MySQLモードのテナントを作成していること。
- 本実験では、16c32g(16コア、32GBメモリ)のリソース構成を使用します。以降のすべての手順およびテスト結果は、この設定に基づいて実行されます。
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(16コア、32GBメモリ)のリソース構成で実施します。実行環境によって実行時間に差異が発生する場合があります。上記の表に記載されている実行時間は参考値です。
結論:ダイレクトロードにより速度が 3倍以上 向上しました。ダイレクトロードは大規模なデータインポートシナリオ(例:TPC-H/TPC-DSテストデータ準備など)に適しています。