Scalar DBを用いた複数のデータベースを跨いだ分散トランザクション(Part 1)

こちらの記事で書いたとおり、Scalar DBでは複数のデータベースが連携する際に生じるトランザクション一貫性に関する課題に取り組んでいます。本記事ではScalar DBの複数データベース/ストレージに跨るトランザクション機能についての説明をします。

Scalar DBの複数のデータベース/ストレージに跨るトランザクション機能として以下があります。

  • Multi-storage Transactions
  • Two-phase commit Transactions

今回は、Part 1としてMulti-storage Transactionsについて説明します。そして、次回のPart 2でTwo-phase commit Transactionsについて説明したいと思います。

Multi-storage Transactionsの概要

Multi-storage Transactionsは、単一のサービス/アプリケーションから複数のデータベース/ストレージに跨るトランザクションを実現する機能です。

こちらの記事で説明したように、Scalar DBでは「Consensus Commit」と呼ばれるクライアント側でコーディネーションを行うトランザクションプロトコルを用いています。そのため、個々のデータベース/ストレージのローカルトランザクション機能に依存することなくACIDトランザクションを実行することができます。これにより、ACIDトランザクション機能を持たないNoSQL等のデータベース上でACIDトランザクションを実現するだけではなく、複数のデータベース/ストレージ上に跨るACIDトランザクションを実行することが可能となっています。

また、Scalar DBでは「Database Abstraction Layer」によりデータベース/ストレージが抽象化されています。そのため、Scalar DBのトランザクションマネージャはデータベース/ストレージの実装を意識することなくトランザクションを実行することが可能です。これにより、様々なデータベース/ストレージを跨るトランザクションが可能になります。

Multi-storage Transactionsのプロトコルの詳細についてはこちらの記事で説明した通りです。このプロトコルを複数のデータベース/ストレージのレコードに対して適用することでMulti-storage Transactionsを実現しています。

複数のデータベースに跨るトランザクションを実現する他のアプローチとしてはXAがあります。XAは殆どのリレーショナルデータベースでサポートしていますが、NoSQL等の比較的新しいデータベースではサポートされていないという欠点があります。それに対して、Scalar DBでは、前述のDatabase Abstraction Layerにより様々なデータベース/ストレージを跨いだトランザクションが可能になります。現時点ではCassandra、Amazon DynamoDB、Azure Cosmos DB、そしてJDBCデータベース (MySQL、 PostgreSQL、 Oracle Database、 Microsoft SQL Server、 Amazon Aurora)を公式にサポートしています。

サンプルアプリケーション

Multi-storage Transactionsの使い方を、前回の記事で作ったものと同じECサイトを題材に説明していきます。ここからは、前回の記事を読んでることを前提としていますので、本記事を読む前にそちらの記事を読むことをお勧めします。

また、本サンプルアプリケーションのソースコードや設定ファイル等は以下にありますので、実際に実行してみたい方はこちらをご覧ください。

https://github.com/scalar-labs/scalardb-samples/tree/main/multi-storage-transaction-sample

スキーマ

サンプルアプリケーションのスキーマは以下のようになります。

ER図

スキーマの内容は、前回の記事とほぼ同じです。違いは、customersテーブルはcustomerネームスペースに作成され、ordersテーブル、statementsテーブル、itemsテーブルはorderネームスペースに作成されます。

トランザクション

実装するトランザクションに関しても前回の記事と同じになります。

  1. 顧客情報の取得
  2. 注文の発行。注文はクレジット決済で行われます。その際には、その顧客のクレジットカードの上限額のチェックを行います
  3. クレジット返済。クレジット利用額を減算します

Multi-storage Transactionsのアプリケーション作成手順

ここからは、実際にサンプルアプリケーションを作成する際の手順を説明します。

Step1. 設定ファイルを作成する

Multi-storage Transactionsでは、各ストレージの設定と、どのテーブルへのオペレーションをどのストレージにマッピングするのかを設定する必要があります。

database.properties

今回は、scalar.db.multi_storage.storagesプロパティでcassandramysqlの2つのストレージを定義し、それぞれのストレージの設定をscalar.db.multi_storage.storages.cassandra.*

scalar.db.multi_storage.storages.mysql.*で設定しています。そして、scalar.db.multi_storage.namespace_mappingプロパティにて、どのネームスペースのテーブルに対するオペレーションをどのストレージにマッピングするのかを設定しています。今回のケースでは、costomerネームスペースのテーブルに対するオペレーションはmysqlストレージへマッピングし、orderネームスペースとcoordinatorネームスペースのテーブルのオペレーションはcassandraストレージにマッピングされる設定になっています。ちなみに、coordinatorネームスペースのテーブルは自動的に作成されるテーブルで、Consensus Commitで使われるものです。最後のscalar.db.multi_storage.default_storageプロパティは、マッピングが無いテーブルに対するオペレーションがマッピングされるストレージを定義します。今回は、マッピングがない場合はcassandraストレージにマッピングされます。

Multi-storage Transactionsの設定についての詳細は以下をご覧ください。

https://github.com/scalar-labs/scalardb/blob/master/docs/multi-storage-transactions.md

Step2. スキーマを作成する

スキーマの作成方法も、前回の記事と同様です。Schema Loaderというツールを用いて、スキーマを作成します。

スキーマファイル(schema.json)は以下になります。これも前回の記事とほとんど同じですが、ネームスペース名だけ違っています。

schema.json

そして、以下のコマンドでスキーマを作成します。

# java -jar scalardb-schema-loader-3.6.0.jar — config database.properties — schema-file schema.json — coordinator — replication-factor 1

このコマンドを実行すると、customer.customersテーブルはMySQLに作成され、order.ordersテーブルとorder.statementsテーブルとorder.itemsテーブルはCassandraに作成されます。

Step3. トランザクションを実装する

トランザクションの実装については、前回の記事のものとほとんど同じ(ネームスペース名以外)になりますので、説明を割愛します。詳細を知りたい方は前回の記事を読むか、以下をご覧ください。

https://github.com/scalar-labs/scalardb-samples/tree/main/multi-storage-transaction-sample

まとめ

本記事では、Scalar DBの複数のデータベース/ストレージに跨るトランザクション機能について説明し、その1つの機能であるMulti-storage Transactionsの概要とその使い方をサンプルアプリケーションを交えて説明しました。次回は、Scalar DBの複数のデータベース/ストレージに跨るトランザクション機能のもう一つの機能であるTwo-phase commit Transactionsについて説明したいと思います。

--

--