かめあるき

プログラミング駄文。

システムデザインを勉強した【1周目】

システムデザインについて勉強しました。

まだほぼ概要が理解できていない状態なので、厳密な説明や定義より平易な表現を選んでいる(というかそれしかできない)ものの、なにかマズそうな嘘が書いてあったら教えていただけると助かります。

現状

  • CSなし、崖っぷち応用情報技術者
  • システム設計の学習・経験無し。
  • system-design-primerをパッと見た感じあんまりよくわからなかった。

目標

  • とりあえず大まかな用語について意味を自分なりに噛み砕いて理解する。
  • 学習する内容の全容をざっくり把握する。
  • これからどんな内容を掘り下げる必要があるのかなんとなく把握する。

使用した教材

github.com

有名なシステムデザインのGitHubリポジトリだけど現状読むための実力もない気がする。日本語でも3回は読みたい。

qiita.com

比較的文調や内容がsystem-design-primerより読みやすそう(まだ読んでる途中)。

あとは随時ググった。

なぜSystem Designを学ぶ必要があるのか

  • たくさんのユーザーがたくさんアクセスしても快適に使えるシステムを構築するため。竸プロで計算量の考え方が大事になるように、システムにめちゃくちゃアクセスされたときに備えて工夫が必要。
  • 障害に備えてシステム構築できるようにするため。システムを🌹世界でたった1つのサーバー🌹で運用すると、そのサーバーがぶっ壊れたとき、誰もシステムが使えなくなったり、二度とデータが蘇らなくなったりする。
  • 快適で壊れないシステムを創るのは、実は結構難しいため。じゃあサーバーを増やそうとかつよつよサーバーを使えばいいとか、案外そういう単純な解決ができない。費用の問題もあるし、サーバーのお世話(運用)の手間が増える場合もある。サーバー同士が勝手に協働してくれたりもしないので、全体でうまく動作するように(整合性を維持できるように)仕組みづくりする必要もある。

System Designでは何を学ぶのか

スケーラビリティ

https://www.sophia-it.com/content/%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%A9%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3

  • 「拡張性」の意味。
  • いまよりたくさんのユーザーやアクセスが押し寄せても対応できるようにしてあれば「スケーラビリティが高い」という。
  • 逆にあまり使われなくなったらミニマルなシステム構成に変更できるようになっている状態も「スケーラビリティが高い」という。
  • つまり、システムの規模(サーバーの性能とか台数とか)を柔軟に変更できる度合いのことをスケーラビリティという。
  • スケーラビリティに関する考え方(原因・対策とか)を学ぶ。

トレードオフ

  • 「強化素材モリモリにしたから大丈夫」みたいな単純な話はない。
  • 何かを手に入れようとすると何かを失う…せつない…。
  • そのシステムに何が求められているのかを考えて、適切な手段を取捨選択する必要がある。
  • いろんな手段のいろんな特徴(なにができるのか、なにができないのか、カネはかかるのか、手間はかかるのか)を把握する必要がある。

分散システム

  • 英語だと「Distributed System」(ディストリビューテッドシステム)。
  • 結局どういうシステム構成にするのが良いかというと、1台のつよつよサーバーを使うのではなく、複数のふつうのサーバーを使おうという話になる事が多い。
  • 管理がめんどくさくなったりして課題は多いので、理解して対処する必要がある。

いろんな道具

容量・用法を守って正しく使う。

DNS

  • ドメインネームシステム(Domain Name System)。ディーエヌエス
  • Webページを見たり、友達にメールを送ったりするには、本当はネットワーク上の住所であるIPアドレス(「127.0.0.0」「192.168.0.0」みたいな数字)が必要。
  • 数字の羅列は人間には厳しいので、人間にやさしいドメインネーム(「www.google.com」「www.example.com」みたいな文字列)でもアクセスできるようになっている。
  • でもコンピュータはIPアドレスがわからないとアクセスできないので、ドメインネームをIPアドレスに変換してくれるDNSが必要。

CDN

  • コンテンツデリバリーネットワーク(Content Delivery Network)。シーディーエヌ。
  • 日本から日本のサーバーにあるWebページにアクセスするより、日本からアメリカのWebページにアクセスするほうが時間がかかる。遠いから。
  • 例えばログインするとき、ログインIDとパスワードが正しいかどうかはアメリカのサーバーにリクエストして処理する必要があるけど、次に表示するHTMLや画像はログインできたかどうかあまり関係なく使うので、切り離して別の場所においておいても問題ないかもしれない。
  • HTMLや画像のような静的コンテンツだけ、日本(あるいはアジア圏の他の国など、できるだけ近く)のデータセンターから取得すれば、早くWebページを表示できる。
  • 静的コンテンツをいろんな地域に置いておいて、アクセスされた場所に近いところからデータを取得できるように、いろいろよしなにしてくれるのがCDN

ロードバランサー

  • 同じ仕事をしているサーバーが複数あるとき、ドッと押し寄せたたくさんのアクセス(トラフィック)を受け止めて、「いい感じ」にサーバー達に仕事を振り分けてくれる。
  • 「いい感じ」がどんな感じなのかはいくつか種類があって状況に合わせて選ぶ(負荷分散アルゴリズムとか)。

リバースプロキシ

  • 窓口みたいな感じ
  • リバースプロキシにアクセスすれば、必要なシステムを呼び出して、結果だけ返してくれる。
  • クライアントはリバースプロキシだけ見ればいい。
  • サーバー側も内部を隠せるので、安全で変更がし易い。
  • (実はあまりロードバランサーとの違いがわかってないが、状況によって使い分けるらしい。)

データベース

  • RDBMSやNoSQLとかの、データを格納したり取り出したりできるシステム。
  • I/O(データの読み書き)の速度を上げるにはどうしたら良いか?
  • トラブルが起きたとき、システムを止めない・データが失われないようにするにはどうしたら良いか(耐障害性・冗長性)?
  • どんなシステムで、どんなデータベースを使うのが適切か?

キャッシュ

  • アクセスされたコンテンツを一定期間記憶しておいて、同じコンテンツにアクセスされたときにサーバーに問い合わせなくても素早く取り出して応答できる。
  • どのコンテンツを、どのくらいの期間、どのタイミングで覚えて(キャッシュして)おくか?

非同期処理(メッセージキューなど)

  • アクセスや処理を一時的にためておいて、サーバーが処理できるようになったタイミングで遅れて処理できるようにする仕組み。
  • ユーザーは処理結果が返ってくるまで作業を止められることはないが、リアルタイムで(即座に)処理結果を受け取ることができない(処理結果が反映されるまでに遅れがある)。

読後感

  • 詳しい部分はかなり読み飛ばしたが、ひとまず勉強する内容や単語をさらっとさらえた。
  • 一番大まかな用語の意味は理解できたと思うので、きちんと頭に定着させることと、メリット/デメリットとどんな状況で使うかくらいは2周目で理解できるようにしたい。
  • 上記で挙げた「いろんな道具」については、さらにそれぞれの道具について種類が豊富にあってベストプラクティスとかもあるみたいだが、3周目以降で理解できるようにしたい。