NoSQLは、そしてCouchbaseはどこへ向かっているのか 〜 トランザクション今昔

# はじめに

この記事では、特にRDB技術を背景にもつデータベース技術者がNoSQL（ドキュメント指向データベース）に触れる際に、関心が深いと思われるトピックである「トランザクション」について、概観を整理していきます。

# トランザクション今昔

## 1. 振り返り〜ドキュメント指向データベースにおけるトランザクション

ドキュメント指向データベースでは、トランザクションの原子性（Atomicity）は、ドキュメントという単位と一致しているということができます。

### 二つのトランザクション
Couchbaseのドキュメント更新に対するアプローチとして、「get-and-lock API」で実現される悲観的（ペシミスティック）ロックと「check-and-set (CAS) AP」による楽観的（オプティミスティック）ロックの二つがあります。それぞれの詳細については踏み込みませんが、重要な部分は、性能と取り扱いの煩雑さのトレードオフであるということが言えるでしょう。と言っても、悲観的アプローチが絶対に必要な要件があることを否定しているわけではありません。ただし、逆を言えば、悲観的アプローチが不要な部分で、それを使っているケースもあることを思い返すのが重要です。

## 2. 今時のNoSQL〜マルチドキュメントトランザクション

ここでいう「ドキュメント」は、JSONという準構造化データです。複数のレコード間を、外部キーによって関連づけることは、ドキュメント指向データベースであっても、採用しうる設計です。

そのことを踏まえ、複数レコード/ドキュメントに跨がるトランザクションが必要なケースとして、乱暴な整理かもしれませんが、次の二つについて考えてみます。

- 複数の（関係のない）エンティティ間でのデータの受け渡し（例えば、口座間での送金）
- 複数の（関係した）エンティティの同時更新（例えば、受注レコードと受注明細）

後者について言えば、ドキュメント指向データベースが扱う（準）構造化データでは、第一正規化が必須とされないため、必要なトランザクション境界を、１ドキュメントに含まれるデータの範囲と一致させる設計が可能だということが言えます。

その一方で、NoSQLテクノロジーが従来想定していた範囲を超えて、有益であることが認められてくるに連れて、複数ドキュメントに跨がるトランザクションの実現に対する要望も高くなっていったものと考えられます。

例えば、Couchbaseの過去のブログでは、トランザクションを表現するドキュメントを使うことによって、複数ドキュメントに跨がるトランザクションをアプリケーションとして実現する例が紹介されていたりもします。
NoSQLデータベースの制限をデータベース外部で解決するという試みは、様々な形で行われてきており、一例としてNECの[InfoFrame Relational Store(IRS)](https://jpn.nec.com/infoframe/relationalstore/docs/irs_couchbase_live_tokyo_2015.pdf)があります。

NoSQLに、マルチドキュメント・トランザクションが、データベースの機能として実装された背景には、ドキュメント指向データベースのユースケースの範囲が、大きく変わってきていることが示唆されていると考えられます。

### Couchbaseのマルチ・ドキュメント・トランザクションとは何であるか

Couchbaseの複数ドキュメントに跨がるトランザクションは、異なるバケットに跨がることができ、論理的なバケットは、実体として複数ノードに跨がるので、トランザクションは、当然複数ノードに跨がることになります。
NoSQLの世界でトランザクションの実現、という時、分散アーキテクチャーとしてのクラスター内の複数のノード間のトランザクションが念頭において語られることがあるため、注釈しておきます。

### Couchbaseのマルチ・ドキュメント・トランザクションは何でないか

ここで注意しなければならないのは、Couchbase(NoSQL)のマルチドキュメントトランザクションは、楽観的平行性制御に基づくものであって、ここでは、ドキュメントの更新のように、悲観的ロックを選択することはできないことです。
このことを踏まえて、次の章（さらに新しい段階）へ移っていきたいと思います。

## 3. NewSQL（Google Spannerクローン）

ここでは、NoSQLを話題の焦点にしていますが、「**New**SQL」と呼ばれる新しいデータベースが登場していることは、現在におけるNoSQLの位置づけを見極める上でも、非常に興味深いものだと考えます。以下の図をここで引用することは、その意味で、意義深いと思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/0e0eddf1-b823-baa0-752a-c79b937422df.png)

画像は、[NoSQL, NewSQL and Beyond](https://www.infoq.com/news/2011/04/newsql/)より引用

NewSQLについての詳細な説明は、上記図の引用元や、後述の参考情報中の記事に譲りたいと思いますが、端的に(若干乱暴に)いえば、[Google Spanner](https://cloud.google.com/spanner)(とそのクローン)を差すものと考えれば良いかと思います（というより、ここでは、その解釈とします）。
その特徴について要約すれば、分散アーキテクチャー（のメリット）を持ち（NoSQLから引継ぎ）ながら、あくまでRDBであること（つまり、SQLによるデータアクセスを行えること）を打ち出してように見えます。例えば、Google社の上記リンクでは、「Fully managed relational database with unlimited scale, strong consistency, and up to 99.999% availability.」と（真っ先に）謳われています。
クローンごとに若干打ち出し方が異なっているのは、[CouckroachDB](https://www.cockroachlabs.com/)では、「strong consistency」（技術的特徴）を「**mission-critical**」（目的）と表現している一方、[TiDB](https://pingcap.com/)は、「distributed SQL database for elastic scale and **real-time analytics**」と定義しています。[YugaByteDB](https://www.yugabyte.com/)は、「**Single-Digit Millisecond Latency**」を三大特徴の一番目に位置付けられているのも興味深いところです。

トランザクションというテーマについていえば、MongoDBやCouchbaseのようなNoSQLが、後天的に獲得した複数レコード/ドキュメント間のロックという特徴が、楽観的ロックに基づいている一方、NewSQLのロックは、悲観的ロックであることが大きく異なっています。これは、SQLが使えることと並び、NewSQLを「RDB」として位置付けているもう一つの特徴と言えるでしょう。Couchbaseとの比較で言えば、SQL(拡張)クエリが使えるところは共通している一方で、明らかに異なる特徴が、このトランザクションの設計ということになります。

### 楽観的ロックの何が問題か
楽観的ロックの何が問題か、乱暴ではあると思いますが、以下の二点に集約して考えてみたいと思います。

- トランザクション競合発生時の対応がリトライに基づくため、最終的に（集中時には）性能の問題に帰結する場合がある。

- 悲観的ロックに基づくRDBでの開発を常識としてきた開発者にとって、これまでの流儀を全く変えずに開発ができるわけではないこと

悲観的アプローチを取ることがが絶対に重要で、システムに必要な要件な場合がある一方（その場合、メリット・デメリットを比較する必要さえないため、ここではそうでないケースを前提としています）、詰まるところは、性能と取り扱いの煩雑さ、がここでもまた問題とされています（ただし、ここでは、一つのデータベースの中での選択肢を比較しているわけではないため、トレードオフの関係と見なすことはできません）。

前者の欠点は、アプリケーション全体において、トランザクション/ロックの要件が必要である場合、それ自体単体で見た場合悲観的ロックと比較して軽量な処理であるはずの、楽観的ロックの実装を利用した場合、問題となりうることを示しています。
また、技術的な進歩の結果として、あるデータベースが悲観的ロックを採用していても、他のデータベースの楽観的ロックに遜色ない性能が実現されるということも無いとは言えないでしょう。

後者については、性能の問題さえ気に掛ける必要がないとすれば、開発者にとっては、考慮する点の少ない手法が好ましいのは間違い無いでしょう。
（これ以上の議論のためには、どのように異なる開発上のアプローチが必要かを具体的にすることが重要だと考えつつ、本稿については、ここで筆を置きたいと思います）


# 参考情報

## NoSQL/ドキュメント指向DB/Couchbaseにおけるトランザクション

[Optimistic vs Pessimistic Locking – Which One Should You Pick?](https://blog.couchbase.com/optimistic-or-pessimistic-locking-which-one-should-you-pick/)

## マルチ・ドキュメント・トランザクション実装の試み

Multi-document transactions: ACID and Couchbase Part 2
https://blog.couchbase.com/multi-document-transactions-acid-couchbase-2/

How NoSQL and ACID Properties and Couchbase: Part 1
https://blog.couchbase.com/acid-properties-couchbase-part-1/

## マルチ・ドキュメント・トランザクション・サポート

### Couchbase
Couchbase Brings Distributed Multi-Document ACID Transactions to NoSQL
https://blog.couchbase.com/couchbase-brings-distributed-multi-document-acid-transactions-to-nosql/

Understanding Distributed Multi-document ACID Transactions in Couchbase
https://blog.couchbase.com/distributed-multi-document-acid-transactions-in-couchbase/

### MongoDB

[MongoDB 4.0 トランザクション機能 ベストプラクティス](https://qiita.com/kabao/items/ecc8e97b2995227f47e8)

## NewSQL

[NoSQL, NewSQL and Beyond](https://www.infoq.com/news/2011/04/newsql/)

[2020年現在のNewSQLについて](https://qiita.com/tzkoba/items/5316c6eac66510233115)

[NewSQLのコンポーネント詳解](https://qiita.com/tzkoba/items/3e875e5a6ccd99af332f)

### NewSQLデータベース（Google Spannerとそのクローン）

[Google Spanner](https://cloud.google.com/spanner)

[CouckroachDB](https://www.cockroachlabs.com/)

[TiDB](https://pingcap.com/)

[YugaByteDB](https://www.yugabyte.com/)

## データベースの歴史

[RDBの限界とNoSQLの登場](https://qiita.com/1amageek/items/3dbbc3112493a73880d0)

## Couchbaseドキュメント
[Transactions](https://docs.couchbase.com/server/current/learn/data/transactions.html)