こまぶろ

技術のこととか仕事のこととか。

『データ指向アプリケーションデザイン』を読む(2):1章「信頼性、スケーラビリティ、メンテナンス性に優れたアプリケーション」

『データ指向アプリケーションデザイン』の1章「信頼性、スケーラビリティ、メンテナンス性に優れたアプリケーション」についての読書メモ。

データ指向アプリケーションデザイン ―信頼性、拡張性、保守性の高い分散システム設計の原理

データ指向アプリケーションデザイン ―信頼性、拡張性、保守性の高い分散システム設計の原理

導入

全体の導入となる章。前回の記事でも引用が、タイトルにも現れている「データ指向アプリケーション」を以下のように提示するところから始まる。

今日の多くのアプリケーションは、演算指向ではなくデータ指向であり、CPUの処理能力そのものが制約条件になることはほとんどありません。通常は、データの量や複雑さ、そしてデータの変化する速度のほうが大きな問題なのです。*1

上記の意味での「データ指向」なアプリケーションを構築するに当たって、重要な課題になるのが、「信頼性」、「スケーラビリティ」、「メンテナンス性」の3つの性質だとされる。著者は、よく使われるこれらの概念が、「はっきりと意味が理解されることなく使われてい」ることを問題視し、1章を丸々これらの概念についての考え方を説明するのに費やす。

信頼性

信頼性は、「何か問題が生じたとしても正しく動作し続けること」とまとめられる。複数のコンポーネントから成るシステムでは、仕様を満たしていないコンポーネントとしてのフォールトの存在が、システム全体の適切なサービスの停止(=障害)に至らないようにしておくことが課題になる。著者は、フォールトの所在として、ハードウェア、ソフトウェア、そして人間を挙げる。

ハードウェアのフォールトからシステムを守る手段として、従来は冗長化が支配的であったが、現在ではそれに加えてソフトウェア側でもハードウェアのフォールトに対応できるような手法を採用することが増えているという。大量のマシンを利用するようになっていること、(それを可能にした)クラウドプラットフォームの仮想マシンが単一マシンの信頼性を最重要視していないことと行ったシステムを環る状況の変化が、耐障害性を確保するための手法にも影響を与えているというのだ*2

ソフトウェアについては、ハードウェアにおけるフォールトとの性質の違いが言及される。ハードウェアのフォールトが、複数のマシンで同時に発生するような性質を有することが稀であるのに対して、ソフトウェアのフォールトは相関をもった形で現れることがあり、障害に繋がりやすいという。このようなフォールトには「手っ取り早い解決策」はないとしながらも、システムに関する前提を注意深く考えることやプロセスの分離などの処方箋が提示される*3

最後の「人間」についての節では、「最大限に努力しても、人間には信頼性がないことが知られています*4」という厳然たる事実から出発し、これに対処するためのアプローチをいくつか挙げている。それらの中には、「『正しいことを』行いやすく、『間違ったこと』を行いにくくしてくれる」インタフェースをうまく設計することも挙げられている。『プログラマの知るべき97のこと』に書かれていることではあるが、「人間の信頼性」という観点でハードウェアやソフトウェアのフォールトと並べた文脈で現れたのは新鮮だった。

プログラマが知るべき97のこと

プログラマが知るべき97のこと

スケーラビリティ

スケーラビリティについては、冒頭に書かれていたことが印象に残った。そのまま引用する。

スケーラビリティとは、負荷の増大に対してシステムが対応できる能力のことを指して使われる言葉です。ただし、これはシステムに対して与えることができる1次元のラベルではないことに注意してください。「Xはスケーラブルである」あるいは「Yはスケールしない」などと言うことに意味はありません。*5

自分の現職は、基本的にデータの量や複雑さがあらかじめ予測できる業務システムを開発していて、「スケーラビリティ」という言葉を社内で聞くことはあまりない。言葉は知っているものの、「あー、クラウドでマシンを横に複数並べたり大きくしたりして得るやつね」というくらいの認識しかなく、まさに一次元で捉えていたことを気付かされた。

さて、スケーラビリティを考えるに当たっては、対処すべき負荷と、その負荷によって影響を受けるパフォーマンスを具体的に特定することが必要で、そのためには負荷とパフォーマンスをどのように表現するかが重要だと著者は指摘する。特定の種類の負荷に対応することを企図したアーキテクチャは、別の種類の負荷に対応するためのアーキテクチャとは全く異なっているのであり、全てに対応できる「魔法のスケーリングソース」は存在しないということを頭に入れておく必要がある。

負荷の表現の説明で挙げられているTwitterの例はとてもわかりやすく、かつ面白い。また、パフォーマンスの表現でパーセンタイルを使うことを推奨しているのは、金融のリスク管理分野に縁がある自分にとってはスムーズに受け入れられた。「見積もりは確率分布で考えよう」というのと同じく、広く知られていい考え方ではないだろうか。

また、コラムの「レイテンシとレスポンスタイム」についての説明は、今まで自分がちゃんと区別できていなかったことを明確に区別していて役に立った。

レスポンスタイムはクライアントから見た値であり、リクエストの処理そのものに費やされた時間(サービスタイム)に加えて、ネットワークやキューイングによる遅延が含まれます。レイテンシは、リクエストが処理を待っている時間であり、リクエストはこの期間待ち状態にあり、サービスを待っています。*6

メンテナンス性

メンテナンスのためのコストを最小化するための設計原理として、運用性、単純性、進化性の3つが挙げられる。

運用性の高いシステムとは、システムが運用チームにとって取り扱いやすいことである。運用性についての記述では、運用チームの責任範囲や彼らの定型タスクを容易にするデータシステムにおけるプラクティスが例示される。後者として指摘されているものは、データシステムに限定したものというよりは、運用に配慮したシステムを作る際に考慮すべき点のリストとなっている。

単純性は、ここではエンジニアにとっての理解しやすさであり、ユーザインタフェースの単純さではないと明確に断っている。実装の複雑さが及ぼす悪影響についての参考文献として、ブルックス『人月の神話』とRich Hickeyの"Simple made Easy"が並んで脚注に載せられているのが印象的だ。複雑さを取り除くための一つの考え方として、「偶発的な複雑さ」という概念が紹介される。

システムを単純にすることは、必ずしも機能を減らすということではありません。単純にするということは、偶発的な複雑さを取り除くということでもあります。MoseleyとMarksは[32]*7、偶発的な複雑さについて、「ソフトウェアが解決しようとしている(ユーザーから見た)問題がもともとは持っておらず、実装からのみ生じている複雑さ」と定義しています。*8

偶発的な複雑さを取り除くための有力な手段として提示されるのが「抽象化」である。実装の詳細をわかりやすいインタフェースの裏側に隠す優れた抽象化が、それを利用するエンジニアにとっては大きな助けになる。抽象化の意義として再利用性が挙げられる場合もあり、この書籍でもそれは指摘されているが、個人的には抽象化の第一の意義は隠蔽であると考えている*9

なお、実装の単純さというと、"Worse is Better"、MIT approach と New-Jersey style との対比が想起される。この辺りは以下が参考になる。

ajito.fm

note.mu

進化性については、この章ではあまり紙幅が割かれていないが、重要な指摘がされている。 システムに対する要求の変化に対応するためのアプローチとして、アジャイルのコミュニティが、これまでテスト駆動開発リファクタリングあなどを提案してきたしてきたが、それはシステム全体の中のごく小さな、ローカルなスケールでの変更を支援すルものだったという。より大きなアーキテクチャのレベルでの「リファクタリング」を可能にするためにどうすればよいか、というのは未解決の課題として残されているというのである。著者は、このレベルでの変化への対応しやすさを、「進化性」と名付けて論じることを予告する。

感想

読んでいて、「そうそう、それそれ」という納得と「なるほど!そうなのか!」という気づきとがひたすら連続する。常識的な事柄も丁寧に説明されている一方で、優れた洞察も随所に散りばめられていて、学ぶことの多い。このような記事を書いておいて言うのも憚られるのだが、一文一文に知見が込められているので、要約してしまうと魅力が失せてしまう本だと思う。

読み方にしても、一回読んで終わりというよりは、なんども繰り返して読む、折に触れて必要な箇所を読み直すという読み方をすることによって、自分の知識や経験の蓄積、その時々の現場での悩みに応じて得られるものがあるのではないかと思う。

*1:3ページ。

*2:8ページ。

*3:9ページ。

*4:9ページ。

*5:11ページ。

*6:15ページ。

*7:Ben Moseley and Peter Marks: "Out of the Tar Pit," at BCS Software Practice Advancement, 2006.

*8:22ページ。

*9:このあたりは『Code Complete』に影響を受けている。