system-design-primer - 大規模システムの設計方法を学びます。システム設計面接の準備。アンキのフラッシュカードが含まれています。

(Learn how to design large-scale systems. Prep for the system design interview. Includes Anki flashcards.)

Created at: 2017-02-27 00:15:28
Language: Python
License: NOASSERTION

英語日本語简体中文 ∙ 繁體中文 |العَرَبِيَّةবাংলাポルトガル語 do Brasilドイツ語 ∙ ελληνικάעבריתイタリア語 ∙ 한국어 فارسیPolskiрусский языкスペイン語ภาษาไทยTürkçetiếng Việt Français |翻訳の追加

このガイドの翻訳を手伝ってください!

システム設計入門


モチベーション

大規模システムの設計方法を学びます。

システム設計面接の準備。

大規模システムの設計方法を学ぶ

スケーラブルなシステムの設計方法を学ぶことは、より良いエンジニアになるのに役立ちます。

システム設計は幅広いトピックです。システム設計の原則に関する膨大な量のリソースがWeb全体に散らばっています

このリポジトリは、大規模なシステムを構築する方法を学習するのに役立つリソースの整理されたコレクションです。

オープンソースコミュニティから学ぶ

これは継続的に更新されるオープンソースプロジェクトです。

貢献は大歓迎です!

システム設計面接の準備

インタビューのコーディングに加えて、システム設計は、多くのテクノロジー企業でのテクニカルインタビュープロセスの必須コンポーネントです。

一般的なシステム設計の面接の質問を練習し、結果をサンプルソリューション(ディスカッション、コード、図)と比較します。

面接準備に関する追加トピック:

アンキフラッシュカード


提供されているAnkiフラッシュカードデッキは、間隔を空けた繰り返しを使用して、主要なシステム設計コンセプトを保持するのに役立ちます。

外出先での使用に最適です。

コーディングリソース:インタラクティブなコーディングの課題

コーディング面接の準備に役立つリソースをお探しですか?


追加のAnkiデッキを含む姉妹リポジトリのインタラクティブコーディングチャレンジをチェックしてください。

貢献

コミュニティから学びましょう。

プルリクエストを送信して、以下を確認してください。

  • エラーを修正する
  • セクションを改善する
  • 新しいセクションを追加する
  • 翻訳

ある程度の推敲が必要なコンテンツは開発中です。

投稿ガイドラインを確認します。

システム設計トピックのインデックス

長所と短所を含むさまざまなシステム設計トピックの要約。 すべてがトレードオフです

各セクションには、より詳細なリソースへのリンクが含まれています。


学習ガイド

面接のタイムラインに基づいて確認する推奨トピック(短、中、長)。

イムグル

Q:面接のために、私はここですべてを知る必要がありますか?

A:いいえ、面接の準備をするためにここですべてを知る必要はありません

面接で尋ねられる内容は、次のような変数によって異なります。

  • あなたがどれだけの経験を持っているか
  • あなたの技術的背景は何ですか
  • 面接するポジション
  • 面接する企業

経験豊富な候補者は、一般的にシステム設計についてもっと知っていることが期待されます。アーキテクトやチーム リーダーは、個々のコントリビューターよりも多くのことを知っていることが期待される場合があります。トップテクノロジー企業は、1回以上のデザイン面接ラウンドを行う可能性があります。

幅広く始めて、いくつかの分野で深く掘り下げてください。さまざまな主要なシステム設計トピックについて少し知っておくと役立ちます。タイムライン、経験、面接するポジション、面接する企業に基づいて、次のガイドを調整してください。

  • 短いタイムライン - システム設計のトピックでを広げることを目指します。面接の質問を解いて練習します。
  • 中程度のタイムライン - システム設計のトピックで深さを目指します。多くの面接の質問を解いて練習します。
  • 長いタイムライン - システム設計のトピックで深さを目指します。ほとんどの面接の質問を解いて練習します。
短い 中程度 長い
システム設計のトピックを読んで、システムがどのように機能するかを幅広く理解してください 👍 👍 👍
あなたがインタビューしている会社の会社のエンジニアリングブログのいくつかの記事を読んでください 👍 👍 👍
いくつかの実世界のアーキテクチャを読む 👍 👍 👍
システム設計面接の質問へのアプローチ方法を確認する 👍 👍 👍
ソリューションを使用したシステム設計の面接の質問に取り組む 多い 最も
オブジェクト指向設計の面接の質問をソリューションで解決する 多い 最も
システム設計に関するその他の面接の質問を確認する 多い 最も

システム設計面接の質問へのアプローチ方法

システム設計の面接の質問に取り組む方法。

システム設計インタビューは自由形式の会話です。あなたはそれを導くことが期待されています。

次の手順を使用して、ディスカッションをガイドできます。このプロセスを固めるには、次の手順を使用して、ソリューションを使用したシステム設計面接の質問セクションに取り組みます。

ステップ 1: ユースケース、制約、前提条件を概説する

要件を収集し、問題の範囲を特定します。ユースケースと制約を明確にするために質問をします。仮定について話し合います。

  • 誰がそれを使うつもりですか?
  • 彼らはそれをどのように使うつもりですか?
  • ユーザーは何人いますか?
  • システムは何をしますか?
  • システムの入力と出力は何ですか?
  • どのくらいのデータを処理する予定ですか?
  • 毎秒いくつのリクエストが予想されますか?
  • 予想される読み取りと書き込みの比率はどれくらいですか?

ステップ 2: 高レベルの設計を作成する

すべての重要なコンポーネントを含む高レベルの設計の概要を説明します。

  • 主要コンポーネントと接続のスケッチ
  • アイデアを正当化する

ステップ 3: コアコンポーネントを設計する

各コアコンポーネントの詳細を詳しく説明してください。たとえば、URL 短縮サービスの設計を依頼された場合は、以下について話し合います。

  • 完全なURLのハッシュの生成と保存
    • MD5 および Base62
    • ハッシュの衝突
    • SQL または NoSQL
    • データベース スキーマ
  • ハッシュされた URL を完全な URL に変換する
    • データベース検索
  • API とオブジェクト指向の設計

ステップ 4: 設計のスケーリング

制約を考慮して、ボトルネックを特定して対処します。たとえば、スケーラビリティの問題に対処するには、次のものが必要ですか?

  • ロードバランサー
  • 水平スケーリング
  • キャッシング
  • データベースのシャーディング

考えられる解決策とトレードオフについて話し合います。すべてがトレードオフです。スケーラブルなシステム設計の原則を使用してボトルネックに対処します。

封筒裏の計算

手作業で見積もりを行うように求められる場合があります。次のリソースについては、付録を参照してください。

出典と参考文献

次のリンクをチェックして、何を期待できるかをよりよく理解してください。

ソリューションによるシステム設計面接の質問

一般的なシステム設計面接の質問と、サンプルディスカッション、コード、および図。

フォルダー内のコンテンツにリンクされたソリューション。

solutions/

質問
設計 Pastebin.com(または Bit.ly) 解決
Twitterのタイムラインと検索(またはFacebookのフィードと検索)をデザインする 解決
Web クローラーを設計する 解決
設計 Mint.com 解決
ソーシャル ネットワークのデータ構造を設計する 解決
検索エンジンのキーと値のストアを設計する 解決
Amazonのカテゴリー別売上ランキング機能のデザイン 解決
AWS 上の数百万人のユーザーに拡張できるシステムを設計する 解決
システム設計の質問を追加する 貢献する

設計 Pastebin.com(または Bit.ly)

演習と解決策を見る

イムグル

Twitterのタイムラインと検索(またはFacebookのフィードと検索)をデザインする

演習と解決策を見る

イムグル

Web クローラーを設計する

演習と解決策を見る

イムグル

設計 Mint.com

演習と解決策を見る

イムグル

ソーシャル ネットワークのデータ構造を設計する

演習と解決策を見る

イムグル

検索エンジンのキーと値のストアを設計する

演習と解決策を見る

イムグル

Amazonのカテゴリー別売上ランキング機能のデザイン

演習と解決策を見る

イムグル

AWS 上の数百万人のユーザーに拡張できるシステムを設計する

演習と解決策を見る

イムグル

ソリューションによるオブジェクト指向設計面接の質問

一般的なオブジェクト指向設計の面接の質問と、サンプルのディスカッション、コード、および図。

フォルダー内のコンテンツにリンクされたソリューション。

solutions/

注:このセクションは開発中です

質問
ハッシュ マップを設計する 解決
最も長く使用されていないキャッシュを設計する 解決
コール センターを設計する 解決
カードのデッキをデザインする 解決
駐車場を設計する 解決
チャット サーバーを設計する 解決
循環配列を設計する 貢献する
オブジェクト指向設計の質問を追加する 貢献する

システム設計のトピック: ここから開始

システム設計は初めてですか?

まず、一般的な原則の基本的な理解、それらが何であるか、それらがどのように使用されるか、およびそれらの長所と短所について学ぶ必要があります。

手順 1: スケーラビリティのビデオ講義を確認する

ハーバード大学でのスケーラビリティ講義

  • 取り上げるトピック:
    • 垂直スケーリング
    • 水平スケーリング
    • キャッシング
    • 負荷分散
    • データベース レプリケーション
    • データベース・パーティション化

手順 2: スケーラビリティに関する記事を確認する

拡張性

次のステップ

次に、高レベルのトレードオフを見ていきます。

  • パフォーマンススケーラビリティ
  • 待機時間とスループット
  • 可用性一貫性

すべてがトレードオフであることに注意してください。

次に、DNS、CDN、ロードバランサーなどのより具体的なトピックについて詳しく説明します。

パフォーマンスとスケーラビリティ

サービスは、追加されたリソースに比例してパフォーマンスが向上する場合、スケーラブルです。一般に、パフォーマンスの向上は、より多くの作業単位を提供することを意味しますが、データセットが大きくなる場合など、より大きな作業単位を処理することもできます。1

パフォーマンスとスケーラビリティを見る別の方法:

  • パフォーマンスに問題がある場合は、1 人のユーザーに対してシステムが遅くなります。
  • スケーラビリティに問題がある場合、システムは 1 人のユーザーにとっては高速ですが、高負荷では低速になります。

出典と参考文献

待機時間とスループット

レイテンシーは、何らかのアクションを実行したり、何らかの結果を生成したりする時間です。

スループットは、単位時間あたりのそのようなアクションまたは結果の数です。

一般に、許容可能な待機時間最大のスループットを目指す必要があります。

出典と参考文献

可用性と一貫性

キャップ定理


出典:CAP定理の再考

分散コンピューター システムでは、次の保証のうち 2 つだけをサポートできます。

  • 整合性 - すべての読み取りが最新の書き込みまたはエラーを受け取る
  • 可用性 - すべての要求は応答を受信しますが、最新バージョンの情報が含まれているという保証はありません。
  • パーティショントレランス - ネットワーク障害による任意のパーティション分割にもかかわらず、システムは動作し続けます

ネットワークは信頼できないため、パーティションの許容範囲をサポートする必要があります。一貫性と可用性の間でソフトウェアのトレードオフを行う必要があります。

CP - 整合性とパーティションの許容範囲

パーティション・ノードからの応答を待機すると、タイムアウト・エラーが発生する可能性があります。CPは、ビジネスニーズにアトミックな読み取りと書き込みが必要な場合に適しています。

AP - 可用性とパーティションの許容範囲

応答は、任意のノードで使用可能なデータの最も簡単に利用できるバージョンを返しますが、最新ではない可能性があります。パーティションが解決されると、書き込みが反映されるまでに時間がかかる場合があります。

APは、ビジネスが最終的な一貫性を考慮する必要がある場合、または外部エラーにもかかわらずシステムが動作し続ける必要がある場合に適しています。

出典と参考文献

整合性パターン

同じデータの複数のコピーがある場合、クライアントがデータの一貫したビューを持つように、それらを同期する方法に関するオプションに直面しています。CAP定理から一貫性の定義を思い出してください-すべての読み取りは最新の書き込みまたはエラーを受け取ります。

弱い一貫性

書き込み後、読み取りでは表示される場合と表示されない場合があります。ベストエフォートアプローチが取られます。

このアプローチは、memcachedなどのシステムで見られます。弱い一貫性は、VoIP、ビデオチャット、リアルタイムマルチプレイヤーゲームなどのリアルタイムユースケースでうまく機能します。たとえば、通話中に数秒間受信が途絶えた場合、接続を回復しても、接続が失われたときに話された内容が聞こえません。

最終的な整合性

書き込み後、読み取りは最終的にそれを確認します (通常はミリ秒以内)。データは非同期的にレプリケートされます。

このアプローチは、DNSや電子メールなどのシステムで見られます。最終的な整合性は、高可用性システムで適切に機能します。

強力な一貫性

書き込み後、読み取りはそれを認識します。データは同期的にレプリケートされます。

このアプローチは、ファイルシステムとRDBMSで見られます。強力な一貫性は、トランザクションを必要とするシステムで適切に機能します。

出典と参考文献

可用性パターン

高可用性をサポートするには、フェールオーバーとレプリケーションという 2 つの補完的なパターンがあります。

フェイルオーバー

アクティブ-パッシブ

アクティブ/パッシブ フェールオーバーでは、スタンバイ状態のアクティブ サーバーとパッシブ サーバーの間でハートビートが送信されます。ハートビートが中断されると、パッシブ サーバーがアクティブ サーバーの IP アドレスを引き継ぎ、サービスを再開します。

ダウンタイムの長さは、パッシブ サーバーが既に "ホット" スタンバイで実行されているかどうか、または "コールド" スタンバイから起動する必要があるかどうかによって決まります。アクティブなサーバーのみがトラフィックを処理します。

アクティブ/パッシブフェイルオーバーは、マスター/スレーブフェイルオーバーとも呼ばれます。

アクティブ-アクティブ

アクティブ/アクティブでは、両方のサーバーがトラフィックを管理しており、サーバー間で負荷を分散しています。

サーバーが公開されている場合、DNS は両方のサーバーのパブリック IP について認識する必要があります。サーバーが内部向けである場合、アプリケーション ロジックは両方のサーバーについて認識する必要があります。

アクティブ/アクティブ フェールオーバーは、マスター/マスター フェールオーバーとも呼ばれます。

デメリット:フェイルオーバー

  • フェールオーバーにより、ハードウェアが増え、複雑さが増します。
  • 新しく書き込まれたデータをパッシブに複製する前にアクティブシステムに障害が発生すると、データが失われる可能性があります。

複製

マスタースレーブおよびマスターマスター

このトピックについては、「データベース」セクションで詳しく説明します。

数字で見る可用性

可用性は、多くの場合、サービスが利用可能な時間の割合としてのアップタイム (またはダウンタイム) によって定量化されます。可用性は通常、9 の数で測定され、99.99% の可用性を持つサービスは 9 つの <> を持つと説明されます。

99.9% の可用性 - 9 つの <>

期間 許容可能なダウンタイム
年間ダウンタイム 8時間45分57秒
月あたりのダウンタイム 43メートル49.7秒
週あたりのダウンタイム 10メートル4.8秒
1 日あたりのダウンタイム 1メートル26.4秒

99.99% の可用性 - 9 つの <>

期間 許容可能なダウンタイム
年間ダウンタイム 52分35秒7
月あたりのダウンタイム 4メートル23秒
週あたりのダウンタイム 1メートル5秒
1 日あたりのダウンタイム 8.6秒

並列対順次での可用性

サービスが障害が発生しやすい複数のコンポーネントで構成されている場合、サービスの全体的な可用性は、コンポーネントが順番に並んでいるか並列になっているかによって異なります。

順番に

全体的な可用性は、可用性が 100% < <> つのコンポーネントが順番に存在する場合に低下します。

Availability (Total) = Availability (Foo) * Availability (Bar)

両方とそれぞれの可用性が 99.9% の場合、シーケンスの合計可用性は 99.8% になります。

Foo
Bar

並行して

全体的な可用性は、可用性が 100% < <> つのコンポーネントが並列になっている場合に増加します。

Availability (Total) = 1 - (1 - Availability (Foo)) * (1 - Availability (Bar))

両方とそれぞれの可用性が 99.9% の場合、並列での合計可用性は 99.9999% になります。

Foo
Bar

ドメイン ネーム システム


ソース: DNS セキュリティに関するプレゼンテーション

ドメイン ネーム システム (DNS) は、www.example.com などのドメイン名を IP アドレスに変換します。

DNSは階層構造になっており、トップレベルにはいくつかの権限のあるサーバーがあります。ルーターまたはISPは、ルックアップを実行するときに接続するDNSサーバーに関する情報を提供します。下位レベルの DNS サーバーはマッピングをキャッシュしますが、DNS 伝達の遅延が原因で古くなる可能性があります。DNS の結果は、ブラウザーまたは OS によって、有効期限 (TTL) によって決定される一定期間キャッシュすることもできます。

  • NS レコード (ネーム サーバー) - ドメイン/サブドメインの DNS サーバーを指定します。
  • MX レコード (メール交換) - メッセージを受け入れるメール サーバーを指定します。
  • レコード (アドレス) - 名前を IP アドレスにポイントします。
  • CNAME (正規) - 名前を別の名前または (www.example.com example.com) またはレコードにポイントします。
    CNAME
    A

CloudFlareRoute 53などのサービスは、マネージドDNSサービスを提供します。一部の DNS サービスでは、さまざまな方法でトラフィックをルーティングできます。

デメリット: DNS

  • DNS サーバーにアクセスすると、上記のキャッシュによって軽減されますが、わずかな遅延が発生します。
  • DNSサーバーの管理は複雑になる可能性があり、通常は政府、ISP、および大企業によって管理されます。
  • DNSサービスは最近DDoS攻撃を受けており、ユーザーはTwitterのIPアドレスを知らなくてもTwitterなどのWebサイトにアクセスできなくなりました。

出典と参考文献

コンテンツ配信ネットワーク


ソース: CDN を使用する理由

コンテンツ配信ネットワーク (CDN) は、プロキシ サーバーのグローバルに分散されたネットワークであり、ユーザーに近い場所からコンテンツを提供します。一般に、HTML/CSS/JS、PHOTOS、ビデオなどの静的ファイルはCDNから提供されますが、AmazonのCloudFrontなどの一部のCDNは動的コンテンツをサポートしています。サイトのDNS解決は、どのサーバーに接続するかをクライアントに通知します。

CDN からコンテンツを提供すると、次の 2 つの方法でパフォーマンスが大幅に向上します。

  • ユーザーは、近くのデータセンターからコンテンツを受信します
  • サーバーは、CDN が満たす要求を処理する必要はありません。

CDN をプッシュする

プッシュCDNは、サーバーで変更が発生するたびに新しいコンテンツを受け取ります。コンテンツの提供、CDN への直接アップロード、および CDN を指すように URL を書き換えることについては、お客様が全責任を負います。コンテンツの有効期限が切れるタイミングと更新されるタイミングを構成できます。コンテンツは新規または変更された場合にのみアップロードされるため、トラフィックは最小限に抑えられますが、ストレージは最大化されます。

トラフィック量が少ないサイトや、頻繁に更新されないコンテンツを含むサイトは、プッシュCDNでうまく機能します。 コンテンツは、定期的に再プルされるのではなく、CDNに一度配置されます。

CDN をプルする

プルCDNは、最初のユーザーがコンテンツを要求したときにサーバーから新しいコンテンツを取得します。コンテンツをサーバーに残し、CDN を指すように URL を書き換えます。これにより、コンテンツが CDN にキャッシュされるまで、要求が遅くなります。

有効期限 (TTL) は、コンテンツがキャッシュされる期間を決定します。プル CDN は CDN のストレージ領域を最小限に抑えますが、ファイルの有効期限が切れ、実際に変更される前にプルされると、冗長なトラフィックが発生する可能性があります。

トラフィックの多いサイトは、トラフィックがより均等に分散され、最近要求されたコンテンツのみがCDNに残るため、プルCDNでうまく機能します。

デメリット: CDN

  • CDNコストはトラフィックによっては高額になる可能性がありますが、CDNを使用しない場合に追加コストを比較検討する必要があります。
  • TTL の有効期限が切れる前にコンテンツが更新されると、コンテンツが古くなる可能性があります。
  • CDN では、静的コンテンツの URL を CDN を指すように変更する必要があります。

出典と参考文献

ロードバランサー


ソース: スケーラブルなシステム設計パターン

ロードバランサーは、受信クライアント要求をアプリケーションサーバーやデータベースなどのコンピューティングリソースに分散します。いずれの場合も、ロード バランサーはコンピューティング リソースからの応答を適切なクライアントに返します。ロードバランサーは、次の場合に効果的です。

  • 要求が異常なサーバーに送られないようにする
  • リソースの過負荷の防止
  • 単一障害点の排除を支援

ロードバランサーは、ハードウェア(高価)またはHAProxyなどのソフトウェアを使用して実装できます。

その他の利点は次のとおりです。

  • SSLターミネーション - 着信リクエストを復号化し、サーバー応答を暗号化して、バックエンドサーバーがこれらの潜在的にコストのかかる操作を実行する必要がないようにします
    • 各サーバーに X.509 証明書をインストールする必要がなくなります。
  • セッション永続性 - Web アプリがセッションを追跡しない場合、Cookie を発行し、特定のクライアントの要求を同じインスタンスにルーティングします。

障害から保護するために、アクティブ/パッシブモードまたはアクティブ/アクティブモードで複数のロードバランサーを設定するのが一般的です。

ロードバランサーは、次のようなさまざまなメトリックに基づいてトラフィックをルーティングできます。

レイヤ 4 ロード バランシング

レイヤー 4 ロードバランサーは、トランスポートレイヤーの情報を参照して、リクエストの分散方法を決定します。通常、これにはヘッダー内の送信元、宛先 IP アドレス、およびポートが含まれますが、パケットの内容は含まれません。レイヤー 4 ロードバランサーは、ネットワークアドレス変換 (NAT) を実行して、アップストリームサーバーとの間でネットワークパケットを転送します。

レイヤ 7 ロード バランシング

レイヤー 7 ロードバランサーは、アプリケーションレイヤーを参照して、リクエストの分散方法を決定します。これには、ヘッダー、メッセージ、および Cookie の内容が含まれる場合があります。レイヤー 7 ロードバランサーは、ネットワークトラフィックを終了し、メッセージを読み取り、負荷分散の決定を行ってから、選択したサーバーへの接続を開きます。たとえば、レイヤー 7 ロード バランサーは、ビデオ トラフィックをビデオをホストするサーバーに転送し、より機密性の高いユーザーの課金トラフィックをセキュリティが強化されたサーバーに転送できます。

柔軟性を犠牲にして、レイヤー4のロードバランシングはレイヤー7よりも少ない時間とコンピューティングリソースを必要としますが、最新のコモディティハードウェアではパフォーマンスへの影響を最小限に抑えることができます。

水平スケーリング

ロードバランサーは、水平スケーリングにも役立ち、パフォーマンスと可用性を向上させます。コモディティ マシンを使用したスケール アウトは、垂直スケーリングと呼ばれる、より高価なハードウェア上の単一のサーバーをスケール アップするよりもコスト効率が高く、可用性も高くなります。また、特殊なエンタープライズシステムよりも、コモディティハードウェアで作業する人材を採用する方が簡単です。

デメリット:水平スケーリング

  • 水平方向にスケーリングすると複雑さが生じ、サーバーのクローン作成が必要になります
    • サーバーはステートレスである必要があり、セッションやプロフィール写真などのユーザー関連のデータを含めないでください
    • セッションは、データベース(SQL、NoSQL)や永続キャッシュ(Redis、Memcached)などの一元化されたデータストアに保存できます。
  • キャッシュやデータベースなどのダウンストリーム サーバーは、アップストリーム サーバーのスケールアウトに合わせて、より多くの同時接続を処理する必要があります。

デメリット:ロードバランサー

  • ロード バランサーは、十分なリソースがない場合、または適切に構成されていない場合、パフォーマンスのボトルネックになる可能性があります。
  • 単一障害点を排除するためにロード バランサーを導入すると、複雑さが増します。
  • 単一のロードバランサーは単一障害点であり、複数のロードバランサーを構成するとさらに複雑さが増します。

出典と参考文献

リバースプロキシ(ウェブサーバー)


出典:ウィキペディア

リバースプロキシは、内部サービスを集中化し、統一されたインターフェイスを一般に提供するWebサーバーです。クライアントからの要求は、リバース プロキシがサーバーの応答をクライアントに返す前に、それを実行できるサーバーに転送されます。

その他の利点は次のとおりです。

  • セキュリティの強化 - バックエンドサーバーに関する情報の非表示、IPのブラックリスト登録、クライアントあたりの接続数の制限
  • スケーラビリティと柔軟性の向上 - クライアントにはリバースプロキシのIPのみが表示されるため、サーバーの拡張や構成の変更が可能です。
  • SSLターミネーション - 着信リクエストを復号化し、サーバー応答を暗号化して、バックエンドサーバーがこれらの潜在的にコストのかかる操作を実行する必要がないようにします
    • 各サーバーに X.509 証明書をインストールする必要がなくなります。
  • 圧縮 - サーバーの応答を圧縮する
  • キャッシュ - キャッシュされた要求の応答を返します。
  • 静的コンテンツ - 静的コンテンツを直接提供する
    • HTML/CSS/JS
    • 写真
    • ビデオ

ロードバランサーとリバースプロキシ

  • ロード バランサーのデプロイは、複数のサーバーがある場合に便利です。多くの場合、ロードバランサーは同じ機能を提供する一連のサーバーにトラフィックをルーティングします。
  • リバースプロキシは、Webサーバーまたはアプリケーションサーバーが1つだけでも便利であり、前のセクションで説明した利点が開かれます。
  • NGINXやHAProxyなどのソリューションは、レイヤー7リバースプロキシとロードバランシングの両方をサポートできます。

デメリット:リバースプロキシ

  • リバースプロキシを導入すると、複雑さが増します。
  • 単一のリバースプロキシは単一障害点であり、複数のリバースプロキシ(つまり、フェールオーバー)を構成すると、複雑さがさらに増します。

出典と参考文献

アプリケーション層


出典:スケールを考慮したシステムの設計の概要

Web レイヤーをアプリケーションレイヤー (プラットフォームレイヤーとも呼ばれます) から分離すると、両方のレイヤーを個別にスケーリングおよび構成できます。新しい API を追加すると、必ずしも Web サーバーを追加することなく、アプリケーションサーバーが追加されます。単一責任の原則は、連携する小規模で自律的なサービスを提唱しています。小規模なサービスを持つ小規模なチームは、急速な成長のためにより積極的に計画を立てることができます。

アプリケーション層のワーカーは、非同期の有効化にも役立ちます。

マイクロサービス

この説明に関連するマイクロサービスは、独立してデプロイ可能な小規模なモジュラーサービスのスイートとして説明できます。各サービスは独自のプロセスを実行し、明確に定義された軽量のメカニズムを介して通信して、ビジネス目標を達成します。1

たとえば、Pinterestには、ユーザープロファイル、フォロワー、フィード、検索、写真のアップロードなどのマイクロサービスを含めることができます。

サービス検出

ConsuletcdZookeeperなどのシステムは、登録名、住所、およびポートを追跡することにより、サービスがお互いを見つけるのに役立ちます。ヘルスチェックはサービスの整合性の検証に役立ち、多くの場合、HTTP エンドポイントを使用して行われます。Consulとetcdの両方に、構成値やその他の共有データを格納するのに役立つキーバリューストアが組み込まれています。

デメリット:アプリケーション層

  • 疎結合サービスを持つアプリケーション層を追加するには、アーキテクチャ、運用、およびプロセスの観点から (モノリシック システムとは対照的に) 異なるアプローチが必要です。
  • マイクロサービスは、デプロイと運用の面で複雑さを増す可能性があります。

出典と参考文献

データベース


ソース: 最初の 10,<> 万人のユーザーへのスケールアップ

リレーショナルデータベース管理システム(RDBMS)

SQLのようなリレーショナルデータベースは、テーブルに編成されたデータ項目のコレクションです。

ACID は、リレーショナル データベース トランザクションのプロパティのセットです。

  • アトミック性 - 各トランザクションはオールオアナッシングです
  • 一貫性 - すべてのトランザクションは、データベースをある有効な状態から別の有効な状態に移動します
  • 分離 - トランザクションを同時に実行すると、トランザクションが順次実行された場合と同じ結果が得られます。
  • 耐久性 - トランザクションがコミットされると、その状態が維持されます

リレーショナル データベースのスケーリングには、マスター/スレーブ レプリケーション、マスター/マスター レプリケーションフェデレーションシャーディング非正規化SQL チューニングなど、さまざまな手法があります。

マスター/スレーブレプリケーション

マスターは読み取りと書き込みを処理し、読み取りのみを提供する1つ以上のスレーブに書き込みを複製します。スレーブは、ツリーのような方法で追加のスレーブに複製することもできます。マスターがオフラインになった場合、システムは、スレーブがマスターに昇格するか、新しいマスターがプロビジョニングされるまで、読み取り専用モードで動作し続けることができます。


ソース: スケーラビリティ、可用性、安定性、パターン

デメリット:マスタースレーブレプリケーション
  • スレーブをマスターに昇格させるには、追加のロジックが必要です。
  • デメリット:マスタースレーブとマスターマスターの両方に関連するポイントのレプリケーションを参照してください。

マスター/マスター複製

両方のマスターは、読み取りと書き込みを行い、書き込み時に相互に調整します。いずれかのマスターがダウンした場合、システムは読み取りと書き込みの両方で動作を継続できます。


ソース: スケーラビリティ、可用性、安定性、パターン

デメリット:マスター/マスターレプリケーション
  • ロード バランサーが必要になるか、アプリケーション ロジックを変更して書き込み先を決定する必要があります。
  • ほとんどのマスター/マスター システムは、一貫性が緩やかであるか (ACID に違反している)、同期のために書き込み待機時間が長くなります。
  • 競合の解決は、書き込みノードが追加され、待機時間が長くなるにつれて、より重要になります。
  • デメリット:マスタースレーブとマスターマスターの両方に関連するポイントのレプリケーションを参照してください。
デメリット:レプリケーション
  • 新しく書き込まれたデータを他のノードに複製する前にマスターに障害が発生すると、データが失われる可能性があります。
  • 書き込みはリードレプリカに再生されます。書き込みが多い場合、リードレプリカは書き込みの再生で行き詰まり、多くの読み取りを実行できなくなる可能性があります。
  • リードスレーブが多いほど、レプリケートする必要があるため、レプリケーションラグが大きくなります。
  • 一部のシステムでは、マスターへの書き込みで複数のスレッドを生成して並列に書き込むことができますが、リードレプリカは 1 つのスレッドでのシーケンシャル書き込みのみをサポートします。
  • レプリケーションにより、ハードウェアが増え、複雑さが増します。
ソースと参考文献:レプリケーション

フェデレーション


ソース: 最初の 10,<> 万人のユーザーへのスケールアップ

フェデレーション (または機能パーティション分割) は、データベースを機能別に分割します。たとえば、単一のモノリシック データベースの代わりに、フォーラムユーザー製品の 3 つのデータベースを使用して、各データベースへの読み取りおよび書き込みトラフィックを減らし、レプリケーションの遅延を減らすことができます。データベースが小さいほど、メモリに収まるデータが多くなり、キャッシュの局所性が向上するため、キャッシュヒットが増加します。書き込みをシリアル化する中央マスターが 1 つないため、並列で書き込みを行うことができ、スループットが向上します。

デメリット:フェデレーション
  • スキーマに巨大な関数やテーブルが必要な場合は、フェデレーションは効果的ではありません。
  • アプリケーション ロジックを更新して、読み取りと書き込みを行うデータベースを決定する必要があります。
  • 2 つのデータベースからのデータの結合は、サーバー リンクを使用するとより複雑になります。
  • フェデレーションは、より多くのハードウェアと複雑さを追加します。
出典と参考文献: フェデレーション

シャーディング


ソース: スケーラビリティ、可用性、安定性、パターン

シャーディングは、各データベースがデータのサブセットのみを管理できるように、データを異なるデータベースに分散します。ユーザー データベースを例にとると、ユーザー数が増えると、クラスターにシャードが追加されます。

フェデレーションの利点と同様に、シャーディングにより、読み取りと書き込みのトラフィック、レプリケーション、キャッシュ ヒットが増加します。インデックス サイズも小さくなり、一般にクエリが高速になり、パフォーマンスが向上します。1 つのシャードがダウンしても、他のシャードは引き続き動作しますが、データの損失を防ぐために何らかの形式のレプリケーションを追加する必要があります。フェデレーションと同様に、書き込みをシリアル化する単一の中央マスターは存在しないため、スループットを向上させながら並列に書き込むことができます。

ユーザーのテーブルをシャード化する一般的な方法は、ユーザーの姓のイニシャルまたはユーザーの地理的な場所を使用することです。

デメリット:シャーディング
  • シャードを操作するにはアプリケーション ロジックを更新する必要があり、SQL クエリが複雑になる可能性があります。
  • データ分散はシャード内で偏る可能性があります。たとえば、シャード上のパワー ユーザーのセットは、他のシャードと比較してそのシャードへの負荷が増加する可能性があります。
    • 再調整はさらに複雑になります。一貫性のあるハッシュに基づくシャーディング関数は、転送されるデータの量を減らすことができます。
  • 複数のシャードからのデータの結合は、より複雑です。
  • シャーディングは、より多くのハードウェアと複雑さを追加します。
出典と参考文献:シャーディング

非正規化

非正規化は、書き込みパフォーマンスをいくらか犠牲にして、読み取りパフォーマンスの向上を試みます。データの冗長コピーは、コストのかかる結合を回避するために複数のテーブルに書き込まれます。PostgreSQLやOracleなどの一部のRDBMSは、冗長な情報を格納し、冗長なコピーの一貫性を維持する作業を処理するマテリアライズドビューをサポートしています。

フェデレーションシャーディングなどの手法を使用してデータが分散されると、データセンター間での結合の管理はさらに複雑になります。非正規化は、このような複雑な結合の必要性を回避する可能性があります。

ほとんどのシステムでは、読み取りは書き込み数を 100:1 または 1000:1 で大幅に上回る可能性があります。読み取りによってデータベースが複雑になると、非常にコストがかかり、ディスク操作にかなりの時間が費やされる可能性があります。

デメリット:非正規化
  • データが重複しています。
  • 制約により、情報の冗長コピーの同期が維持され、データベース設計の複雑さが増します。
  • 書き込み負荷が高い非正規化データベースは、正規化されたデータベースよりもパフォーマンスが低下する可能性があります。
出典と参考文献:非正規化

SQL チューニング

SQLチューニングは幅広いトピックであり、多くのが参照として書かれています。

ベンチマークプロファイリングを行い、ボトルネックをシミュレートして発見することが重要です。

  • ベンチマーク - ab などのツールを使用して高負荷状況をシミュレートします。
  • プロファイル - スロークエリログなどのツールを有効にして、パフォーマンスの問題を追跡できるようにします。

ベンチマークとプロファイリングでは、次の最適化が示される場合があります。

スキーマを強化する
  • MySQLは、高速アクセスのために連続したブロックでディスクにダンプします。
  • 固定長フィールドの代わりに使用します。
    CHAR
    VARCHAR
    • CHAR
      高速のランダムアクセスを効果的に可能にしますが、 では、次の文字列に進む前に文字列の末尾を見つける必要があります。
      VARCHAR
  • ブログ投稿などの大きなテキストブロックに使用します。 ブール検索も可能です。フィールドを使用すると、テキスト ブロックの検索に使用されるポインターがディスクに格納されます。
    TEXT
    TEXT
    TEXT
  • 2 ^ 32または4億までのより大きな数値に使用します。
    INT
  • 浮動小数点表現エラーを回避するために通貨に使用します。
    DECIMAL
  • 代わりに、オブジェクトを取得する場所の場所を格納し、大きな格納を避けます。
    BLOBS
  • VARCHAR(255)
    は、8ビットの数値でカウントできる最大文字数であり、多くの場合、一部のRDBMSではバイトの使用を最大化します。
  • 検索パフォーマンスを向上させるために、必要に応じて制約を設定します。
    NOT NULL
良いインデックスを使う
  • クエリを実行する列 (、) は、インデックスを使用すると高速になる可能性があります。
    SELECT
    GROUP BY
    ORDER BY
    JOIN
  • インデックスは通常、データのソートを維持し、対数時間での検索、順次アクセス、挿入、および削除を可能にする自己バランスBツリーとして表されます。
  • インデックスを配置すると、データをメモリに保持でき、より多くの領域が必要になります。
  • インデックスも更新する必要があるため、書き込みが遅くなる可能性があります。
  • 大量のデータを読み込む場合は、インデックスを無効にし、データを読み込み、インデックスを再構築する方が速い場合があります。
コストのかかる結合を避ける
パーティションテーブル
  • ホットスポットを別のテーブルに配置してテーブルを分割し、メモリに保持できるようにします。
クエリ キャッシュを調整する
出典と参考文献:SQLチューニング

いいえSQL

NoSQL は、キー値ストア、ドキュメント ストア、ワイド列ストア、またはグラフ データベースで表されるデータ項目のコレクションです。データは非正規化され、結合は通常、アプリケーション コードで行われます。ほとんどの NoSQL ストアには真の ACID トランザクションがなく、最終的な一貫性が優先されます。

BASEは、NoSQLデータベースのプロパティを記述するためによく使用されます。CAP定理と比較して、BASEは一貫性よりも可用性を選択します。

  • 基本的に利用可能 - システムは可用性を保証します。
  • ソフト状態 - システムの状態は、入力がなくても時間の経過とともに変化する可能性があります。
  • 最終的な整合性 - システムは、その期間中に入力を受信しない場合、一定期間にわたって一貫性が保たれます。

SQLまたはNoSQLのどちらかを選択することに加えて、ユースケースに最適なNoSQLデータベースのタイプを理解することは役立ちます。次のセクションでは、キー値ストア、ドキュメント ストア、ワイド列ストアグラフ データベースを確認します。

キーバリューストア

抽象化:ハッシュテーブル

キーバリューストアは通常、O(1)の読み取りと書き込みを可能にし、多くの場合、メモリまたはSSDによってバックアップされます。データ ストアは、キーを辞書順に保持できるため、キー範囲を効率的に取得できます。キー値ストアでは、値を持つメタデータを格納できます。

キー値ストアは高いパフォーマンスを提供し、単純なデータ モデルや、メモリ内キャッシュ レイヤーなどの急速に変化するデータによく使用されます。提供される操作のセットは限られているため、追加の操作が必要な場合は、複雑さがアプリケーション層に移ります。

キー値ストアは、ドキュメントストアや、場合によってはグラフデータベースなどのより複雑なシステムの基礎となります。

ソースと参考文献:キーバリューストア

ドキュメント ストア

抽象化:値として保存されたドキュメントを持つキーバリューストア

ドキュメントストアはドキュメント(XML、JSON、バイナリなど)を中心にしており、ドキュメントには特定のオブジェクトのすべての情報が格納されます。ドキュメント ストアは、ドキュメント自体の内部構造に基づいてクエリを実行するための API またはクエリ言語を提供します。多くのキーバリューストアには、値のメタデータを操作する機能が含まれているため、これら 2 つのストレージタイプの境界線があいまいになっています。

基になる実装に基づいて、ドキュメントはコレクション、タグ、メタデータ、またはディレクトリ別に編成されます。ドキュメントは整理またはグループ化できますが、ドキュメントには互いに完全に異なるフィールドが含まれる場合があります。

MongoDBCouchDB などの一部のドキュメント ストアでは、複雑なクエリを実行するための SQL に似た言語も用意されています。DynamoDB は、キー値とドキュメントの両方をサポートしています。

ドキュメント ストアは高い柔軟性を提供し、頻繁に変更されるデータの操作によく使用されます。

出典と参考文献:ドキュメントストア

ワイドコラムストア


Source: SQL & NoSQL, a brief history

Abstraction: nested map

ColumnFamily<RowKey, Columns<ColKey, Value, Timestamp>>

A wide column store's basic unit of data is a column (name/value pair). A column can be grouped in column families (analogous to a SQL table). Super column families further group column families. You can access each column independently with a row key, and columns with the same row key form a row. Each value contains a timestamp for versioning and for conflict resolution.

Google introduced Bigtable as the first wide column store, which influenced the open-source HBase often-used in the Hadoop ecosystem, and Cassandra from Facebook. Stores such as BigTable, HBase, and Cassandra maintain keys in lexicographic order, allowing efficient retrieval of selective key ranges.

Wide column stores offer high availability and high scalability. They are often used for very large data sets.

Source(s) and further reading: wide column store

Graph database


Source: Graph database

Abstraction: graph

In a graph database, each node is a record and each arc is a relationship between two nodes. Graph databases are optimized to represent complex relationships with many foreign keys or many-to-many relationships.

Graphs databases offer high performance for data models with complex relationships, such as a social network. They are relatively new and are not yet widely-used; it might be more difficult to find development tools and resources. Many graphs can only be accessed with REST APIs.

Source(s) and further reading: graph

Source(s) and further reading: NoSQL

SQL or NoSQL


Source: Transitioning from RDBMS to NoSQL

Reasons for SQL:

  • Structured data
  • Strict schema
  • Relational data
  • Need for complex joins
  • Transactions
  • Clear patterns for scaling
  • More established: developers, community, code, tools, etc
  • Lookups by index are very fast

Reasons for NoSQL:

  • Semi-structured data
  • Dynamic or flexible schema
  • Non-relational data
  • No need for complex joins
  • Store many TB (or PB) of data
  • Very data intensive workload
  • Very high throughput for IOPS

Sample data well-suited for NoSQL:

  • Rapid ingest of clickstream and log data
  • Leaderboard or scoring data
  • Temporary data, such as a shopping cart
  • Frequently accessed ('hot') tables
  • Metadata/lookup tables
Source(s) and further reading: SQL or NoSQL

Cache


Source: Scalable system design patterns

Caching improves page load times and can reduce the load on your servers and databases. In this model, the dispatcher will first lookup if the request has been made before and try to find the previous result to return, in order to save the actual execution.

Databases often benefit from a uniform distribution of reads and writes across its partitions. Popular items can skew the distribution, causing bottlenecks. Putting a cache in front of a database can help absorb uneven loads and spikes in traffic.

Client caching

Caches can be located on the client side (OS or browser), server side, or in a distinct cache layer.

CDN caching

CDNs are considered a type of cache.

Web server caching

Reverse proxies and caches such as Varnish can serve static and dynamic content directly. Web servers can also cache requests, returning responses without having to contact application servers.

Database caching

Your database usually includes some level of caching in a default configuration, optimized for a generic use case. Tweaking these settings for specific usage patterns can further boost performance.

Application caching

In-memory caches such as Memcached and Redis are key-value stores between your application and your data storage. Since the data is held in RAM, it is much faster than typical databases where data is stored on disk. RAM is more limited than disk, so cache invalidation algorithms such as least recently used (LRU) can help invalidate 'cold' entries and keep 'hot' data in RAM.

Redis has the following additional features:

  • Persistence option
  • Built-in data structures such as sorted sets and lists

There are multiple levels you can cache that fall into two general categories: database queries and objects:

  • Row level
  • Query-level
  • Fully-formed serializable objects
  • Fully-rendered HTML

Generally, you should try to avoid file-based caching, as it makes cloning and auto-scaling more difficult.

Caching at the database query level

Whenever you query the database, hash the query as a key and store the result to the cache. This approach suffers from expiration issues:

  • Hard to delete a cached result with complex queries
  • If one piece of data changes such as a table cell, you need to delete all cached queries that might include the changed cell

Caching at the object level

See your data as an object, similar to what you do with your application code. Have your application assemble the dataset from the database into a class instance or a data structure(s):

  • Remove the object from cache if its underlying data has changed
  • Allows for asynchronous processing: workers assemble objects by consuming the latest cached object

Suggestions of what to cache:

  • User sessions
  • Fully rendered web pages
  • Activity streams
  • User graph data

When to update the cache

Since you can only store a limited amount of data in cache, you'll need to determine which cache update strategy works best for your use case.

Cache-aside


Source: From cache to in-memory data grid

The application is responsible for reading and writing from storage. The cache does not interact with storage directly. The application does the following:

  • Look for entry in cache, resulting in a cache miss
  • Load entry from the database
  • Add entry to cache
  • Return entry
def get_user(self, user_id):
    user = cache.get("user.{0}", user_id)
    if user is None:
        user = db.query("SELECT * FROM users WHERE user_id = {0}", user_id)
        if user is not None:
            key = "user.{0}".format(user_id)
            cache.set(key, json.dumps(user))
    return user

Memcached is generally used in this manner.

Subsequent reads of data added to cache are fast. Cache-aside is also referred to as lazy loading. Only requested data is cached, which avoids filling up the cache with data that isn't requested.

Disadvantage(s): cache-aside
  • Each cache miss results in three trips, which can cause a noticeable delay.
  • Data can become stale if it is updated in the database. This issue is mitigated by setting a time-to-live (TTL) which forces an update of the cache entry, or by using write-through.
  • When a node fails, it is replaced by a new, empty node, increasing latency.

Write-through


Source: Scalability, availability, stability, patterns

The application uses the cache as the main data store, reading and writing data to it, while the cache is responsible for reading and writing to the database:

  • Application adds/updates entry in cache
  • Cache synchronously writes entry to data store
  • Return

Application code:

set_user(12345, {"foo":"bar"})

Cache code:

def set_user(user_id, values):
    user = db.query("UPDATE Users WHERE id = {0}", user_id, values)
    cache.set(user_id, user)

Write-through is a slow overall operation due to the write operation, but subsequent reads of just written data are fast. Users are generally more tolerant of latency when updating data than reading data. Data in the cache is not stale.

Disadvantage(s): write through
  • When a new node is created due to failure or scaling, the new node will not cache entries until the entry is updated in the database. Cache-aside in conjunction with write through can mitigate this issue.
  • Most data written might never be read, which can be minimized with a TTL.

Write-behind (write-back)


Source: Scalability, availability, stability, patterns

In write-behind, the application does the following:

  • Add/update entry in cache
  • Asynchronously write entry to the data store, improving write performance
Disadvantage(s): write-behind
  • There could be data loss if the cache goes down prior to its contents hitting the data store.
  • It is more complex to implement write-behind than it is to implement cache-aside or write-through.

Refresh-ahead


Source: From cache to in-memory data grid

You can configure the cache to automatically refresh any recently accessed cache entry prior to its expiration.

Refresh-ahead can result in reduced latency vs read-through if the cache can accurately predict which items are likely to be needed in the future.

Disadvantage(s): refresh-ahead
  • Not accurately predicting which items are likely to be needed in the future can result in reduced performance than without refresh-ahead.

Disadvantage(s): cache

  • Need to maintain consistency between caches and the source of truth such as the database through cache invalidation.
  • Cache invalidation is a difficult problem, there is additional complexity associated with when to update the cache.
  • Need to make application changes such as adding Redis or memcached.

Source(s) and further reading

Asynchronism


Source: Intro to architecting systems for scale

Asynchronous workflows help reduce request times for expensive operations that would otherwise be performed in-line. They can also help by doing time-consuming work in advance, such as periodic aggregation of data.

Message queues

Message queues receive, hold, and deliver messages. If an operation is too slow to perform inline, you can use a message queue with the following workflow:

  • An application publishes a job to the queue, then notifies the user of job status
  • A worker picks up the job from the queue, processes it, then signals the job is complete

The user is not blocked and the job is processed in the background. During this time, the client might optionally do a small amount of processing to make it seem like the task has completed. For example, if posting a tweet, the tweet could be instantly posted to your timeline, but it could take some time before your tweet is actually delivered to all of your followers.

Redis is useful as a simple message broker but messages can be lost.

RabbitMQ is popular but requires you to adapt to the 'AMQP' protocol and manage your own nodes.

Amazon SQS is hosted but can have high latency and has the possibility of messages being delivered twice.

Task queues

Tasks queues receive tasks and their related data, runs them, then delivers their results. They can support scheduling and can be used to run computationally-intensive jobs in the background.

Celery has support for scheduling and primarily has python support.

Back pressure

If queues start to grow significantly, the queue size can become larger than memory, resulting in cache misses, disk reads, and even slower performance. Back pressure can help by limiting the queue size, thereby maintaining a high throughput rate and good response times for jobs already in the queue. Once the queue fills up, clients get a server busy or HTTP 503 status code to try again later. Clients can retry the request at a later time, perhaps with exponential backoff.

Disadvantage(s): asynchronism

  • Use cases such as inexpensive calculations and realtime workflows might be better suited for synchronous operations, as introducing queues can add delays and complexity.

Source(s) and further reading

Communication


Source: OSI 7 layer model

Hypertext transfer protocol (HTTP)

HTTP is a method for encoding and transporting data between a client and a server. It is a request/response protocol: clients issue requests and servers issue responses with relevant content and completion status info about the request. HTTP is self-contained, allowing requests and responses to flow through many intermediate routers and servers that perform load balancing, caching, encryption, and compression.

A basic HTTP request consists of a verb (method) and a resource (endpoint). Below are common HTTP verbs:

Verb Description Idempotent* Safe Cacheable
GET Reads a resource Yes Yes Yes
POST Creates a resource or trigger a process that handles data No No Yes if response contains freshness info
PUT Creates or replace a resource Yes No No
PATCH Partially updates a resource No No Yes if response contains freshness info
DELETE Deletes a resource Yes No No

*Can be called many times without different outcomes.

HTTP is an application layer protocol relying on lower-level protocols such as TCP and UDP.

Source(s) and further reading: HTTP

Transmission control protocol (TCP)


Source: How to make a multiplayer game

TCP is a connection-oriented protocol over an IP network. Connection is established and terminated using a handshake. All packets sent are guaranteed to reach the destination in the original order and without corruption through:

If the sender does not receive a correct response, it will resend the packets. If there are multiple timeouts, the connection is dropped. TCP also implements flow control and congestion control. These guarantees cause delays and generally result in less efficient transmission than UDP.

To ensure high throughput, web servers can keep a large number of TCP connections open, resulting in high memory usage. It can be expensive to have a large number of open connections between web server threads and say, a memcached server. Connection pooling can help in addition to switching to UDP where applicable.

TCP is useful for applications that require high reliability but are less time critical. Some examples include web servers, database info, SMTP, FTP, and SSH.

Use TCP over UDP when:

  • You need all of the data to arrive intact
  • You want to automatically make a best estimate use of the network throughput

User datagram protocol (UDP)


Source: How to make a multiplayer game

UDP is connectionless. Datagrams (analogous to packets) are guaranteed only at the datagram level. Datagrams might reach their destination out of order or not at all. UDP does not support congestion control. Without the guarantees that TCP support, UDP is generally more efficient.

UDP can broadcast, sending datagrams to all devices on the subnet. This is useful with DHCP because the client has not yet received an IP address, thus preventing a way for TCP to stream without the IP address.

UDP is less reliable but works well in real time use cases such as VoIP, video chat, streaming, and realtime multiplayer games.

Use UDP over TCP when:

  • You need the lowest latency
  • Late data is worse than loss of data
  • You want to implement your own error correction

Source(s) and further reading: TCP and UDP

Remote procedure call (RPC)


Source: Crack the system design interview

In an RPC, a client causes a procedure to execute on a different address space, usually a remote server. The procedure is coded as if it were a local procedure call, abstracting away the details of how to communicate with the server from the client program. Remote calls are usually slower and less reliable than local calls so it is helpful to distinguish RPC calls from local calls. Popular RPC frameworks include Protobuf, Thrift, and Avro.

RPC is a request-response protocol:

  • Client program - Calls the client stub procedure. The parameters are pushed onto the stack like a local procedure call.
  • Client stub procedure - Marshals (packs) procedure id and arguments into a request message.
  • Client communication module - OS sends the message from the client to the server.
  • Server communication module - OS passes the incoming packets to the server stub procedure.
  • Server stub procedure - Unmarshalls the results, calls the server procedure matching the procedure id and passes the given arguments.
  • The server response repeats the steps above in reverse order.

Sample RPC calls:

GET /someoperation?data=anId

POST /anotheroperation
{
  "data":"anId";
  "anotherdata": "another value"
}

RPC is focused on exposing behaviors. RPCs are often used for performance reasons with internal communications, as you can hand-craft native calls to better fit your use cases.

Choose a native library (aka SDK) when:

  • You know your target platform.
  • You want to control how your "logic" is accessed.
  • You want to control how error control happens off your library.
  • Performance and end user experience is your primary concern.

HTTP APIs following REST tend to be used more often for public APIs.

Disadvantage(s): RPC

  • RPC clients become tightly coupled to the service implementation.
  • A new API must be defined for every new operation or use case.
  • It can be difficult to debug RPC.
  • You might not be able to leverage existing technologies out of the box. For example, it might require additional effort to ensure RPC calls are properly cached on caching servers such as Squid.

Representational state transfer (REST)

REST is an architectural style enforcing a client/server model where the client acts on a set of resources managed by the server. The server provides a representation of resources and actions that can either manipulate or get a new representation of resources. All communication must be stateless and cacheable.

There are four qualities of a RESTful interface:

  • Identify resources (URI in HTTP) - use the same URI regardless of any operation.
  • Change with representations (Verbs in HTTP) - use verbs, headers, and body.
  • Self-descriptive error message (status response in HTTP) - Use status codes, don't reinvent the wheel.
  • HATEOAS (HTML interface for HTTP) - your web service should be fully accessible in a browser.

Sample REST calls:

GET /someresources/anId

PUT /someresources/anId
{"anotherdata": "another value"}

REST is focused on exposing data. It minimizes the coupling between client/server and is often used for public HTTP APIs. REST uses a more generic and uniform method of exposing resources through URIs, representation through headers, and actions through verbs such as GET, POST, PUT, DELETE, and PATCH. Being stateless, REST is great for horizontal scaling and partitioning.

Disadvantage(s): REST

  • With REST being focused on exposing data, it might not be a good fit if resources are not naturally organized or accessed in a simple hierarchy. For example, returning all updated records from the past hour matching a particular set of events is not easily expressed as a path. With REST, it is likely to be implemented with a combination of URI path, query parameters, and possibly the request body.
  • REST typically relies on a few verbs (GET, POST, PUT, DELETE, and PATCH) which sometimes doesn't fit your use case. For example, moving expired documents to the archive folder might not cleanly fit within these verbs.
  • Fetching complicated resources with nested hierarchies requires multiple round trips between the client and server to render single views, e.g. fetching content of a blog entry and the comments on that entry. For mobile applications operating in variable network conditions, these multiple roundtrips are highly undesirable.
  • Over time, more fields might be added to an API response and older clients will receive all new data fields, even those that they do not need, as a result, it bloats the payload size and leads to larger latencies.

RPC and REST calls comparison

Operation RPC REST
Signup POST /signup POST /persons
Resign POST /resign
{
"personid": "1234"
}
DELETE /persons/1234
Read a person GET /readPerson?personid=1234 GET /persons/1234
Read a person’s items list GET /readUsersItemsList?personid=1234 GET /persons/1234/items
Add an item to a person’s items POST /addItemToUsersItemsList
{
"personid": "1234";
"itemid": "456"
}
POST /persons/1234/items
{
"itemid": "456"
}
Update an item POST /modifyItem
{
"itemid": "456";
"key": "value"
}
PUT /items/456
{
"key": "value"
}
Delete an item POST /removeItem
{
"itemid": "456"
}
DELETE /items/456

Source: Do you really know why you prefer REST over RPC

Source(s) and further reading: REST and RPC

Security

This section could use some updates. Consider contributing!

Security is a broad topic. Unless you have considerable experience, a security background, or are applying for a position that requires knowledge of security, you probably won't need to know more than the basics:

  • Encrypt in transit and at rest.
  • Sanitize all user inputs or any input parameters exposed to user to prevent XSS and SQL injection.
  • Use parameterized queries to prevent SQL injection.
  • Use the principle of least privilege.

Source(s) and further reading

Appendix

You'll sometimes be asked to do 'back-of-the-envelope' estimates. For example, you might need to determine how long it will take to generate 100 image thumbnails from disk or how much memory a data structure will take. The Powers of two table and Latency numbers every programmer should know are handy references.

Powers of two table

Power           Exact Value         Approx Value        Bytes
---------------------------------------------------------------
7                             128
8                             256
10                           1024   1 thousand           1 KB
16                         65,536                       64 KB
20                      1,048,576   1 million            1 MB
30                  1,073,741,824   1 billion            1 GB
32                  4,294,967,296                        4 GB
40              1,099,511,627,776   1 trillion           1 TB

Source(s) and further reading

Latency numbers every programmer should know

Latency Comparison Numbers
--------------------------
L1 cache reference                           0.5 ns
Branch mispredict                            5   ns
L2 cache reference                           7   ns                      14x L1 cache
Mutex lock/unlock                           25   ns
Main memory reference                      100   ns                      20x L2 cache, 200x L1 cache
Compress 1K bytes with Zippy            10,000   ns       10 us
Send 1 KB bytes over 1 Gbps network     10,000   ns       10 us
Read 4 KB randomly from SSD*           150,000   ns      150 us          ~1GB/sec SSD
Read 1 MB sequentially from memory     250,000   ns      250 us
Round trip within same datacenter      500,000   ns      500 us
Read 1 MB sequentially from SSD*     1,000,000   ns    1,000 us    1 ms  ~1GB/sec SSD, 4X memory
HDD seek                            10,000,000   ns   10,000 us   10 ms  20x datacenter roundtrip
Read 1 MB sequentially from 1 Gbps  10,000,000   ns   10,000 us   10 ms  40x memory, 10X SSD
Read 1 MB sequentially from HDD     30,000,000   ns   30,000 us   30 ms 120x memory, 30X SSD
Send packet CA->Netherlands->CA    150,000,000   ns  150,000 us  150 ms

Notes
-----
1 ns = 10^-9 seconds
1 us = 10^-6 seconds = 1,000 ns
1 ms = 10^-3 seconds = 1,000 us = 1,000,000 ns

Handy metrics based on numbers above:

  • Read sequentially from HDD at 30 MB/s
  • Read sequentially from 1 Gbps Ethernet at 100 MB/s
  • Read sequentially from SSD at 1 GB/s
  • Read sequentially from main memory at 4 GB/s
  • 6-7 world-wide round trips per second
  • 2,000 round trips per second within a data center

Latency numbers visualized

Source(s) and further reading

Additional system design interview questions

Common system design interview questions, with links to resources on how to solve each.

Question Reference(s)
Design a file sync service like Dropbox youtube.com
Design a search engine like Google queue.acm.org
stackexchange.com
ardendertat.com
stanford.edu
Design a scalable web crawler like Google quora.com
Design Google docs code.google.com
neil.fraser.name
Design a key-value store like Redis slideshare.net
Design a cache system like Memcached slideshare.net
Design a recommendation system like Amazon's hulu.com
ijcai13.org
Design a tinyurl system like Bitly n00tc0d3r.blogspot.com
Design a chat app like WhatsApp highscalability.com
Design a picture sharing system like Instagram highscalability.com
highscalability.com
Design the Facebook news feed function quora.com
quora.com
slideshare.net
Design the Facebook timeline function facebook.com
highscalability.com
Design the Facebook chat function erlang-factory.com
facebook.com
Design a graph search function like Facebook's facebook.com
facebook.com
facebook.com
Design a content delivery network like CloudFlare figshare.com
Design a trending topic system like Twitter's michael-noll.com
snikolov .wordpress.com
Design a random ID generation system blog.twitter.com
github.com
Return the top k requests during a time interval cs.ucsb.edu
wpi.edu
Design a system that serves data from multiple data centers highscalability.com
Design an online multiplayer card game indieflashblog.com
buildnewgames.com
Design a garbage collection system stuffwithstuff.com
washington.edu
Design an API rate limiter https://stripe.com/blog/
Design a Stock Exchange (like NASDAQ or Binance) Jane Street
Golang Implementation
Go Implementation
Add a system design question Contribute

Real world architectures

Articles on how real world systems are designed.


Source: Twitter timelines at scale

Don't focus on nitty gritty details for the following articles, instead:

  • Identify shared principles, common technologies, and patterns within these articles
  • Study what problems are solved by each component, where it works, where it doesn't
  • Review the lessons learned
Type System Reference(s)
Data processing MapReduce - Distributed data processing from Google research.google.com
Data processing Spark - Distributed data processing from Databricks slideshare.net
Data processing Storm - Distributed data processing from Twitter slideshare.net
Data store Bigtable - Distributed column-oriented database from Google harvard.edu
Data store HBase - Open source implementation of Bigtable slideshare.net
Data store Cassandra - Distributed column-oriented database from Facebook slideshare.net
Data store DynamoDB - Document-oriented database from Amazon harvard.edu
Data store MongoDB - Document-oriented database slideshare.net
Data store Spanner - Globally-distributed database from Google research.google.com
Data store Memcached - Distributed memory caching system slideshare.net
Data store Redis - Distributed memory caching system with persistence and value types slideshare.net
File system Google File System (GFS) - Distributed file system research.google.com
File system Hadoop File System (HDFS) - Open source implementation of GFS apache.org
Misc Chubby - Lock service for loosely-coupled distributed systems from Google research.google.com
Misc Dapper - Distributed systems tracing infrastructure research.google.com
Misc Kafka - Pub/sub message queue from LinkedIn slideshare.net
Misc Zookeeper - Centralized infrastructure and services enabling synchronization slideshare.net
Add an architecture Contribute

Company architectures

Company Reference(s)
Amazon Amazon architecture
Cinchcast Producing 1,500 hours of audio every day
DataSift Realtime datamining At 120,000 tweets per second
Dropbox How we've scaled Dropbox
ESPN Operating At 100,000 duh nuh nuhs per second
Google Google architecture
Instagram 14 million users, terabytes of photos
What powers Instagram
Justin.tv Justin.Tv's live video broadcasting architecture
Facebook Scaling memcached at Facebook
TAO: Facebook’s distributed data store for the social graph
Facebook’s photo storage
How Facebook Live Streams To 800,000 Simultaneous Viewers
Flickr Flickr architecture
Mailbox From 0 to one million users in 6 weeks
Netflix A 360 Degree View Of The Entire Netflix Stack
Netflix: What Happens When You Press Play?
Pinterest From 0 To 10s of billions of page views a month
18 million visitors, 10x growth, 12 employees
Playfish 50 million monthly users and growing
PlentyOfFish PlentyOfFish architecture
Salesforce How they handle 1.3 billion transactions a day
Stack Overflow Stack Overflow architecture
TripAdvisor 40M visitors, 200M dynamic page views, 30TB data
Tumblr 15 billion page views a month
Twitter Making Twitter 10000 percent faster
Storing 250 million tweets a day using MySQL
150M active users, 300K QPS, a 22 MB/S firehose
Timelines at scale
Big and small data at Twitter
Operations at Twitter: scaling beyond 100 million users
How Twitter Handles 3,000 Images Per Second
Uber How Uber scales their real-time market platform
Lessons Learned From Scaling Uber To 2000 Engineers, 1000 Services, And 8000 Git Repositories
WhatsApp The WhatsApp architecture Facebook bought for $19 billion
YouTube YouTube scalability
YouTube architecture

Company engineering blogs

Architectures for companies you are interviewing with.

Questions you encounter might be from the same domain.

Source(s) and further reading

Looking to add a blog? To avoid duplicating work, consider adding your company blog to the following repo:

Under development

Interested in adding a section or helping complete one in-progress? Contribute!

  • Distributed computing with MapReduce
  • Consistent hashing
  • Scatter gather
  • Contribute

クレジット

クレジットとソースは、このリポジトリ全体で提供されます。

特別な感謝:

連絡先情報

問題、質問、コメントについて話し合うために私に連絡してください。

私の連絡先情報は私のGitHubページにあります。

ライセンス

私はこのリポジトリのコードとリソースをオープンソースライセンスの下であなたに提供しています。これは私の個人的なリポジトリであるため、私のコードとリソースに対して受け取るライセンスは、私の雇用主(Facebook)ではなく、私からのものです。

Copyright 2017 Donne Martin

Creative Commons Attribution 4.0 International License (CC BY 4.0)

http://creativecommons.org/licenses/by/4.0/