『データ指向アプリケーションデザイン』を読んだ

すでにほぼ出社しなくなっていた数ヶ月前、久しぶりにオフィスで会った同僚たちと雑談していて、本書の話題になった。「おもしろかった」「かばたが好きそう」と言われたので、気になって即購入即積ん読だった。読もうと思っても積ん読にマンガがスタックされていくのでなかなか着手できずにいたが、このたび無事に表紙を開くに至った。

www.oreilly.co.jp

3部構成、12章構成。各章ともに、まず全体像を示した上でそれぞれの原理的な説明からはじまり、そのあとにユースケースや固有のソフトウェアを紹介する流れになっている。また、全体としてもひとつの大きな流れに沿って展開されていく。例示もケースごとに独立してミニマムに示されており、たいへん読みやすくおもしろい。が、ボリュームがすごく、自分が分散システムの知識、とりわけ合意など分散システム自身の実装を経験していないため、途中から理解が追いつかず意識が途切れた。悲しい。一気に理解しようとするものでもないとおもうので、また関心が湧いたら戻ってきたい。

例によってメモしながら読んだが、ボリュームが膨大になってしまった。これを載せると著作権的にもアウトな気がするし人間が読める状態ではないため、部ごとの感想を書いておく。それぞれの部が独立した一冊の技術書になってもいいレベルの濃度だった。

第Ⅰ部 データシステムの基礎

サブタイトルをみればわかるが、本書のメイントピックは「分散データベースシステム」とされている。第Ⅰ部ではその前段として、個別のデータベースシステムがどういう原理で動いているかを取り上げている。データベースというソフトウェアに求められる特性からはじまり、データモデルやクエリの概要、またストレージ・メモリにおける物理構造、それらの挙動について、本部がメインでもいいのではというレベルできれいに説明されている。

信頼性、スケーラビリティ、メンテナンス性に焦点を当て、それぞれどのような要求なのかを述べている。本筋とは違うが、メンテナンス性の低いシステムを「巨大な泥の玉」と表現しており、辛辣すぎるとは思いつつ決して大げさではないし、はじめてきいた表現でおもしろかった。

www.laputan.org

データモデルについては、階層モデル、リレーショナルモデル、ドキュメントモデルを挙げている。後者2つは互いに競合かのように謳われることがある*1が、本質的にはスキーマオンライトかスキーマオンリードの違いでしかなく、いわば静的型つき言語と動的型つき言語の違いのようなものと説明されている。この領域についていろいろな書籍や記事を読んだが、この説明がもっとも端的で実態を説明できているとかんじた。また、実際にはインターフェイスとしてリレーショナルモデルとドキュメントモデルは互いにサポートし合うような状態になってきている*2。さらに、多対多の表現としてプロパティグラフモデルとトリプルストアモデルについて、CypherやRDF、Datalogといった実装を挙げながら説明されている。表現としてはシンプルなだけに、その意義や解決したい課題を理解するのが難しいことが多いが、本書ではそこが冗長にならず必要十分に説明されていると感じた。

ストレージの章もおもしろかった。「情報を記録する」仕事のもっとも原始的な形式のひとつとしてlog-structuredなデータ構造があり、SSTableを用いたLSMツリーが一般的にある。他方でBツリーが普及し一般に利用されてきている中で、メモリ容量の拡大とSSDの普及に伴い、LSMツリーが再び脚光を浴びているっぽい。これは多くのSSDがファームウェア的にlog-structured相当のアルゴリズムを使っており相性がいいためらしい*3。このあたりのレイヤは勉強不足で理解しきれなかったが、おもしろそうなので別の機会に調べてみる。

The flash translation layer in a modern, full-featured SSD resembles a log-structured file system in several important ways.

第4章では、データのエンコーディングとそれに伴うアプリケーション観点での課題について説明されている。データのフォーマットとしてどのような表現があるかが実用によりつつ広く紹介されていて、このあたりは本書のバランスが非常によいところとおもった。現在のアプリケーションはほとんどがデータ指向であり、暗黙的にデータの表現に束縛されていることは体感としてもあるし、データのモデル化と設計がアプリケーションの進化にいかに重要かが伺い知れる。

第Ⅱ部 分散データ

データシステムを複数のマシンに分散させたい欲求がある。高負荷に対するスケーリングを考えたとき、垂直スケーリングと水平スケーリングに分類でき、主に後者の水平スケーリングにおいて、シェアドナッシングアーキテクチャを前提としてレプリケーションとパーティショニングを主に掘り下げている。

レプリケーションにおいては、「複数のノードがある中で、意思決定者(=リーダー)はだれか」という基軸で、さまざまなアルゴリズムがある。もっともシンプルには単一のリーダーがいて、レプリカはそれを信じればよい。リーダーの障害時にはレプリカのだれかをリーダーに選出する。この場合においてもさらにレプリケーションの手法がさまざまある*4。ちなみにPostgreSQLはバージョン9.0でWALを送信する物理(ストリーミング)レプリケーションがサポートされ、バージョン10でステートメントを送信する論理レプリケーションがサポートされている。

www.postgresql.org

リーダーレスレプリケーションはクオラムの仕組みを説明しており、関心のあるところだった。この手の説明は何度読んでもわかったようなわからないようなダメな状態になる。実装するしかないのかもしれない。平行書き込みを検出する必要があるが、平行とは何かを突き詰めると特殊相対性理論に行き着くらしい。怖い。

パーティショニングも関心のある章だった。パーティショニングの目的はデータとクエリの負荷をノード間で均等に分散させることであり、不均等な状態をスキュー(skew)と呼ぶ。これをなんとかしたい。データを投入するときの分割の方法、データ投入後のリバランス、リクエストのルーティングと、バランスをとる戦略が紹介されている。分散したパーティションへの書き込みをどう保証するかという問題が、次章へと繋がっている。こういった流れが本書では明示的に説明されていていい。

トランザクションの章では、一般的に知られるACIDや分離レベルについて本書の文脈を踏まえつつ改めて説明されている。トランザクションの実装に触れられている書籍はなくはないが、本書は歴史を踏まえてその必要性と価値から書かれている。例えば、SQL標準は1975年のSystem Rに基づいており、スナップショット分離という概念がなく、実装依存になっている*5。理論と実装の橋渡しが丁寧にされており、初学書を読んで混乱した人にも必要十分な情報が提供されている。SSIのところはどこかでちゃんと理解したい。

okachimachiorz.hatenablog.com

第8章と第9章はここまで積み上げてきた説明の集大成であり、本書のメイントピックであるようにかんじた。第8章では分散システムの問題にフォーカスし、1章をかけて問題定義をしている。レプリケーションや、パーティショニングや、トランザクションといった問題は、相互のコミュニケーションが絶対の信頼性を持たない実世界において、どのように単一の状態に収束するかという命題であり、つまりは「合意」という等価な目的を目指すものである。論文をはじめとして合意アルゴリズムそのものの説明や実装ケースの紹介は世に溢れているが、本書がもつ価値のひとつは、この問題の導出に至るまでの精緻な積み上げにある。とおもう。合意アルゴリズムさえあれば、それがアトミックなブロードキャストを提供し、それによって耐障害性を持ちながら線形化可能な操作を実装できる。

第Ⅲ部 導出データ

ここまでは主にOLTPを前提としてきたが、バッチ処理とストリーム処理にも触れている。バッチ処理に関しては、Unixツールによる分析処理からMapReduceによる分散分析環境を説明している。ストリーム処理に関してはもなんか書いてある。このあたりになると集中力が完全に切れ、各章の冒頭くらいしか読んでない。仕事でもプライベートでもこれまで必要とすることがなかったから、関心が持てない。また関心を持つことがあったら読みにくる。

最後の章では、データベースの将来について著者の見解を述べている。ここまでくると目が滑って限界。お腹すいた。いまを生きるに精一杯な自分にとってあまり関心がないのだが、倫理的な側面にも触れられていて、面白そう。いま必要なことからやっていきましょう。

*1:NoSQLがでてきて、NewSQLがでてきて、など

*2:リレーショナルモデルのPostgreSQLやMySQLはXML/JSONをサポートしているし、ドキュメントモデルであるRethinkDBはリレーショナル的な結合をクエリ言語でサポートしている

*3:https://lwn.net/Articles/353411

*4:ステートメントベース、ログベース、行ベース、トリガベース

*5:PostgreSQLではリピータブルリード、OracleではSERIALIZABLEと呼ばれている