MarkLogic ColumnACID特性
はじめに
ACID特性とは、トランザクションを扱うシステムが持つべき性質として定義されているものです。多くのNoSQLデータベースはACID特性を保証しませんが、MarkLogicはACID特性を持っています。
本稿では、「How MarkLogic Supports ACID Transactions」というMarkLogicのブログ記事を基にその内容を説明します。
ACID特性
以下の表にあるような4つの英単語の頭文字を使ってACIDと呼ばれています。
ACID | 訳語 | 説明 |
---|---|---|
Atomicity | 原子性 (不可分性) |
トランザクションに含まれる処理が「すべて実行される」か「1つも実行されない」のどちらかの状態になる。 |
Consistency | 一貫性 (整合性) |
トランザクションの前後でのデータの整合性が保たれ、矛盾の無い状態が継続される。 |
Isolation | 独立性 (隔離性) |
トランザクション実行中の処理過程が外部から隠蔽され、他の処理などに影響を与えない。いわゆる排他制御が行われる。 |
Durability | 耐久性 (永続性) |
トランザクションが完了した結果は記録されて、障害が生じても失われることがない。 |
ACID特性に関連する技術
MarkLogicは一般的にも存在する複数の技術を使って、ACID特性を保証しています。
- 分散された複数のホストであっても、変更されたデータが一度にすべて変更されるか、まったく変更されないことを担保するコミットプロセス
- 更新中にデータを保護し、トランザクションが互いに競合しないようにするためのドキュメント単位でのロック
- クエリが実行時に有効なドキュメントの内容のみを参照するようにするドキュメントのタイムスタンプ設定
- システム障害が発生した場合にトランザクションをリプレイできるように、更新をコミットする前にジャーナリングすること
それぞれの項目について順番に説明していきます。
トランザクションのコミット・分散ホストでのコミット
トランザクションのコミット機能はAtomicity (原子性) に関連します。
トランザクションが正常に終了してコミットすれば、そのトランザクションによる変更がユーザに公開されます。トランザクションが中止した場合などはロールバックして、トランザクション開始前の状態になります。
トランザクションをコミットすると、新しいバージョンには現在の時間に基づく開始タイムスタンプが付けられ、これまでのバージョンには終了タイムスタンプが付けられます。これらは全て同時に行われます。タイムスタンプ情報は、独立したTimestampsファイルに格納され、コミットは1つの操作として実行されます。トランザクションにおいてファイル変更時ではなく、コミット時にタイムスタンプを更新します。
MarkLogicが複数のホストに分散したクラスタ構成だった場合、2相コミット(Two-Phase Commit)が用いられています。2相コミットは、ホストのうちの1つがコーディネータとなって、全てのホストがOKだった場合のみ同時にコミットさせる機能です。
更新リクエストに対するドキュメント単位のロック
MarkLogicのトランザクションは、ドキュメントに対してロックすることで他のトランザクションからの操作を制約します。この機能はConsistency (一貫性) と Isolation (独立性) を保証するためのものです。
更新リクエストに対して、「読み取り(非排他)ロック」 と 「書き込み(排他)ロック」 の2つがあります。
「読み取りロック」は他のトランザクションの読み取りは許容しますが、書き込みはブロックします。感覚的には、共有フォルダにて誰かが見ているだけのファイルを自身が開くと編集できない旨が表示されるようなイメージです。
「書き込みロック」は、他のトランザクションの読み取りもブロックします。いざドキュメントの更新を行おうとするタイミングで、当該ドキュメントに対して設定されます。更新処理が終わったらロックは自動的に解放されます。
MVCCに裏付けされたロックフリークエリ
ロックは前述の通り排他制御に寄与しますが、参照のみのリクエストであれば必ずしも必要ありません。MarkLogicをはじめとしたデータベース製品ではMVCC (Multi-Version Concurrency Control、多重バージョン並行処理制御) を用いてドキュメントに対する読み取りロックを回避することができます。MVCCとは複数のユーザから同時に処理要求が行われた場合でも同時並行性を失わずに処理し、かつ情報の一貫性を保証する仕組みです。
MarkLogicでは、MVCCの考えに基づいてドキュメントをタイムスタンプを用いて複数のバージョンを保持することで、ロックなしでの読み取りができるようにしています。データベース内のドキュメントに対して作成・削除時にそれぞれ時間に応じたタイムスタンプを設定します。更新があった場合は、新しいバージョンを作成する一方で、既存のものには削除タイプスタンプを設定します。これを繰り返すと、データベースには同一URIのドキュメントに対して複数のバージョンが存在することになります。詳細はこちらのサイトが分かりやすいかもしれません。
このタイムスタンプを活用して複数のバージョンを持つことを許容することで、参照リクエストと更新リクエストに対して同時に対応することができます。例えば、あるドキュメント(最新のタイムスタンプ5001)に対しての参照リクエスト実行中に更新リクエストが実行されたとします。この場合、参照リクエストはタイムスタンプ5001のドキュメント内容を取得します。一方で更新リクエストは、新たなバージョンのドキュメント(同5002)を別途作成します。
オンディスクジャーナル
ジャーナル はDurability (耐久性) に関わる機能です。
更新されたドキュメントは最初に揮発的なメモリに保存されます。更新内容が重なって規模が大きくなれば最終的に不揮発的なディスクに書き込まれます。しかし、この方法では、ディスクに書き込まれる直前に障害が起きるとメモリ内にあるドキュメントに関する情報が失われます。
MarkLogicは、トランザクションの更新内容をメモリに書き込む前に、ディスク上のジャーナルに書き込みます。ジャーナルには、トランザクション実行中の障害の際にリプレイするための全ての操作が記録されます。また、コミットの情報もジャーナルに記録されます。これによって、最終的にトランザクションが完了したかもMarkLogicは把握できます。
データベースの復元に関するジャーナルの役割の詳細については、関連するナレッジベースも参照ください。
まとめ
本稿の内容をまとめます。
- MarkLogicは、信頼あるトランザクションシステムが持つべきACID特性を保証しています。
- ACID特性を保証するため、MarkLogicは「トランザクションのコミット機構」「ドキュメントロック」・「MVCCによるロックフリークエリ」・「オンディスクジャーナル」などの技術を用いています。