データ指向アプリケーションデザイン

最近久しぶりに書籍を購入しました(但しKindle版)。
普段利用するドキュメントはWeb上で読め、それほどボリュームが無いものが多いので、技術の専門書の購入としては10年ぶりくらいでしょうか。

タイトルはM. Kleppmannの「データ指向アプリケーションデザイン」( 英題: “Designing Data-Intensive Applications” )。この本のKindle版を、時間がある時にざっと読んでるんですが、まだ二章までしか読めてません。

・・・という訳で二章までレヴューをしてみましょうか。

パラパラ目次と各章のSummaryを見るだけでも、見る人によっては結構面白いんじゃないでしょうか。本の冒頭で謳ってるように、(システムの)エンジニア/アーキテクト/管理者、あるいは学生、いずれの所属でも役立つと思います。

まず気になったところを含め、要約していきましょう。

第一章

しばしばSLA(SLO)で見られるような非機能要件(Reliability, Scalability, Maintainability)。これらの厳密な定義や各種パラメタ(例えばScalabilityであればそのload parameter)の選定方法について詳述してあります。

特に興味深い点として、システムのReliabilityを考える際に「人的ミス」が如何に影響が大きく、かつこれに対処することが重要か強調してあります。

(必ずしもヒューマンエラーとは限らない)システムの誤動作(faults)の範囲を最小化する以下のようなアイデア(一部)が挙げられているので、頭で分かっていてもチェックリストに良さそうです:

faultsを起こさせない構成を取る
  • 実際のプロダクションデータが使えるsandbox(テスト環境)の準備
  • ハードウェア冗長化
  • セキュリティの強化/アクセス経路の制限
  • テストをあらゆるレベルで行い、自動化を積極的に使う
  • 人員の管理/トレーニング
faultsが起こった場合に、それに迅速に対処/復帰する構成を取る
  • あらゆる事態の慎重な検討
  • プロセス同士の隔離
  • バックアップ
  • 設定変更のロールバック構成
  • 監視
  • モジュール(機能)の分離

第二章

データモデル、特にRelational Data Modelとそれ以外との比較について、Modelの性質や具体例から、いくつかの切り口でアプリケーションに最適な選択に関する議論を展開してます。

昨今では労力においても金額においても、DBの導入コストが小さいですから、DBを利用したことがある人は多いでしょう。例えそのような人でも、RDB(RDBMS)で標準となっているRelational Data Model以外のData Modelを明確な意図を持って選定し、データのアクセス・パスを自分で設計したり、実際にプロダクトで活用したことがある人は少数かも知れません。

実際のところ現代のRDB(MySQLは少し特殊のようですが)は、Relational Data Model以外のModelを完全に表現できる(として良いと考えられます)上、Relational Data Modelは一般的な目的(general purpose)に適っているため、内容やスケールによってはData Modelの選定自体が必要とならないケースも多いでしょう(表現できるというのは、データ同士の関係や制限、優先的なindexの指定等をSQLの範囲でSchemaとして記述できるということ)。

さてこの章では、NoSQLをNOT Only SQLと翻訳することから始まるので、何か自分の常識が覆ることを期待して胸が膨らむでしょう。ちなみに私が興味深いと思った箇所はそこではなく、Relational Data Modelへの批判(批判はしていないが、敢えて批判としておきます)をしている部分です。

Relational Data Modelへの批判

Relational Data Modelでは、しばしばアプリケーションコードで表現するオブジェクト (model)と、物理テーブル及びその行や列が表現するものが対応せず、「翻訳」のレイヤーが必要になる(アプリケーションオブジェクトとDBモデルとの分断は、impedance mismatchと呼ばれる)。

これは書籍の該当箇所の(私の)翻訳ですが、意味は変わってないと思います。私も言語化はしていなかったがずっと考えていたことで、この現象に名前が付いてないのが不思議なくらいでした。そして名前があったようです、impedance mismatch

アプリケーション内オブジェクトと物理データとの「翻訳」を補助する役割を持つものとしてORMがありますが、翻訳が完全ではあり得ないため、それ自身が新たな問題をはらむ可能性があります。
例えば特定のモデルを表現するために構築した複雑なクエリをORMでカバーしようとすると、フレームワーク固有のカスタムコードが必要になるケース(この場合特定のORMフレームワークに依存する)や、実質的にハードコードしてしまう場合はMaintainabilityに悪影響を及ぼすばかりか、impedance mismatchの問題は解決されないため、ビジネスロジックが複雑化したり、その解釈/変更/改修が属人化します。

ちなみにRelational Data Modelへの批判とは言ったものの、これを特定のData Modelに対する批判だとは解釈してませんし、するべきではないでしょう。というのも、他のgraph-like data modelにしても、document data modelにしても、よく考えずに設計すればもちろんimpedance mismatchは起きます。

impedance mismatch ― データとアプリケーション間で翻訳のロジックが必要になるケース ― の皺寄せはアプリケーション側のローンチ時の開発・保守工数に跳ね返ってくるだけならまだしも、特定の言語・フレームワークに依存させる温床となるので、学習コストが高くなり、拡張性や保守性も失われかねません。特に設計が変わったとき、要件で扱うオブジェクトはアプリケーション側の表現の方が近いので、データ側の変更が複雑化したり、ダウンタイムを要したり、ともかく大変なことです。

最後に、少し触れたdocument data modelを選定する基準について簡潔にまとめておきます。

document data modelを選定する基準

モデル別名説明
document modelschema-on-read動的型付け: アプリケーション側でScheme(構造)を持ち、データ読み込み時に構造の解釈を与える。この実装が有効なRDBにおける型の例としては, JSON型やTEXT型、XML型(MySQL以外)が含まれる。
relational modelschema-on-write静的型付け: DB側でScheme(構造)を持つ。
relational modelとの比較

次のような場合、document modelが効果的とされる:

  • 外部システムや外部デバイスにデータ型が委ねられており、将来変更の可能性がある、あるいは変更に対する柔軟性が欲しい
  • ツリー型である(他データとの関係は、高々1:1~1:nの低階層に留まる)
  • データが内包する型の種類が多く、正規化し個別のテーブルに格納するには合理性に欠ける

かなり偏ったレヴューなのは承知なのですが、読んでみたくなったでしょうか?

引き続き時間を見つけて残り読んでいきます。

技術の世界では実践や経験が理論よりも重要な場面が多いかと思いますが、時折散り散りになった知識や経験を整理、言語化し、構築しなおすと良いものです。もう少し大きな枠組みで考えられますから。