見出し画像

第1章 信頼性、スケーラビリティ、メンテナンス性に優れたアプリケーション

要約

信頼性、スケーラビリティ、メンテナンス性はソフトウェアシステムの重要な課題です。
信頼性はフォールトに対処し、障害に強いシステムを構築すること。スケーラビリティはシステムが負荷に対応できる能力であり、オートスケーリングだけでなく、設計変更も含む。メンテナンス性は初期開発だけでなく、運用中のメンテナンスコストも考慮し、単純性、進化性に注力する。
以上、この3つが重要になります。

データシステムに関する考察

最近はデータベースとメッセージキュー等のツールがしばらくの間データを保存するという類似性を持っていますが、アクセスパターンが異なり、特性が異なると言う特徴を持っていますが、それら全てをデータシステムと言う広い用語でまとめています。

最近ではデータのストレージやその処理のためのツールはどんどん登場してきています。以下のようなツールの境界線がどんどん曖昧になってきている現状があります。

  • データストアでありながらメッセージキューとしても使えるRedis

  • メッセージキューでありながらデータベースのような耐久性を保障しているApache Kafka

ソフトウェアシステムにおける3つの課題

ソフトウェアシステムにおいて以下のような3つの課題を常に抑える必要があります。

  • 信頼性

  • スケーラビリティ

  • メンテナンス性

信頼性

信頼性とは何か問題が生じたとしても正しく動作し続けることです。
ここで問題を起こし得るものはフォールトと呼ばれ、フォルトの存在を見越して対処できるようなシステムを耐障害性を持つなどといいます。通常、フォールトは仕様を満たしていないコンポーネントとして定義されますが、障害はシステムが全体として必要なサービスのユーザへの提供を止めてしまった場合を指します。

この本では、耐障害性を持つシステムでは意図的にフォールトを発生させることで、フォールトの割合を増加させることが理にかなっている場合があると記載があります。
具体的な方法でいうと、ランダムに個々のプロセスを kill するといったことです。実際のところ、よくある原因として多くの致命的なバグは、エラー処理が貧弱なことによるものが多いのです。

例えば、信頼性を損なう要因としてハードウェアやソフトウェアの障害があります。
データの量やアプリケーションに求められる処理量が増大するにつれて、大量のマシンを使うアプリケーションが増え始め、それに比例して、ハードウェアのフォールトの発生率も増大するようになりました。
AWSのようなクラウドが登場してきたため、ハードウェアの障害は減ってはいます。ただし、ソフトウェアのバグやカスケード障害などのソフトウェア障害はまだまだ減っていません。そういった際に常にソフトウェアでは異常があればアラートを出すような設計をする必要があります。

また、ヒューマンエラーについても「 最大限に努力しても、人間には信頼性がないことが知られています」とエンジニアとして、仕組みを作る者として重要だという言及があります。 ヒューマンエラーから脱するために、ユニットテストや結合テストなどすべてのレベルで徹底的なテストを行います。また、エラーの発生率などモニタリングの仕組みもセットアップします。

主要因子絞込みによる分析負荷低減のイメージ(IPAより)

スケーラビリティ

スケーラビリティとは、負荷の増大に対してシステムが対応できる能力のことを指します。ソフトウェアシステムの劣化の原因として、一般的なものの1つとして不可の増大があります。ウェブサーバーの毎秒のリクエスト数やデータベースの読み書きの比率、アクティブ数などが挙げられます。

スケーラビリティと聞くと、サーバーを自動的にアクセス数に応じて増減させるオートスケーリングを思い浮かべるかもしれませんが、本書では設計を変えるような広い意味で使われています。

例えば、Twitter(現在はX)のDB検索時に読み込み負荷が高いことから、書き込み処理をすることにより読み込み処理を減らす変更を行なった。

その他にもパフォーマンスを見ることが重要になります。
例えば、Hadoopのようなバッチ処理システムの場合は、通常スループットに注目します。これは1秒あたりに処理できるレコード数やデータセットに対して1つのジョブを実行するのにかかる合計時間になります。
また、計測可能な値は分布として捉える必要があり、 パーセンタイルを使うことで中央値を把握することも重要になります。

メンテナンス性

ソフトウェアには初期開発コストだけではなく、運用中のメンテナンスコストも発生します。ソフトウェアシステムの注意点としては、以下の3つの設計原理に着目する必要があります。

  • 運用性

  • 単純性

  • 進化性

よく勘違いされていますが、単純化はエンジニアが構築するシステムにとって目標であるべきです。単純にするという事は偶発的な複雑さを取り除くことができます。
そして、この複雑さを取り除くための最も優れた手段の1つが抽象化になります。大規模なシステムの一部を抜き出して定義された再利用可能なコンポーネント化することが重要になります。

また、システムが永遠に変わらないままであり、続ける事はあり得ません。開発者は新しいことを学び、以前は予想されていなかったユースケースがあがり、ビジネスの優先順位は入れ替わり、古いプラットフォームは新しいものに置き換えられ、システムの成長に伴ってアーキテクチャーを変更せざるを得なくなります。そういった時に変更しの変更のしやすさ進化のしやすさと言う観点が必要になってきます。

まとめ

以上、信頼性、スケーラビリティ、メンテナンス性に優れたアプリケーションについて解説しました。
データ量が劇的に増大する世の中で3つの課題を常に考えながら設計をする必要があります。
信頼性、スケーラビリティ、メンテナンス性に優れたアプリケーションについて特に重要な点を解説しました。ただし、非常に量が多いため解説していない部分が多々あります。詳細は本書を手にとってみて下さい。

いいなと思ったら応援しよう!

zono
よろしければ応援お願いします! いただいたチップはデータエンジニアとしての活動費や勉強代、教育に使わせていただきます!