こまどブログ

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

『データ指向アプリケーションデザイン』を読む(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』に影響を受けている。

『データ指向アプリケーションデザイン』を読む(1):タイトルについて

『データ指向アプリケーションデザイン』を読み始めた。本文だけで605ページという大著なので、少しずつ読み進めていきたい。

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

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

  • 第I部 データシステムの基礎(1〜154ページ)
    • 1章 信頼性、スケーラビリティ、メンテナンス性に優れたアプリケーション(3〜27ページ)
    • 2章 データモデルとクエリ言語(29〜71ページ)
    • 3章 ストレージと抽出(72〜117ページ)
    • 4章 エンコーディングと進化(119〜154ページ)
  • 第II部 分散データ(155〜422ページ)
    • 5章 レプリケーション(161〜213ページ)
    • 6章 パーティショニング(215〜237ページ)
    • 7章 トランザクション(239〜295ページ)
    • 8章 分散システムの問題(297〜349ページ)
    • 9章 一貫性と合意(351〜422ページ)
  • 第III部 導出データ(423〜605ページ)
    • 10章 バッチ処理(427〜479ページ)
    • 11章 ストリーム処理(481〜535ページ)
    • 12章 データシステムの将来(537〜605ページ)

XX-oriented vs XX-intensive

「〇〇指向△△」というと、原題は「〇〇-oriented △△」だろうかと想像するが、この本の原題は、「Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems」である。

まず気がつくのが、「データ指向」がDate-orientedの訳語ではなくData-intensiveであるということだ。この"intensive"の語感は、「labor-intensive(労働集約的)」というときのintensiveに近いものだと思われる。つまり、アプリケーションのなかの相対的に重要な位置をデータが占めているということだ。本文中の以下の記述には、演算指向(compute-intensive)、つまり演算(計算処理)が中心となるアプリケーションとの対比が表現されている。

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

オブジェクト指向(Object-oriented)」が分析なり設計なりプログラミングなりの「中心にオブジェクトを据えていきましょう」という方向性を示しているものであるのに対して、「データ指向(Data-intensive)」は事実としてデータが重要な位置付けを占めているということを表現しているということができるだろう。それは、「労働集約型産業(Labor-intensive industry)」が「労働を中心に据えてやっていこうな」という話ではないというのと同じだ。

「データ指向アプリケーションデザイン」は手法ではない

上述の点と関連して、押さえておかなければならないのは、「Data-intensive」という形容詞が、「Application」にかかっているということである。つまり、本書が語る対象は、「<データ指向な><アプリケーション設計>」ではなく、「<データ指向アプリケーション>の<設計>」なのである。

この書籍の主眼は、先述の意味で「データ指向なアプリケーション」をどのように「設計」すべきかという点に置かれている。「デザイン」と訳されている原題の語は「Designing」(動名詞)であり、たとえば『エリック・エヴァンスのドメイン駆動設計(Domain-Driven Desgin)』における名詞の「Design」とは異なっている。後者が設計の手法であるのに対して、前者は設計という営み自体である。

内容に照らしてみても、本書は「データ指向アプリケーションデザイン」という設計手法の考案・提唱を目的としたものではない。したがって、「DDDで設計してみました」はありえても*2、「データ指向アプリケーションデザインで設計してみました」ということはない。

技術書の邦題問題

以上、『データ指向アプリケーションデザイン』のタイトルについて考えてきた。自分の考察が適切であるとすれば、本書の邦題はややピンぼけしているように思う。しかし、それは訳者に帰する問題ではおそらくないし、批判しようという意図はない。

テスト駆動開発』をオーム社から再出版するときに、「入門」とタイトルに入れたがる出版社サイドを、訳者のt-wadaさんが制したという。「入門」や「実践」が入るとよく売れるという出版事情があるようで、それは自分の知っている書籍にも影響を与えているように思う*3。それ以外にも、シリーズらしく見えるように邦題を設定したり、さまざまな制約が邦題というものにはあるのだろう。

読者コミュニティの一員としてできるのは、このような大著を母語で読める形で世に出してくれた訳者や出版社に敬意を評しつつ、より良くその書籍を読むアイデアをコミュニティに提出していくことなのではないかと思う。

*1:『データ指向アプリケーションデザイン』3ページ。

*2:ただ、「DDDで設計してみました」にはその他の理由でマサカリが飛ぶことはあろう。

*3:『実践ドメイン駆動設計』や『実践テスト駆動開発』など。

書けない言い訳を封じよう:『できる研究者の論文生産術』

ブログを書くようになって15ヶ月が経った。ブログを書き始めたきっかけをくれた師匠ともいうべき存在であるkakakakakkuさんは、三大欲求の一角を「ブログ欲」が突き崩しているとのことだが、僕にとっては今でもブログを書くことは苦痛を伴うものであり続けている。

fukabori.fm

「書きたい」のに「書けない」という人に

ブログは、書きたいと思っていれば書けるものではない。書きたいと思っていても書けないときはある。自分自身、むしろ書けないときの方が多い。書けない時間が続いているときは、「あぁ、ダメな時期がやってきたなぁ」と思う。

「まぁそんなもんだよね」と諦めてしまうのもいい。ブログを書かなくても開発者は生きていける。しかし、本当に書くべきなのであれば、書かなければならない。「書けない」と嘯いているわけにはいかない。『できる研究者の論文生産術』は、そのような状況に対する処方箋だ。

できる研究者の論文生産術 どうすれば「たくさん」書けるのか (KS科学一般書)

できる研究者の論文生産術 どうすれば「たくさん」書けるのか (KS科学一般書)

この書籍は、タイトルにあるように研究者、つまり書くことを仕事としている人に向けたものだ。著者の専門である心理学の知見も用いながら、「書く」ためのアドバイス・知見を紹介してくれる。ブログと研究論文との間の違いはあるが、その知見はブログ執筆にも役立てることができる。

「書けない」は「書いていない」でしかない

『できる研究者の論文生産術』は、「書けない」言い訳を封じていく*1。以下に掲げるものが、議論の対象となる4つの言い訳である。

  • 「書く時間がとれない」「まとまった時間さえとれれば、書けるのに」
  • 「もう少し分析しないと」「もう少し論文を読まないと」
  • 「文章をたくさん書くなら、新しいコンピュータが必要だ」
  • 「気分がのってくるのを待っている」「インスピレーションが湧いたときが一番よいものが書ける」

書籍では、これらの書けない言い訳を、一つ一つ論破していく。たとえば、スケジュールを守って書くことを拒む言い訳に対しては、以下のように辛辣に応答する。

「一気書き」派の面々は、執筆生産性の低さに話が及ぶと、自分のダメな性格に言及することが多いようだ。いわく、「自分は、スケジュールを立てたり、守ったりするようながらじゃない」。むろん、こういう議論に意味はない。人間というのは、変化を拒むときには、自分の気質のせいにしたがるものだ(Jellison, 1993)。「スケジュールなんてがらじゃない」と言う人ほど、別の場面ではスケジュールを完璧に守って、常に同じ時間に授業をし、就寝し、好きなテレビ番組を見たりしているものだ。*2

スケジュールを守れないと言っている人がその他の場面ではスケジュールを守っている。こういうことはよくある。当人に言わせれば、好きなことはスケジュール通りできるが、気が進まないものは無理ということだろう。しかし、こう答えることによって「スケジュールを守れない」というのが本当の原因ではないと語っているのである。

執筆時間を設ける

冒頭で、「書けない」時期に言及した。この言い訳に対しても、この書籍は応答する。曰く、「書けない」というのは、「書いていない」ということの言い換えでしかない。

スランプというのは自家撞着のよい例だろう。行動を描写しても、描写された行動の説明にはならない。スランプというのは、書かないという行動以外の何ものでもない。スランプだから書けないというのは、単に、書いていないから書けないと言っているにすぎない。それだけ。スランプという言い訳の治療がもし可能だとすれば、治療としては、書くことしかありえない。*3

対処法として提示されるのは、執筆時間を設けて、その時間に必ず書くようにするということだ。書籍中では、実験において、書くことを強制された群が、気が向いた時に書けばいいとされた群に比して多くの分量を執筆したということを論拠として挙げている。驚くべきなのは、執筆の強制によって単に量が改善しただけでなく、独創的な発想もまたより多く現れたということである。量は質に転化するとよくいうが、通常ひらめきの産物と思われがちな独創もまた量から生まれるというのである。

30分の執筆時間を設けろと言われた時に、「そう言われても書くことがないよ」という反応が当然出る。それに対しては著者は明確な答えを用意している。調査などの書くために必要な作業は、すべてその時間に行えばいいというのだ。

このぼろぼろの言い訳から脱却するのは簡単だ。執筆に必要な作業は、作業の種類を問わず、執筆時間中に行うこと。(中略)書くというのは、文字を入力するだけではない。書くというプロジェクトを遂行するうえで必要な作業は、すべて執筆作業だと考えてよい。*4

30分、一文字も書かなかったとしても、書くための作業をする。これを繰り返していけばよい。書けるようになる根拠は書籍中で示されている。もし仮にそれでも書けなかったとしたら、という疑問も出てくるが、それはそれでも良いのではないかと自分は思う。その30分は無駄には決してならないし、自分を許すことができると思うからだ。「書きたい」「書くべき」と思っているのに何も行動できていないときほど、自分を嫌いになるタイミングはないからだ。

研究者と開発者と執筆

研究者というのは、書くことを本分とする職業だ。大学教員などであれば、教育というのも確かに重要な職責だが、それは大学教員が研究者と教育者の両方を担うからでしかない。研究者は書かなければならない。

これに対して、ソフトウェア開発者はブログを書く必要はない。『できる研究者の論文生産術』で語られるメソッドをそのまま生活に適用しなければ生きていけない職業ではない。しかし、そういった中でブログを書こうとするのであれば、効果的に執筆作業を進められる習慣を身につけることには意味がある。

もし、ブログを書こうと思っているのに、そのために必要な行動が取れていないとすれば、「自分は本当にブログを書こうと思っているのか」を問うべきだろう。

できる研究者の論文生産術 どうすれば「たくさん」書けるのか (KS科学一般書)

できる研究者の論文生産術 どうすれば「たくさん」書けるのか (KS科学一般書)

小さな習慣

小さな習慣

*1:kakakakakkuさんのブログメンタリングにも通ずるところがある。

*2:16ページ。

*3:52ページ。

*4:20ページ。