キャッシュは”アーキテクチャの臭い”か?

この記事は、Robert Annett氏による、”Is caching an ’Architectural Smell’?”を、ご本人の許可を得て翻訳したものです。*1

This article is translated from ”Is caching an ’Architectural Smell’?” written by Mr. Robert Annett, with his permission.


キャッシュは”アーキテクチャの臭い”か?

Kent Beckは、Marin Fowlerの有名なリファクタリングの書籍に取り組んでいた際に、”コードの臭い”という概念を導入した。私はほとんどの人が、彼が特定した多くの悪臭に同意するだろうと思う。おそらく私たちの大部分が、長すぎるメソッドや、死んでいるコードなどを自動的に検知するために、checkstyleなどのツールを使用している。もしこの概念に慣れていない人は、是非上のリンクを呼んで欲しい。基本的な前提は、次のようなものである。

コードの臭いとは、システムにおける更に深刻な問題に対応するような、表面に現れる兆しである。

私たちは、コードの”臭い”が、即時に悪いということを意味するのではく、調査し正当化する価値があるものということを意味するのを、理解しておかなければならない。

更にもう一段抽象化のレイヤーを上り、色々な”アーキテクチャの臭い”を特定することができる。最近のこのブログ記事が、私が考えているものの一つに関連している。それは、キャッシュの(度を過ぎた)使用だ。

私は過去に、キャッシュに関するひどいトラブルに出会ったことがある。操作のタイミングに依存するため、再現するのが難しいようなバグが含まれているものだ。問題が数千回の操作ごとにしか発生せず、デバッガやログを仕掛けると消えてしまうような、並行システムで見られるバグと同様だ。他の全てのパフォーマンス・チューニングと同じく、本来キャッシュはそこにパフォーマンスの問題があるとわかった”後”に、導入すべきものである。しかしながら、あまりにも簡単に導入できるため、開発者たちはどこにでもキャッシュを使ってしまう。もちろん、キャッシュのヒット率が低ければ、パフォーマンスは実際にはキャッシュ導入後に悪化してしまうだろう。

あなたがこの意見に同意するかもしれないし、しないかもしれない(そして私は非難されるだろうこともわかっている)。しかし、なぜ私はキャッシュをアーキテクチャの臭いと考えるのだろうか?

完全なシステムにおいては、ビジネスロジックは、必要となるごとに、毎回データそのものにアクセスする。(ローカルまたはリモートの)アクセスは、非機能要件に合致し、取得されるデータはいつも本来のソース/システムから取得され、古くなっているようなことはない。

実世界に戻ると、システムは最初にデザインされたような方法で使用されることはない。想像した以上のユーザがシステムを使用し、そして彼らは待つことに我慢できないからだ。

個々のレイヤーにおいて、キャッシュを導入しようという誘惑、そこに問題が存在する。あまりにも簡単に導入でき(Springでは、数行の設定によって、データベース・アクセスのコンポーネントにキャッシュの導入が可能)、ユーザーのレスポンス感を劇的に改善することができる。それはただ乗りできるものなのだろうか?キャッシュシステムで使用可能なオプションを詳細に見ると、全てデータベースに関連するような種類のものであることを見るだろう。それはまさに小さなデータベースといっても驚きではない。あなたはデータの鮮度やダーティ・リード、ターティ・ライト、更新スケジュールなどを考慮しただろうか?データに対する全てのクライアントが、同じタイミングで、同じデータを見るのだろうか?更新が漏れることはあるか?更新を通知してもらうのか、それとも問い合わせるのか?データはまとめられるのか、グルーピングされるのか、それとも省略されるのか?データの使用に応じて、あなたがこれらの問いに答え、キャッシュが有効で正しい解決であることを決めているのならば – 素晴らしい!そうでなければ、キャッシュの使用は、私が述べたようなバグを埋め込むことになるだろう。

いずれにしろ、それはやはりアーキテクチャの臭いである。おそらく最も良い解決法は、システムを通じてどのようにデータが分散され、アクセスされるのかを再吟味することだ。例えば:

  • たぶんシステムの中央に巨大なデータベースを配置するのが最も良い案なのではなく、おそらく異なった責務の、複数のデータベースを必要とするのではないか? (巨大なリモート・データベースの問題は、キャッシュを必要とすることだ)
  • たぶん非同期のメッセージング・システムで複数のメッセージを処理する方が、単一のリクエスト/レスポンス・システムよりよいのではないか?
  • おそらくリクエストに紐づくデータは、リクエストそのものと共にシステムに送られるべきなのではないか?(リッチ化されたリクエスト)
  • あるデータ(例えば、静的なもの)は、要求されキャッシュされるより、むしろ明示的にローカルに保持すべきではないか?
  • あるデータは、符号化方式を変更すべきなのではないか?XMLへ/からの変換は、かなりの時間を要する。
  • オーバーヘッドを減らすために、大きな、もしくは小さなブロックでデータを要求できないか?ループの中でデータベース呼び出しを行うのは良く知られた問題である。

私はこのやり方が、数行の設定を追加するより多くの労力を要求するが、間に合わせというよりむしろアーキテクチャが論理的に発展して行く方法であることを高く評価する。キャッシュの導入は、アーキテクチャ上の決定であり、コーディング上の決定ではないのだ。

私たちが見つけるべき、あなたのお気に入りのアーキテクチャの臭いはなんだろうか?私は既に別のものに言及している。”どこにでもXML”である。


(翻訳者のコメント)

”コードの臭い”は有名ですが、”アーキテクチャの臭い”というテーマはあまり見かけたことがなかったため、紹介させていただきました。キャッシュが”アーキテクチャの臭い”であるかどうかは意見の分かれるところかと思いますが、私たちの多くが悩まされる「データの不整合」という問題の一つの源なのではないでしょうか。

それにしても、特定のコードから何となく受けるあのいやな感じや気づきを、身体的な感覚である”smell”で表したKent Beckのセンスは素晴らしいと思います。優秀な開発者やアーキテクトは、言葉の使い方やセンスも非常に優れているという僕の仮説に対する、まさに一つの証明例です。

*1:原文公開日:2011年10月2日。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です