文字起こし · CC BY 3.0

MIT 6.824 講義 1:分散システム & MapReduce

このページのタイトル、字幕、要約、読書メモは保存済みの AI 翻訳です。誤りが含まれる場合があります。タイムスタンプは原文と同じです。原文の字幕を開き、元の動画と照合できます。

MIT 6.824 講義 1:分散システムが構築される理由、ラボの仕組み、フォールトトレランスと一貫性、そしてGoogleのMapReduceの解説。

MIT 6.824:分散システム · 公開 · 1 時間 20 分 · 英語 · ライセンス:CC BY 3.0 · ソース:YouTubeで視聴

文字起こしの出典:Vidleafによる自動音声認識(誤りを含む可能性があります)。AIによる句読点はVidleafが追加しました。元の文言とタイムスタンプのアンカーは保持されています。元の文字起こしは以下でご覧いただけます。

AI生成の要約

MITの分散システム入門講義では、アプリケーションが協調するコンピュータを使用する理由と、そうすることが難しい設計上の問題を生み出す理由を説明します。性能、フォールトトレランス、物理的分散がこの分野の動機となる一方、並行性と部分的な障害が実装を複雑にします。講義ではコースとラボの概要を述べた後、ストレージ、レプリケーション、スケーラビリティ、一貫性に関する考えを展開します。GoogleのMapReduceがケーススタディとして用いられ、単純なmap関数とreduce関数を、作業を分散しデータを移動するために必要なインフラストラクチャと結び付けます。タイムスタンプ付きのセクションにより、一般的な設計上のトレードオフから具体的な単語カウントとネットワークの例への移行を追うことができます。

要点

  • [0:17] 分散システムは、ネットワーク化されたコンピュータを協調させて一貫したタスクを実行します。
  • [42:39] 一貫性の選択は、読み手が観察できる内容とレプリカ間の協調のコストに影響します。
  • [46:53] MapReduceは、講義の設計上の考えを大規模分散計算のためのフレームワークと結び付けます。

記録から生成されました。リンクされた箇所を元のビデオと照合してください。概要と要点はVidleafが2026-10-21に確認しました。

全体概要

この講義は分散システムのコースを開講するにあたり、分散システムを、ネットワークを介して通信し協調するコンピュータが一貫したタスクを完了するものと定義し、並列性による性能、耐故障性、物理的分散、セキュリティを通じてこの分野を動機づける。単一のコンピュータで解ける問題はそのように解くべきであり、分散システムは並行実行と部分的な故障のために難しいと論じる。講師はコースの運営について説明する。ラボ、スケジュール、Piazzaを含むコースウェブサイト、ロバート・モリスによる講義と四人のTA、ほぼ毎回の講義に対応する論文、二回の試験、MapReduceからRaftベースのレプリケーション、複製された耐故障キーバリューサーバー、シャーディングへと進む四つのプログラミングラボ、そしてラボの一つを置き換えることができる任意の最終プロジェクトである。ラボは与えられたテストの合格数で採点され、隠されたテストはなく、学生は早く始め、TAのオフィスアワーとPiazzaを利用するよう助言される。コースはアプリケーションのためのインフラストラクチャー、つまりストレージ、通信、計算を扱い、ストレージを主な焦点とし、これらのシステムの分散性を隠す抽象化という繰り返し現れる目標を持つ。講義はその後、遠隔手続き呼び出し、スレッド、ロックなどの実装のアイデアと、スケーラビリティ(およそ10、20、100台のウェブサーバーの後でデータベースがボトルネックになる)、大規模な耐故障性、不揮発性ストレージ、レプリケーション、一貫性などの設計上の課題を扱い、強一貫性は高コストであり、レプリカは独立した無相関の故障確率を持つべきであると指摘する。レプリカは遠く離れて配置されるが、光の速さでも大陸間通信にはミリ秒または数十ミリ秒かかるため、人々はしばしば最も近いコピーだけを更新または参照する弱いシステムを構築すると説明する。MapReduceはケーススタディとして提示される。Googleによってテラバイトのデータに対する巨大な計算のために2004の論文で構築され、非専門家がmap関数とreduce関数だけを書けるようにし、マスターとワーカーのアーキテクチャを持ち、入出力はGFS上のファイルであり、単語カウントの例がある。GFSサーバーとMapReduceワーカーが同じマシン上で動作していたため、mapはデフォルトでローカルディスクから入力を読み取ることができたが、シャッフルはすべてのデータをネットワーク経由で移動させ、それが高コストな部分であった。講演者は、現代のデータセンターのネットワークははるかに高いスループットを持ち、Googleは数年前にMapReduceの使用をやめたと伝えられており、後のMapReduceはデータが保存されている場所でmapを実行しようとしなくなったと述べる。このセグメントは、やや簡略化されたMapReduceを含むラボを告知して終わる。

タイムスタンプ付きの章の要約

分散システム:定義と動機

  • [0:17] 分散システムとは、何らかの一貫したタスクを成し遂げるためにネットワークを介して通信する協調的なコンピュータの集合です。
  • [0:32] コースのケーススタディには、大規模ウェブサイトのためのストレージ、MapReduceのようなビッグデータ計算、ピアツーピアのファイル共有が含まれます。
  • [1:10] 問題が単一のコンピュータで解ける可能性があるなら、その方法で行うべきです。分散システムはより単純ではないからです。
  • [1:40] 分散システムを構築する一つの理由は、多くのCPU、メモリ、ディスクアームにわたる並列性を通じて高い性能を得ることである。
  • [1:54] もう一つの理由は耐故障性であり、例えば二台のコンピュータに全く同じことをさせ、一方が故障したら他方が引き継げるようにすることである。
  • [2:11] 問題によっては本質的に空間的に分散しています。例えば、ニューヨーク市とロンドンのコンピュータ間の銀行間送金などです。
  • [2:38] 最後の理由はセキュリティです。信頼できない、またはバグのあるコードを隔離し、狭く定義されたネットワークプロトコルを介してのみ通信させるために、計算をコンピュータ間に分割します。
  • [3:20] コースの大部分は性能とフォールトトレランスに焦点を当てていますが、セキュリティと物理的分散はしばしばケーススタディの制約を通じて関わってきます。
  • [3:32] 分散システムが難しい理由の一部は、複数のコンピュータにまたがる並行実行が複雑な相互作用や、タイミングに依存した奇妙な問題を引き起こすことです。
  • [4:12] また、複数の部品とネットワークがあることで部分的な障害が起こり得ることも難しさの理由です。一部の部品が動作を停止しても他の部品は動き続けたり、ネットワークが壊れていたり信頼できなかったりする場合があります。
  • [4:49] 千台のコンピュータで千倍の高速化を達成するのは難しく、期待する性能を得るには慎重な設計がしばしば必要です。

分散システムのコースを履修する理由

  • [5:31] このコースは、問題と解決策が技術的に興味深く難しいため、履修する価値があります。
  • [5:41] 一部の問題には他の問題から知られているかなり良い解決策がありますが、それらの解決策はここではあまり優れていません。
  • [5:46] 分散システムは多くの実世界のシステムで使われており、しばしば膨大な数のコンピュータを持つ大規模なウェブサイトで利用されています。
  • [6:02] このコースが始まった当初、分散システムはある種の学術的な好奇心の対象であり、時々小規模に使われる程度でした。
  • [6:13] 特に巨大なウェブサイトの台頭に後押しされ、分散システムは過去20年の間にコンピューティングインフラの非常に重要な一部となってきました。
  • [6:36] これらには多くの注目が集まってきましたが、大学院生や研究に興味のある人々にとって未解決の問題がかなり残っています。
  • [6:49] このコースは何かを作るのが好きな人に適しており、性能と耐障害性に焦点を当てたかなり現実的な分散システムを構築するラボのシリーズを通じて学びます。

コースの構成と運営

  • [7:17] コースのウェブサイトはGoogleで見つけることができ、ラボの課題、コースのスケジュール、質問と回答のためのPiazzaが掲載されています。
  • [7:33] 講義は Robert Morris が担当し、四名の TA がオフィスアワーを設けており、ラボの解決の専門家です。
  • [7:59] コースの構成要素には講義、ほぼ毎回の講義に対応する論文、二回の試験、プログラミングラボ、そしてラボの一つを置き換えられる任意の最終プロジェクトが含まれます。
  • [8:35] 講義では分散システムの大きなアイデアを扱い、ラボのプログラミングに関する講義もいくつかあり、多くは実際の問題に対する実際の解決策を述べた論文のケーススタディです。
  • [9:05] 講義はビデオ録画され、復習のためや出席できなかった人のためにオンラインで公開することが講師によって望まれています。
  • [9:18] 週に一篇の論文を読む必要があり、そのほとんどは研究論文で、MapReduce のようないくつかの古典的なものと、より最近のものもあります。
  • [9:43] 講義では論文から基本的な問題とアイデアを引き出し、時には実装の詳細を扱い、耐障害性と性能の評価に時間を費やします。
  • [10:15] 講義は論文の内容をすべて説明することとそれについて考察することの両方はできないため、学生は授業前に論文を読むべきです。このクラスは迅速で効率的な論文の読み方を教えることを目指しています。
  • [10:50] すべての論文について、学生は前日の夜中までにウェブサイトに回答と質問を提出する必要があり、これは講師が講義を準備するための材料にもなります。
  • [11:21] 春休み前の最後の授業の頃に授業内の中間試験があり、期末試験週に最終試験があり、主に論文とラボに焦点を当てています。
  • [11:48] 試験対策として過去20年分の試験と解答が利用可能で、問題は必然的に過去問に似たものになります。
  • [12:12] プログラミングラボは四つあり、最初の簡単な MapReduce ラボは来週の金曜日が締め切りです。

ラボのシリーズ、プロジェクト、成績評価

  • [12:38] ラボ2ではRaftの技法を用いて、理論上はあらゆるシステムを複製することで耐障害性を持たせます。Raftが複製を管理し、複製されたサーバが故障した際に自動的に切り替えます。
  • [13:07] ラボ3ではRaftの実装を用いて、複製された耐障害性のあるキーバリューサーバを構築します。
  • [13:22] ラボ4では、複製されたキーバリューサーバを複数の独立したグループに複製し、データをそれらに分割して並列の高速化を図り、サーバが参加したり離脱したりする際にデータのチャンクをサーバ間で移動させます。
  • [14:02] シャーディングとは、並列の高速化を得るためにデータを複数のサーバ間で分割またはパーティション化することを意味します。
  • [14:13] ラボ4の代わりに、学生は分散システムのアイデアに基づく独自のプロジェクトを行い、何かを作ってそれがうまくいったかどうかを測定することができます。
  • [14:36] プロジェクトは二人または三人のチームで行う必要があり、プロジェクトのアイデアは承認と助言のために教員に送る必要があります。
  • [15:03] プロジェクトの学生は設計作業を行い、実際のシステムを構築し、最終授業日にそれを実演し、短い書面による報告書を提出する必要があります。
  • [15:40] ラボの成績は合格したテストの数に基づきます。すべてのテストが公開されているため隠されたテストはなく、ローカルですべてのテストに合格すれば満点が得られる可能性が高いです。
  • [16:18] 分散システムには多くの並行性と通信があるため、ラボのデバッグには時間がかかることがあります。学生は早めに始め、TAのオフィスアワーとPiazzaを活用すべきです。

アプリケーション基盤に関するコース

  • [17:34] このコースはアプリケーションのための基盤についてです。
  • [17:38] このコースは、他者(顧客)によって書かれたアプリケーションと、研究対象である基盤の間に分かれます。
  • [17:49] アプリケーションはこのコースで扱う基盤を利用します。
  • [18:05] 一般的な基盤の種類は、ストレージ、通信、計算です。
  • [18:15] このコースでは、三種類すべてのインフラを提供するシステムを扱います。

コースの焦点:ストレージ、計算、通信

  • [18:23] ストレージは明確に定義された有用な抽象化であるため、主な焦点となります。
  • [18:31] ストレージの抽象化は通常かなり単純明快であるため、人々は複製された耐障害性のある高性能な分散ストレージの構築について多くを知っています。
  • [18:45] このコースではMapReduceのような計算システムも扱います。
  • [18:53] コミュニケーションは主に、分散システムを構築するために必要なツールとして扱われます。このコースは主にコミュニケーションの消費者だからです。
  • [19:11] コミュニケーションシステム自体について学ぶことは、むしろ6829の話題です。
  • [19:24] ストレージと計算については、目標の多くは、アプリケーションをその上に簡単に構築できるようにインターフェースを簡素化する抽象化を発見することです。
  • [19:41] これは、これらのシステムの分散的な性質を隠す抽象化を構築することを意味します。
  • [19:50] 夢は、めったに完全には達成されませんが、アプリケーションから見てファイルシステムのような非分散ストレージシステムのように見えるインターフェースです。
  • [20:37] このコースはそこまでしか到達していません。分散ストレージや計算の抽象化は、非分散版とまったく同じようには振る舞わないことがほとんどです。

分散システムにおける実装の話題

  • [21:11] 取り上げられるシステムで繰り返し登場する一般的な話題は実装です。
  • [21:27] リモートプロシージャコールは、これらのシステムを構築することを学ぶための一般的なツールであり、その目標は信頼性の低いネットワーク上のコミュニケーションを覆い隠すことです。
  • [21:45] スレッドももう一つの実装の話題です。マルチコアコンピュータを活用するためのプログラミング技法であり、この授業にとってより重要なのは、プログラマの見方を簡素化してくれることを願う並行操作を構造化する方法です。
  • [22:08] スレッドは頻繁に使われるため、この授業ではロックなどの実装レベルでの並行性制御にも時間を割く必要があります。
  • [22:22] これらの実装の考え方は多くの論文で触れられますが、学生が分散システムを構築するラボで大々的に登場します。

分散システムにおけるスケーラビリティとボトルネック

  • [23:03] 分散システムの高レベルの目標は、しばしばスケーラブルな高速化です。
  • [23:17] スケーラビリティとは、コンピュータを二倍にすると時間を半分にできる、またはスループットを二倍にできることを意味します。
  • [23:58] ある係数でスケールしてその係数分のスループットを得ることは、大きな勝利です。
  • [24:17] コンピュータをお金で買う方が、パフォーマンスのためにソフトウェアを再構築するプログラマに払うよりも安くつきます。
  • [25:10] 多くのコンピュータから実際に対応するパフォーマンスを得るには、慎重な設計が必要です。
  • [26:27] 典型的な最初のステップは、より多くのWebサーバーを購入し、ユーザーをそれらに分散させることです。
  • [27:18] このスケーラビリティが無限であることはほとんどなく、10台、20台、または100台のWebサーバーの後では、データベースがボトルネックになります。
  • [27:51] Webサーバーを追加すると、ボトルネックはWebサーバーからデータベースへと移ります。
  • [28:01] その時点で設計作業がほぼ確実に必要になります。単一のデータベースをリファクタリングすることはめったに簡単ではないからです。

スケールアウトとフォールトトレランス

  • [28:15] 単一のデータベースに格納されたデータは、複数のデータベースに分割されるようにリファクタリングできます。
  • [28:24] このリファクタリングはしばしばかなりの作業量で厄介ですが、実際に多くの人がそれを行う必要があります。
  • [28:31] このコースでは、議論される分散システムがストレージシステムである多くの例を示します。
  • [28:39] これらの例は、単一のデータベースやストレージサーバーで限界に達した大規模なWebサイトのようなものを運営していた著者たちによるものです。
  • [28:49] このようにスケールするシステムは望ましいですが、この考えを無限に押し進めるのは困難か、設計作業を要します。
  • [29:09] フォールトトレランスは、頻繁に登場するもう一つの大きな話題です。

大規模環境におけるフォールトトレランス

  • [29:23] 単一のコンピュータとそのOSはしばしば何年も稼働し続けることができ、建物の電力はどうやら信頼できるようです。
  • [29:46] 数千台のコンピュータでは、各マシンが約一年間稼働し続けるとしても、千台あればおよそ一日に三回の故障が起きます。
  • [30:01] 大規模な分散システムは、ごくまれなフォールトトレランスの問題を、常に起こる故障に変えてしまいます。
  • [30:14] 千台のコンピュータがあるシステムでは、クラッシュしたマシンや誤動作しているマシンを含め、ほぼ確実に常に何かが壊れています。
  • [30:25] 多くのネットワークケーブルとスイッチがあるため、建物ほどの大きさのシステムのどこかで常にケーブルやスイッチの問題が発生しています。
  • [30:58] 故障は常に存在するため、故障を覆い隠すことと故障を知覚する能力は設計に組み込まれなければなりません。
  • [31:10] インフラストラクチャは、アプリケーションのプログラマから故障を隠す、または覆い隠すべきであり、そうすれば各プログラマが故障の種類ごとに複雑な対応を用意する必要がなくなります。
  • [31:45] フォールトトレランスの一般的な概念の一つは可用性です。ある種の故障(すべてではありません)の下でも、システムは損なわれていないサービスを提供し続けます。
  • [32:21] 二つのコピーを持つ複製サービスは、一方のレプリカが故障しても動作を続けられるかもしれませんが、両方が故障するとそうはいきません。
  • [32:56] 回復可能性は可用性よりも弱い要件です。サービスは応答を停止して修復を待ち、その後何事もなかったかのように続行するかもしれません。
  • [33:38] 回復可能なシステムは通常、電源が戻った後に取得できるよう、最新のデータをディスクに保存する必要があります。
  • [33:52] 可用性のあるシステムは通常、ある数の故障が発生するまで動作し、その後停止し、十分に修復されれば正しく動作を続けるように仕様が定められています。

問題を解決するためのアプローチ

  • [34:35] 講演者は、自分が聞くのが大好きで、得たいと思っていることを強調します。
  • [34:40] これらの問題を解決するための複数のアプローチが提示されます。最も強力な手段も含まれます。

フォールトトレランスのツール:ストレージとレプリケーション

  • [34:49] 不揮発性ストレージは、学科で最も重要なフォールトトレランスのツールの一つです。
  • [34:54] クラッシュや電源障害の後、ハードドライブ、フラッシュ、SSDなどの不揮発性ストレージは、システム状態のチェックポイントやログを保存できます。
  • [35:15] 電源が回復すると、システムはハードドライブから最新の状態を読み取り、そこから続行できます。
  • [35:28] 不揮発性ストレージの管理は、更新に費用がかかる傾向があるため、頻繁に登場します。
  • [35:35] 高性能なフォールトトレラントシステムを構築する際には、不揮発性ストレージへの書き込みをあまり行わないようにする巧妙な方法が多く関わってきます。
  • [35:50] 伝統的に不揮発性ストレージへの書き込みは、ディスクアームを動かし、プラッタが回転するのを待つことを意味し、どちらも3ギガヘルツのマイクロプロセッサの尺度では耐え難いほど遅いものでした。
  • [36:05] フラッシュはかなり優れていますが、それでも良好なパフォーマンスを引き出すには多くの考慮が必要です。
  • [36:12] レプリケーションはフォールトトレランスのためのもう一つの大きなツールであり、レプリカのコピーの管理は難しいものです。
  • [36:33] あらゆる複製システムにおける重要な問題は、二つのレプリカが誤って同期を外れてしまい、レプリカでなくなることです。
  • [36:50] ラボ2はフォールトトレランスのためのレプリカのコピーの管理に関するもので、かなり複雑です。

分散キーバリューシステムにおける一貫性

  • [37:16] 分散キーバリューストレージシステムは、キーと値のテーブルに対するputおよびget操作をサポートします。
  • [38:08] アプリケーションプログラマは、putとgetが何を意味するかを記述した仕様を必要とします。そうでなければアプリケーションの作成は困難です。
  • [38:37] 分散システムにおいて一貫性が興味深いのは、パフォーマンスとフォールトトレランスのためにデータのコピーを複数保持することが多いからです。
  • [38:53] 単一サーバーの非分散システムでは、putとgetが何を意味するかについて相対的な曖昧さはほとんどありません。
  • [39:16] レプリケーションやキャッシングでは、キーバリューペアの多くのバージョンが浮遊している可能性があります。
  • [40:19] クライアントが一方のレプリカを更新した後、二つ目を更新する前にクラッシュした場合、一方のレプリカは21を保持し、もう一方はまだ20を保持しています。
  • [40:39] 後続のgetは、どのサーバーと通信するかによって21または20を返す可能性があり、古いコピーがいつか露出するかもしれません。
  • [41:28] このレプリケーションの危険性のため、putとgetに関するルールを書き留める必要があります。
  • [41:37] 一貫性の定義には多くの可能性があります。強一貫性は通常、getが最も最近完了したputによって書き込まれた値を返すことと定義されます。
  • [42:02] また、getが最も最近のputによって書き込まれた値を見ることを保証しない弱一貫性システムを構築することも非常に有用です。

弱一貫性と強一貫性のトレードオフ

  • [42:39] 弱一貫性では、読み手はputを見ない可能性があり、無制限の時間にわたって古い値を見る可能性があります。
  • [42:54] 強一貫性は、読み取りが最新の書き込みを見ることが保証されることを意味しますが、実装するには非常に高コストな仕様です。
  • [43:19] 複数のコピーを持つ強い一貫性とは、書き手、読み手、またはその両方がすべてのコピーに問い合わせなければならないことであり、一つの値を読むのに大量の通信が必要になります。
  • [43:53] 通信を避けるため、特にレプリカが遠くにある場合、人々は古い値の古い読み取りを許容する可能性のある弱いシステムを構築します。
  • [44:23] フォールトトレランスのためには、レプリカは独立した無相関の故障確率を持つべきなので、両方のレプリカを同じラックに置くのはおそらく悪い考えです。
  • [44:57] 人々はレプリカをできるだけ離れた場所、たとえば異なる都市に置きたいと考えます。そうすれば一つの地震で両方が破壊される可能性は低くなります。
  • [45:24] 光の速さの移動により、大陸を越えたデータセンターとの通信には数ミリ秒から数十ミリ秒のオーダーがかかる可能性があります。
  • [45:48] 強一貫性では、両方のコピーと通信するために10、20、または30ミリ秒待つ必要があり、多くの潜在的な命令を無駄にする可能性があります。
  • [46:12] 人々はしばしば、最も近いコピーのみを更新するか、または問い合わせることのみが許される、はるかに弱いシステムを構築します。

ケーススタディとしてのMapReduce

  • [46:53] MapReduceは、議論されたアイデアのほとんどを例示する詳細なケーススタディです。
  • [47:06] MapReduceは元々Googleによって設計、構築、使用され、論文は2004に遡ります。
  • [47:15] Googleは、ウェブのインデックス作成や重要なページを見つけるためのリンク構造の分析など、テラバイトのデータに対する巨大な計算に直面していました。
  • [47:53] ウェブコンテンツ全体を単一のコンピュータでソートするには、数週間、数ヶ月、または数年かかったでしょう。
  • [48:02] Googleは、ジョブが迅速に完了できるように、数千台のコンピュータで巨大な計算を実行したいと考えていました。
  • [48:25] しばらくの間、エンジニアは多くのコンピュータに計算を分散させるためのアドホックなソフトウェアを手書きしていました。
  • [49:49] 彼らは、非専門家が巨大な分散計算を簡単に書いて実行できるフレームワークを望んでいました。
  • [50:04] プログラマは分散について知ることなく、単純なmap関数と単純なreduce関数のみを書きます。
  • [50:28] 入力はチャンクまたはファイルに分割され、フレームワークは各入力ファイルに対してmap関数を並列に実行します。
  • [51:31] map関数はファイルを入力として受け取り、キーバリューペアのリストを出力として生成します。
  • [51:45] 単語カウントの例では、map 関数は各単語をキーとして、一を値として出力します。

MapReduceジョブの実行と用語

  • [52:20] mapタスクは、入力で見つかった各単語に対してA:1やB:1などのキーバリューペアを出力します。
  • [52:52] すべての入力ファイルに対してすべてのmapを実行すると、中間出力、つまりmapごとのキーバリューペアのセットが生成されます。
  • [53:06] MapReduce フレームワークは、すべての map から各キーのすべてのインスタンスを集め、プログラマが定義した reduce 関数の一回の呼び出しに渡します。
  • [53:35] Bのようなキーを収集するには、異なるコンピュータ上の異なるmap呼び出しによって生成されたため、実際のデータ移動が必要です。
  • [54:05] フレームワークは、いずれかの map の出力に現れたすべてのキーに対して一回の reduce 呼び出しを手配します。
  • [54:17] 単語カウントの例では、各値は一を足すものなので、各 reduce は渡された項目の数を数えるだけです。
  • [55:07] 計算全体はジョブと呼ばれ、map または reduce の一回の呼び出しはタスクと呼ばれます。

MapReduceの単語カウントの例

  • [55:27] 単語カウントの例は、map関数とreduce関数がどのようなものかを示しています。
  • [55:40] map関数はキーと値を引数として受け取り、C++やJavaのような通常のプログラミング言語で書かれます。
  • [55:53] 単語カウント用のmap関数は、入力ファイルの内容である値を単語に分割します。
  • [56:30] 各単語について、map 関数はその単語をキーとして、文字列の一を値として出力します。
  • [56:51] MapReduceにおける単語カウントのmap関数は、文字通りこれほど単純なものであり得ます。
  • [57:00] map関数は、分散、複数のコンピュータ、ネットワークを介したデータ移動について何も知りません。
  • [57:18] reduceはキーと、そのキーに対してmapが生成したすべての値のベクトルを引数として呼び出されます。
  • [57:37] 単語カウントでは、キーは単語であり、値はすべて一です。重要なのは数だけです。
  • [57:44] reduceは配列の長さを、そのキーの最終出力値として出力します。
  • [58:00] MapReduceのreduce関数は極めて単純で、フォールトトレランスに関する知識を必要としません。

MapReduceジョブの連鎖とその限界

  • [58:34] reduceの出力を別のMapReduceジョブへの入力として渡すことができます。
  • [58:51] 多段階の分析や反復アルゴリズムのためにジョブを連鎖させることは、MapReduceユーザーの間では日常的なことです。
  • [59:08] Googleがウェブページの重要度を推定するために使用するPageRankは、徐々に収束する反復アルゴリズムです。
  • [59:25] MapReduceでPageRankを実装するには、ジョブを複数回実行する必要があり、各出力は別のジョブへの入力として使用されます。
  • [59:50] 次のMapReduceジョブに必要な形式でデータを生成するようにreduce関数を設定する必要があります。
  • [1:00:07] MapReduceの欠点は、アルゴリズムがmap、キーによるシャッフル、reduceとして容易に表現できる場合にのみうまく機能することです。
  • [1:00:30] 各mapは完全に独立しており、引数のみを参照する純粋関数でなければなりません。
  • [1:00:46] 多くの人々は、多種類の処理を含むより長いパイプラインを望んでおり、それは複数の異なるMapReduceジョブを寄せ集めて構築しなければなりません。
  • [1:00:59] このコースの後半で議論されるより高度なシステムは、完全なパイプラインを指定し、最適化を行うことをよりうまく実現します。

MapReduce:プログラマー視点とフレームワーク視点

  • [1:01:39] プログラマーの観点から見ると、MapReduceは単にmapとreduceに関するものです。
  • [1:01:43] フレームワークの観点から見ると、MapReduceフレームワークの一部であるワーカープロセスやワーカーサーバーなど、多くの要素が関係します。
  • [1:02:00] フレームワークの構成は非常に重要であり、プログラマーの視点は分散部分を取り除いたものです。

MapReduceのemitとワーカーアーキテクチャ

  • [1:02:31] 二つの別々の問いがあります。出力されたデータがどうなるかということと、関数がどこで実行されるかということです。
  • [1:02:51] 現実の世界では、論文の図一に示されているように、多数のワーカーサーバーの集合と、計算を組織する単一のマスターサーバーがあります。
  • [1:03:16] マスターは入力ファイルの数(例:5,000)を把握しており、mapの呼び出しを異なるワーカーに割り当てます。
  • [1:03:39] ワーカープロセスがemitを実装しており、mapがemitを呼び出すたびに、ワーカーはデータをローカルディスク上のファイルに書き込みます。
  • [1:04:27] mapフェーズの終了時には、各ワーカーマシンはそこで実行されたmapの出力を保持しています。
  • [1:04:40] その後、MapReduceワーカーはreduceに必要な場所へデータを移動します。
  • [1:05:13] reduceを実行する前に、reduceワーカーは通常、他のすべてのサーバーに連絡し、自身が担当するキーのすべてのインスタンスを取得する必要があります。
  • [1:05:48] reduceワーカーがそのすべてのデータを収集すると、reduceを呼び出すことができ、reduceはreduce emitを呼び出します。

GFSとMapReduceの入力ストレージ

  • [1:06:17] 講演者はまだ、入力データと出力データがどこに存在するかについて言及していませんでした。
  • [1:06:22] 入力と出力はどちらもファイルに存在します。
  • [1:06:27] 任意のワーカーサーバーで入力の任意の部分を読み取るには、入力データを保存するネットワークファイルシステムが必要です。
  • [1:06:41] 論文では、Google File SystemであるGFSについて議論しています。
  • [1:06:49] GFSは、MapReduceを実行するのとまったく同じワーカーサーバー上で動作するクラスタファイルシステムです。
  • [1:07:03] GFSは、そこに保存された大きなファイルを自動的に64メガバイトのチャンクに分割し、多数のサーバーに分散させます。
  • [1:07:10] GFSに書き込まれた10テラバイトのクロールされたウェブページコンテンツは、たとえ単一の大きなファイルであっても、自動的に64キロバイトのチャンクに分割され、すべてのGFSサーバーに均等に分散されます。
  • [1:07:35] クロールされたウェブ全体を入力とする MapReduce ジョブでは、データはすでにすべてのサーバーに均等に分割されているため、千台のサーバーがあれば千台の map ワーカーがそれぞれ入力の千分の一を千台の GFS ファイルサーバーから並列に読み取ります。

MapReduceのネットワークボトルネックとGFSデータアクセス

  • [1:08:21] 疑問は、GoogleがGFSとMapReduceを別々の物理マシンセットで実行しているかどうかです。
  • [1:08:48] GFSとMapReduceの間の矢印が何を意味するかという答えは、Googleのシステムが進化するにつれて年々変化しました。
  • [1:08:58] 最も一般的なケースでは、大きなファイルはGFSのようなネットワークファイルシステムに保存され、それはAFSに少し似ています。
  • [1:09:18] MapReduceワーカーは、入力を取得するために、ネットワークを介して正しいGFSサーバーと通信しなければならない場合があります。
  • [1:09:36] そのネットワークフェッチのアプローチが最終的にMapReduceの実際の動作方法となりましたが、それは多くのネットワーク通信を意味します。
  • [1:10:05] この論文の2004の世界では、彼らのMapReduceシステムにおける最も制約となるボトルネックはネットワークスループットでした。
  • [1:10:43] すべてのラックのイーサネットスイッチが単一のルートイーサネットスイッチと通信していたため、少なくとも半分の時間は通信がそれを通過していました。
  • [1:11:17] ルートスイッチの総スループットを約2,000台のサーバーで割ると、各マシンには50メガビット毎秒しか割り当てられませんでした。
  • [1:11:50] その50メガビット毎秒は、ディスクやCPUの速度と比較して途方もない制限であったため、設計ではネットワークの使用を避けるための工夫がなされました。

GFSとMapReduceのデータローカリティ

  • [1:12:14] GFS サーバーと MapReduce ワーカーは同じ千台のマシン上で実行されました。
  • [1:12:28] マスターがマップ作業を分割するとき、各入力ファイルがローカルディスク上のどのサーバーに保持されているかをGFSから判断しました。
  • [1:12:50] マスターは、入力ファイルに対する各マップを同じマシン上のMapReduceソフトウェアに送信しました。
  • [1:12:57] デフォルトでは、読み取りはディスクからローカルに行われ、ネットワークを介しませんでした。
  • [1:13:03] 障害や負荷に応じて、常にこれができるわけではありませんでしたが、ほとんどすべてのマップはデータを保存しているマシン上で実行され、入力データをネットワーク経由で移動する時間を節約しました。
  • [1:13:22] マップの出力はマップを実行しているマシンのローカルディスクに保存されるため、出力の保存にはネットワーク通信は必要ありません。

MapReduceのシャッフルとネットワークコスト

  • [1:13:54] あるマシンで出力を生成するには、ネットワーク通信が必要です。
  • [1:14:06] シャッフルは、マップを実行したマシン上で行ごとに保存されていたキーを、リデュースを担当するマシン上で列ごとに保存されるように移動します。
  • [1:14:21] 論文では、この行ストレージから列ストレージへの変換をシャッフルと呼んでいます。
  • [1:14:27] シャッフルでは、すべてのデータを、それを生成したマップからそれを必要とするリデュースへとネットワーク経由で移動する必要がありました。
  • [1:14:32] そのネットワーク移動がMapReduceの高コストな部分でした。
  • [1:14:51] よりストリーミング的なリデュースは想像できますが、講演者はそれを十分に検討しておらず、実現可能かどうかはわかりません。
  • [1:15:01] 彼らの第一の目標は、システム内で何が起こっているかをまったく知らない人々にとってプログラミングを容易にすることでした。
  • [1:15:16] リデュース関数仕様のストリーミング版は、おそらくこれほど単純には見えないでしょう。

MapReduceの現代の後継者

  • [1:15:36] 人々はMapReduceの現代の後継者によってより洗練されてきました。
  • [1:15:39] これらの後継者は、バッチアプローチを使用するのではなく、データのストリームを処理することがよくあります。
  • [1:15:48] MapReduceは、すべてのデータが利用可能になるまで待ってから処理するため、バッチアプローチです。
  • [1:15:55] バッチアプローチでは、有限の入力という概念が必要です。
  • [1:15:59] 現代のシステムはしばしばストリームを使用し、それによるいくつかの効率性を活用できます。

MapReduceのシャッフルと出力ネットワークトラフィック

  • [1:16:12] シャッフル段階は、すべてのネットワークトラフィックが発生する場所であり、膨大な量のデータを伴う可能性があります。
  • [1:16:24] ソートの場合、出力サイズは入力サイズと等しいため、10テラバイトをソートすると10テラバイトがネットワーク上を移動します。
  • [1:16:40] これは、すべてではないにしても多くのMapReduceジョブにとって大量のデータであり、一部の段階ではデータを大幅に削減できます。
  • [1:16:49] 人々はしばしばリデュースの出力を別のMapReduceジョブに供給したいと考えました。
  • [1:16:56] リデュースの出力は、ソートやウェブインデックス作成の場合のように、膨大になる可能性があります。例えば、10テラバイト入力に対して10テラバイト出力です。
  • [1:17:04] リデュースの出力もGFSに保存され、フレームワークはキーと値のペアを巨大なファイルにまとめました。
  • [1:17:24] 各リデュースの出力をそれを保存するGFSサーバーに届けるには、別のラウンドのネットワーク通信が必要でした。
  • [1:17:48] GFS は耐障害性のために二つまたは三つのコピーを保持するため、一つのコピーは常にネットワークを介して別のサーバーに書き込まれなければなりません。

現代のデータセンターネットワークとMapReduce

  • [1:18:16] 単一ルートのネットワーク構成は、多くの望ましいデータセンタータスクにとって制限要因でした。
  • [1:18:22] 現代のデータセンターネットワークは、この初期の設計よりもルートでの速度がはるかに速いです。
  • [1:18:28] 典型的な現代のデータセンターネットワークには、単一のルートスイッチではなく多数のルートスイッチがあり、各ラックスイッチは各複製ルートスイッチに接続され、トラフィックはそれらの間で分割されます。
  • [1:18:49] したがって、現代のデータセンターネットワークははるかに多くのネットワークスループットを備えています。
  • [1:18:52] Googleは数年前にMapReduceの使用を停止したと報じられています。
  • [1:19:01] それ以前は、現代のMapReduceはデータが保存されている同じマシン上でマップを実行しようとせず、ネットワークが非常に高速であると仮定して、どこからでもデータをロードして問題ありませんでした。

MapReduceのまとめとラボ

  • [1:19:16] MapReduceの時間は終わり、ラボがあります。
  • [1:19:21] 来週の終わりのラボでは、やや簡略化されたMapReduceを作成します。
  • [1:19:30] 講師は楽しんでくださいと言い、木曜日に会いましょうと言っています。

[0:01] では、始めましょう。これは6824、分散システムです。ええと、ありがとう。まず、私が分散システムとは何かと思うかについて簡単に説明したいと思います。ありがとう。その核心は、ネットワークを介して互いに通信し、何らかの一貫したタスクを完了する協調コンピューターのセットです。このクラスで焦点を当てる例の種類は、大規模ウェブサイトのストレージや、MapReduceのようなビッグデータ計算などです。ええと、また、ピアツーピアのファイル共有のようないくつかよりエキゾチックなものもあります。

[0:43] これらはすべて、私たちが検討するケーススタディの種類の単なる例です。ええと、これがすべて重要である理由は、多くの重要なインフラストラクチャが分散システムで構築されているからです。複数のコンピューターを必要とする、または本質的に物理的に分散する必要があるインフラストラクチャです。ええと。では、人々がこれを作る理由は、まず第一に、分散システムについて話す前に、システムを設計しているなら、単一のコンピューターで解決できるなら、何らかの問題を解決する必要があることを思い出してほしいのです。

[1:17] ご存知のとおり、分散システムを構築せずに、そのようにすべきです。そして、単一のコンピュータで完了できる仕事は非常に多くあり、その方が常に簡単です。ですから分散システムについては、分散システムを構築する前に他のあらゆる方法を試すべきです。なぜならそれらはより単純ではないからです。人々が多数の協調するコンピュータを使うようになる理由は、高い性能を得る必要があるからです。そしてそれを考える方法は、何らかの並列性を達成したいということです。多数のCPU、多数のメモリ、多数のディスクアームが並列に動くのです。

[1:54] 人々がこうしたものを作るもう一つの理由は、故障に耐えられるようにするためです。わあ。二台のコンピュータにまったく同じことをさせるのです。一方が故障したら、もう一方に切り替えられます。もう一つは、問題によっては空間的に自然に分散しているものがあることです。ええと、銀行間の送金などをしたいとします。銀行 A はニューヨーク市にこのコンピュータを持ち、銀行 B はロンドンにこのコンピュータを持っています。

[2:25] ご存知のとおり、それを実行するためには、それらが互いに通信し協調する何らかの方法が必要なだけです。ですから、本質的に物理的に分散しているシステムには、ある種の自然な物理的理由があります。そして人々がこうしたものを構築する最後の理由は、何らかのセキュリティ目標を達成するためです。よくあるのは、信頼できないコードがある場合、または誰かとやり取りする必要がある場合です。その相手は悪意があるかもしれませんし、そのコードにバグがあるかもしれません。ですからそれを信頼しなくて済むようにしたいのです。計算を分割したいかもしれません。つまり、あなたのものはあちらのコンピュータで動き、私のものはこちらのコンピュータで動き、それらは互いにだけ通信します。

[3:03] 何らかの狭く定義されたネットワークプロトコルに対してです。ですから私たちはセキュリティを心配しているかもしれません。そしてそれは、複数のコンピュータに分割して分離できるようにすることで達成されます。ええと。このコースの大部分は性能と障害耐性についてですが、他の二つもしばしば、これから見ていくケーススタディに対する制約という形で自然に関わってきます。ええと、ご存知のとおり、これらの問題における分散システムはすべて、多くの部分を持ち、その部分が並行して実行されるため、複数のコンピュータがあるからです。

[3:42] 並行プログラミングで生じるすべての問題、つまり複雑な相互作用や奇妙なタイミング依存の事柄すべてが発生します。そしてそれが分散システムを難しくする一因です。分散システムを難しくするもう一つのことは、ここでも複数の部分とネットワークがあるため、非常に予期しない障害パターンが起こり得ることです。つまり、単一のコンピュータの場合、通常はコンピュータが動くか、あるいはクラッシュしたり電源障害などに遭ったりするかもしれません。しかし基本的には動くか動かないかのどちらかです。

[4:12] 多数のコンピュータで構成される分散システムでは、部分的な障害が起こり得ます。つまり、一部の部分が動かなくなり、他の部分は動き続けます。あるいはコンピュータは動いているが、ネットワークの一部が壊れているか信頼できないかもしれません。ええと、ですから部分的な障害は、分散システムが難しいもう一つの理由です。これが基本的な課題の一種です。さようなら。ありがとう。ありがとう。

[4:44] さようなら。字幕は Amara.org コミュニティによるものです。ありがとう。ありがとう。そして難しい理由の最後の一つは、ご存じのとおり、分散システムを作るもともとの理由はしばしばより高い性能を得るためだということです。1,000 台のコンピュータ分の性能、または 1,000 本のディスクアーム分の性能を得るためです。しかし、千台のコンピュータでその千倍の高速化を得るのは実に難しいのです。しばしば多くの障害物が行く手に投げ込まれます。ええと、こんにちは。

[5:15] ありがとう。ありがとう。システムが実際に自分にふさわしいと思う性能を出せるようにするには、しばしば少し注意深い設計が必要です。ですからこれらの問題を解くことは、もちろん、これらの課題に対処することにほかなりません。ええと、このコースを受ける理由は、しばしば問題と解決策が技術的に非常に興味深く、そして難しい問題だからです。これらの問題のいくつかについては、かなり良い解決策が知られていますが、他の問題については、それほど優れた解決策はありません。いいえ。

[5:46] 分散システムは実世界の多くのシステムで使われており、大規模なウェブサイトもしばしば関わっています。ご存知のとおり、膨大な数のコンピュータが分散システムとして組み合わされています。私がこのコースを教え始めた頃、それは…分散システムはある種の学術的な好奇心の対象でした。ご存知のとおり、人々は「ああ、小規模では時々使われていて、いつかは重要になるかもしれない」と思っていました。しかし今では、特に巨大なウェブサイトの台頭に後押しされて、

[6:17] ご存知のとおり、膨大な量のデータとコンピュータでいっぱいの倉庫を持つようになり、分散システムは過去20年間でコンピューティングインフラの非常に重要な部分になってきました。わかりました。これは、それらに多くの注意が払われてきたことを意味し、多くの問題は解決されてきましたが、まだかなりの数の未解決問題があります。ですから、大学院生であるか研究に興味があるなら、分散システムにはまだ解くべき問題がたくさんあります。彼の研究を調べてみるとよいでしょう。

[6:49] そして最後に、ものづくりが好きなら、このクラスは良いクラスです。なぜなら、性能と障害耐性に焦点を当てた、かなり現実的な分散システムを構築するラボのシーケンスがあるからです。ですから、分散システムを構築し、それらを動作させる多くの練習ができます。よし。実際の技術的な内容を始める前に、コースの構成について少し話しましょう。コースのウェブサイトは見つけられるはずです。

[7:20] Google を使ってください。コースのウェブサイトにはラボの課題、コースのスケジュールがあり、また質問を投稿して回答を得られる Piazza へのリンクもあります。ええと、コースのスタッフですが、私 Robert Morris が講義を行います。また四名の TA がいます。皆さん、立って顔を見せてくれますか。ええと、ありがとう。TA は特にラボの解決の専門家であり、オフィスアワーを設けますので、ラボについて質問があればオフィスアワーに来てください。

[7:54] あるいは Piazza に質問を投稿することもできます。ええと、ありがとう。このコースにはいくつかの重要な構成要素があります。ええと、一つは講義です。ほぼ毎回の講義に対応する論文があります。ありがとう。ありがとう。二回の試験があります。ありがとう。ありがとう。ありがとう。さようなら。ラボ、プログラミングラボがあり、ええと、ラボの一つに代えて行える任意の最終プロジェクトがあります。

[8:27] ありがとう。字幕はAmara.orgコミュニティによるものです。講義は分散システムの大きなアイデアについてです。また、ラボのプログラミングに関する講義もいくつかあります。講義の多くはケーススタディに費やされます。私が分散システムの内容を引き出す方法の多くは、論文を見ることです。学術論文もあれば、業界の人々が実際の問題に対する実際の解決策を説明したものもあります。

[9:04] ええと、これらの講義は実際にビデオ録画されます。そしてオンラインに投稿して、ここにいない場合や講義を復習したい場合にビデオ講義を見られるようにしたいと思っています。アーメン。論文については、繰り返しますが、週に一篇読む必要があります。そのほとんどは研究論文です。いくつかは古典的な論文です。今日の論文のように、MapReduce について書かれたもので、何人かは読んでいることを願っています。古い論文ですが、始まりであり、学術界と実社会の両方で膨大な量の興味深い研究を促しました。ですから、古典的なものもあれば、より最近の論文もあります。

[9:38] より最新の研究、人々が現在懸念していることについて話します。そして論文から、基本的な問題は何か、分散システムの問題を解決するのに役立つかもしれないし役立たないかもしれない、人々が持ったアイデアは何かを引き出したいと思っています。ええと、これらの論文のいくつかでは実装の詳細を見ることもあります。というのも、この多くはソフトウェアベースのシステムの実際の構築に関係しているからです。また、評価を見る時間もかなり取ります。人々が自分のシステムの耐障害性を測定して評価したり、パフォーマンスがどれだけあるか、あるいはパフォーマンスの改善がまったく得られたかどうかを測定したりするものです。

[10:14] ええと、皆さん全員が授業に来る前に論文を読んでいることを願っています。講義は… まだ講義を読んでいないとあまり意味をなさないかもしれません。というのも、論文の内容をすべて説明し、論文が意味するものについて興味深い考察をする時間が十分にないからです。オンラインクラスでは、本当に授業に来る前に論文を読まなければなりません。そして、このクラスで学ぶことの一つが、論文を迅速かつ効率的に読み、あまり重要でない部分を飛ばし、重要なアイデアを引き出すことに焦点を当てる方法であることを願っています。

[10:50] ウェブサイトには、スケジュールによる各リンクに対して、質問があります。論文ごとに回答を提出する必要があります。回答は真夜中が締め切りだと思います。また、論文についての質問も提出するよう求めています。ええと、ウェブサイトに提出することで、私が講義を準備する際に考える材料になり、時間があれば少なくともいくつかの質問にはメールで答えようと思います。各論文の質問と回答は、前日の真夜中が締め切りです。

[11:21] 試験は二つあり、授業中に行われる中間試験は、確か春休み前の最後の授業の回だったと思います。それから学期末の期末試験週間に行われる期末試験があります。試験は主に論文とラボに焦点を当てます。そしておそらく試験対策として最良の方法は、講義に出席して論文を読むことと並んで、過去の試験を見ることです。

[11:52] 過去20年分の試験と解答があります。それらを見て、私がどのような種類の質問をするのが好きかを感じ取ってください。実際、私たちは同じ論文を多く読むので、毎年、前の年に出された質問に似ざるを得ない質問をどうしてもすることになります。ありがとう。ラボは四つのプログラミングラボがあります。最初のラボの締め切りは来週の金曜日です。それらは……

[12:23] ありがとう。ラボ一は……ありがとう。シンプルなMapReduceラボです。数分後に私が説明する論文の自分自身のバージョンを実装します。ラボ二は、raftと呼ばれる技術を使って、理論上はあらゆるシステムを複製し、このraft技術に複製を管理させ、複製されたサーバーの一つが故障した場合の自動切り替えを管理させることで、フォールトトレラントにできるようにすることを含みます。

[12:59] これがフォールトトレランスのためのRAFTです。ありがとう。字幕はAmara.orgコミュニティによる *キス* ラボ三では、raftの実装を使ってフォールトトレラントなキーバリューサーバーを構築します。ありがとう。アーメン。ありがとう。それは複製され、フォールトトレラントになります。そしてラボ四では、複製されたキーバリューサーバーを多数の独立したグループに複製し、キーバリューストレージシステム内のデータをこれら個々の複製グループ全体に分割して、並列のスピードアップを得ます。

[13:37] 複数の複製グループを並列に実行することで、また、サーバーが増減する際にさまざまなデータのチャンクを異なるサーバー間で移動させる責任も負うことになります。ボールを一つも落とさないように。よくシャーディングと呼ばれる、さようなら。キーバリューサービス。さようなら。あなた シャーディングとは、データを分割すること、データをパーティション分割することを指します。並列の高速化を得るために複数のサーバー間で。

[14:10] ありがとう。希望するなら、ラボ四の代わりに自分で選んだプロジェクトを行うこともできます。ここでの考え方は、分散システムについて何かアイデアがあるなら、授業で話す分散システムのスタイルで、追求したい自分のアイデアがあり、何かを作ってそれがうまくいったかどうかを測定したいなら、自分のアイデアを探求できるということです。プロジェクトを行うことができます。プロジェクトでは、プロジェクトは二、三人のチームで行うことを要求しているので、チームメイトを何人か選びます。

[14:45] ナム。それで、チームメイトを何人か選んで、プロジェクトのアイデアを私たちに送ってください。そうすれば私たちが検討して、はいかいいえを言い、おそらくいくつかアドバイスをします。ええと、そしてもし先に進んで行うなら、もし私たちがはいと言い、あなたがプロジェクトを行いたいなら、ラボ4の代わりにそれを行い、それは学期の終わりに行います。ご存知の通り、あなたは... いくつかの設計作業を行い、実際のシステムを構築すべきです。そして授業の最終日に、あなたのシステムを実演します。また、短い... 一種の書面による報告書を、何を構築したかについて私たちに提出します。そして私はウェブサイトにいくつかのアイデアを投稿しました。それはあなたがどんなプロジェクトを構築できるかについての考えを刺激するのに役立つかもしれないし、役立たないかもしれません。しかし本当に最良のプロジェクトは、あなたがプロジェクトについて良いアイデアを持っているものです。そして考え方は、もしプロジェクトを行いたいなら、この授業で話すシステムと同じ系統のアイデアを選ぶべきだということです。

[15:40] はい、ラボに戻ります。私たちが与えるラボの成績は、あなたがラボのコードを提出し、私たちがそれに対していくつかのテストを実行し、あなたは合格したテストの数に基づいて採点されます。私たちは使用するすべてのテストをあなたに与えるので、隠されたテストはありません。ですから、もしラボを提出してそれがすべてのテストに確実に合格すれば、何かおかしなことが起こっていない限り、時々起こりますが、可能性は高いです。あなたのコードが実行時にすべてのテストに合格すれば、私たちが実行するときにもすべてのテストに合格する可能性が高く、満点を取れるでしょう。ですから、あなたが得そうなスコアについて謎はないことを願っています。

[16:13] ラボについて。ええと、これらのラボのデバッグは時間がかかる可能性があることを警告しておきます。なぜならそれらは分散システムであり、多くの並行性と通信があり、ええと、一種の奇妙でデバッグが難しいエラーが発生する可能性があるからです。本当にラボを早く始めるべきです。残さないでください。ラボを最後の瞬間まで残すと多くの問題が発生します。早く始めなければなりません。もし問題があれば、TAのオフィスアワーに来てください。

[16:44] そして遠慮なく質問してください。ラボについてPiazzaで。そして実際、もし答えを知っているなら、Piazzaで他の人の質問にも答えてくれることを願っています。よし。コースの仕組みについて何か質問はありますか?はい?さようなら。ええ。ありがとうございます。それで質問は、これらのことが成績にどう影響するかということです。忘れましたが、すべて...に載っています。

[17:18] それはウェブサイトの...何かの下に載っています。ええと。ラボが単一の最も重要な要素だと思います。ありがとうございます。よし。ありがとうございます。ええと... よし、それではこれはアプリケーションのためのインフラストラクチャについてのコースです。ですからこのコース全体を通して、私が物事を話す方法には一種の分裂があります。アプリケーション、つまり他の人、顧客、誰か他の人が書くものの間で。

[17:49] アプリケーションは、このコースで私たちが考えているインフラストラクチャを使用します。そして、よく出てくる種類のインフラストラクチャ。ありがとうございます。ありがとうございます。はストレージ ありがとうございます。通信 ありがとうございます。そして計算です。そして私たちはこれら三種類のインフラストラクチャすべてを提供するシステムについて話します。

[18:19] ええと、ストレージ ストレージが私たちが最も焦点を当てるものになることがわかりました。なぜならそれは非常によく定義され有用な抽象化だからです。そしてありがとうございます。通常はかなり straightforward な抽象化です。ですから人々はストレージシステムの使用方法と構築方法、そしてストレージの複製されたフォールトトレラントな高性能分散実装の構築方法について多くを知っています。私たちはまた、今日のMapReduceのようないくつかの計算システムについても話します。

[18:50] は計算システムです。ええと、そして私たちは通信についてもいくらか話しますが、主に分散システムを構築するために使用する必要があるツールとしての観点からです。コンピュータはネットワークを介して互いに通信しなければならないように、信頼性か何かが必要かもしれません。ですから私たちは少し話しますが、実際には主に...通信の消費者です。ええと、もし通信システムについて、またはそれらがどのように機能するかを学びたいなら、それはより6829のトピックです。ですからストレージと計算については、私たちの目標の多くは抽象化を発見できることです。ええと、これらのストレージと計算の分散ストレージと計算インフラストラクチャへのインターフェースを簡素化する方法であり、その上にアプリケーションを構築しやすくするためです。

[19:41] そしてそれが本当に意味するのは、私たちはこれらのシステムの分散的な性質を隠す抽象化を構築できることを望んでいるということです。ですから夢は、めったに完全には達成されませんが、夢はインターフェースを構築できることであり、アプリケーションにとっては、あたかも非分散ストレージシステム、ちょうどファイルシステムや誰もがすでにプログラムする方法を知っていてかなり単純なモデルセマンティクスを持つもののように見えることです。私たちは非分散のストレージと計算システムとまったく同じように見え、動作するが、実際には...ご存知の通り、その下に広大で極めて高性能なフォールトトレラントな分散システムがあるインターフェースを構築できることを切望しています。

[20:23] ええと。ですので、抽象化があると嬉しいですよね。ありがとうございます。字幕はAmara.orgコミュニティによるものです。ありがとうございます。そして、コースが進むにつれてお分かりになるでしょうが、私たちはある意味、ご存じの通り、まだ道半ばなのです。分散版のストレージや計算の抽象化で、単純な振る舞いをするもの、つまり皆が理解している非分散版のストレージと同じように振る舞うものを見つけることは稀です。人々はこれに関して上手くなってきていますが…

[20:54] ええと、私たちは人々がそのような抽象化を構築する方法について学んだことを研究しようとしています。よろしいですか。これらの抽象化を検討する際に、どのような種類の、どのような種類のトピックが現れるでしょうか。最初のもの、最初のトピック、私たちがよく目にする一般的なトピックは、私たちが見る多くのシステムにおいて、実装に関係しています。ありがとうございます。ええと、例えば、人々がこれらのシステムを構築する方法を学ぶためによく目にするツールの種類は、リモートプロシージャコールのようなもので、その目的は、私たちが信頼性の低いネットワークを介して通信しているという事実を覆い隠すことです。

[21:38] ええと、もう一つの実装に関するトピックとしてよく目にするのはスレッドです。これはプログラミング技法で、マルチコアコンピュータを活用できるようにしますが、このクラスではおそらくもっと重要なのは、スレッドは並行操作を構造化する方法であり、できればプログラマにとってそれらの並行操作の見方を単純化するものであるということです。ええと、そしてスレッドをたくさん使うことになるので、実装レベルからも、並行性制御、例えばロックのようなものについてある程度時間をかけて考える必要が出てきます。

[22:18] ええと。ありがとうございます。そして、これらの実装のアイデアがクラスで主に登場する場所は、多くの論文でも触れられますが、ラボで本格的に直面することになります。分散システムを構築する必要があります。つまり、分散システムのプログラミングを行うのです。これらは普通のプログラミングを超えた重要なツールの多くのようなものです。ええと、これらは分散システムを構築するために必要となる重要なツールの一部です。戻りました。

[22:50] これから話すすべての論文で出てくるもう一つの大きなテーマは性能です。ありがとう。さようなら。ありがとう。ありがとう。通常、分散システムを構築する高レベルの目標は、人々がスケーラブルなスピードアップと呼ぶものを得ることです。ですから私たちはスケーラビリティを追求します。スケーラビリティ、つまりスケーラブルなスピードアップとは、一つのコンピュータで解いている問題があり、その問題を実行するのを助けるために二台目のコンピュータを買った場合に、

[23:30] 今度はその問題を半分の時間で解ける、あるいは一分間に二倍の問題インスタンスを解けるなら、一台のコンピュータでできたことを二台のコンピュータでできるなら、それはスケーラビリティの一例です。つまり、コンピュータやリソースが二倍になれば、性能やスループットが二倍になるということです。そしてこれは巨大なハンマーです。このような挙動を実際に持つシステムを構築できれば、つまり、問題に投入するコンピュータの数をある係数だけ増やせば、その係数分だけ多くのスループット、より高い性能が得られるなら、

[24:14] システムから。それは大きな勝利です。なぜなら、コンピュータはお金で買えるからです。そうでしょう?一方、これに対する代替手段を得るには、ええと、より多くのパフォーマンスを得るために、プログラマにお金を払ってソフトウェアを再構築させ、より良いパフォーマンスを得るために、より効率的にし、何らかの専門的な技術やより良いアルゴリズムなどを適用させる必要があります。コードを速くするためにプログラマにお金を払わなければならないなら、

[24:44] それは費用のかかる方法です。10台のコンピュータの代わりに千台のコンピュータを買うだけで、100倍のスループットが得られれば素晴らしいです。それは素晴らしいことです。ですからこのスケーラビリティの考え方は、人々がコンピュータでいっぱいの建物で動く大規模なウェブサイトのようなものを構築するときに、頭の片隅にある巨大なアイデアです。コンピュータでいっぱいの建物がそれに対応する量のデータ性能を得るために存在するなら、実際にその性能を得るためには設計に注意しなければなりません。このコースで図を見たり図を書いたりするときによく見られる形は、ウェブサイトを構築していると仮定すると、

[25:26] 通常、ウェブサイトにはHTTPサーバーがあり、たとえばユーザーがいて、ウェブブラウザを動かしていて、PythonやPHPなどで動くウェブサーバーと通信します。そしてウェブサーバーは何らかのデータベースと通信します。ユーザーが一人か二人なら、両方を動かすコンピュータが一台あるか、ウェブサーバー用のコンピュータとデータベース用のコンピュータが一台ずつあるかもしれません。突然とても人気が出て、100百万人があなたのサービスに登録したらどうしますか。

[26:10] そうですよね?どうやって……いや。どうやって修正しますか——確かに、極めて注意深く労働集約的な最適化をしない限り、一台のコンピュータで何百万人もの人を支えることはできません。しかしそれには時間がありません。ですから通常、物事を速くする方法として最初にやることは、より多くのウェブサーバーを買い、ユーザーを分割して、ユーザーの半分か一部をウェブサーバー一に送り、残りの半分をウェブサーバー二に送ることです。

[26:40] そして、例えばRedditのようなものを作っているとして、すべてのユーザーが最終的に同じデータを見る必要があるなら、すべてのウェブサーバーをバックエンドと通信させます。そして、ここでは長い間ウェブサーバーを追加し続けられるかもしれません。ありがとうございます。ええと、ありがとうございます。ですので、これはウェブサーバーコードで並列スピードアップを得る方法です。PHPやPythonを動かしているなら、あまり効率的ではないかもしれません。ええと、個々のウェブサーバーがデータベースに過度の負荷をかけない限り、多くのウェブサーバーを追加できます。

[27:13] 問題が発生する前に。しかし、残念ながら、この種のスケーラビリティが無限であることはほとんどありません。うーん、真剣に考えなければ、決してそうではありません。そして、これらのシステムでよく起こるのは、10 台や 20 台、あるいは 100 台のウェブサーバーがすべて同じデータベースと通信するようになった後、ある時点で、突然データベースがボトルネックになり始めるということです。そして、ウェブサーバーをさらに追加しても、もはや役に立たなくなります。ですから、無限台のコンピューターを追加し続けることで完全なスケーラビリティを得られることは稀です。

[27:45] ある時点で、あなたは行き詰まります。なぜなら、コンピューターを追加している場所がもはやボトルネックではないからです。たくさんのウェブサーバーを持つことで、私たちは基本的にボトルネックを移動させます。うーん、ウェブサーバーからデータベースへのパフォーマンスを制限しているのだと思います。うーん、そしてこの時点で、実際にはほぼ確実に少し設計作業を行う必要があります。なぜなら、単一のデータベースを取って、何らかの形でリファクタリングするような簡単な方法があることは稀だからです。単一のデータベースに格納されたデータを取って、複数のデータベースに分割するようにリファクタリングすることはできます。

[28:21] うーん、しかし、それはしばしばかなりの作業量になります。そして、それは厄介だからです。しかし、多くの人が実際にこれを行う必要があります。うーん、このコースでは、分散システムがストレージシステムについて語っている例をたくさん見ることになります。なぜなら、著者たちは、単一のデータベースやストレージサーバーで行き詰まった大規模なウェブサイトのようなものを運営していたからです。うーん、とにかく、スケーラビリティの話は、私たちはこのようにスケールするシステムを構築するのが大好きですが、うーん、それを実現するのは難しい、あるいはしばしば作業、設計作業が必要で、このアイデアを無限に押し進めるのは大変だということです。

[29:04] アーメン。ありがとう。ありがとう。さて、それでは。よく出てくるもう一つの大きなトピックは、フォールトトレランスです。ありがとう。もし単一のコンピューターでシステムを構築しているなら、まあ、単一のコンピューターはしばしば何年も稼働し続けることができます。例えば、私のオフィスには何年もクラッシュせずに稼働し続けているサーバーがあります。うーん、コンピューターはかなり信頼性が高く、オペレーティングシステムもかなり信頼性が高く、どうやら私の建物の電源もかなり信頼性が高いようです。ですから、単一のコンピューターが驚くほど長い間稼働し続けることは珍しくありません。

[29:44] しかし、何千台ものコンピュータでシステムを構築している場合、各コンピュータが一年間稼働し続けると期待できたとしても、千台のコンピュータでは一日あたり約三回のコンピュータ故障が起こることになります。そしてコンピュータの集合の中で、大規模な分散システムで大きな問題を解くことは、非常に稀なフォールトトレランス、非常に稀な故障問題を、常に起こる故障問題に変えてしまいます。千台のコンピュータがあるシステムでは、ほぼ確実に常に何かが壊れています。常にどこかのコンピュータがクラッシュしているか、不思議なことに誤って動作しているか、遅く動いているか、間違ったことをしています。

[30:25] あるいは、ネットワークの一部、たとえば千台のコンピュータのようなものがあるかもしれません。ネットワークケーブルがたくさんあります。そしてネットワークスイッチもたくさんあります。ご存じのとおり、誰かが踏んでしまって信頼性が低くなったネットワークケーブルや、抜け落ちたネットワークケーブル、あるいはファンが壊れてスイッチが過熱して故障したネットワークスイッチが必ずあります。建物サイズの分散システムのどこかには、必ず何か小さな問題があります。つまり大規模化は、問題を、めったに起きない出来事でほとんど心配する必要がないものから、絶え間ない問題へと変えるのです。

[30:57] 障害は本当に、あるいは応答、障害のマスキング、障害を認識する能力は、設計に組み込まれていなければなりません。なぜなら、常に障害があるからです。うーん...そして、ご存知のように、アプリケーションプログラマーにとって便利な抽象化を構築することの一部として、私たちは本当に、可能な限りアプリケーションプログラマーから障害を隠すか、マスクするかするインフラストラクチャを構築できる必要があります。そうすれば、すべてのアプリケーションプログラマーが、発生しうるすべての異なる種類の障害について、完全で複雑な説明を持つ必要がなくなります。

[31:32] うーん、フォールトトレラントであることの意味について、さまざまな考え方があります。それについてもう少し。しかし、私たちがそれを正確にどういう意味で使うのか。そして、私たちは多くの異なる種類を見ることになりますが、より一般的な考え方の中には、可用性があります。ありがとう。アーメン。ですから、ご存知のように、一部のシステムは、ある種の障害、すべての障害ではありませんが、ある種の障害の下でも、損なわれていないサービスを提供しながら、障害にもかかわらず動作し続けるように設計されています。

[32:15] たとえ障害がなかったとしても、それが提供したであろうのと同じ種類のサービスです。つまり、その意味で可用なシステムもあります。ですから、たとえば二つのコピーを持つ複製サービスを構築した場合、一方のレプリカサーバーが故障しても、もう一方のサーバーは動作を続けられるかもしれません。もちろん両方が故障すれば、それはできません。その場合の可用性を約束することはできません。ですから可用なシステムは通常、ある一定の障害の集合のもとでは、サービスを提供し続ける、可用であり続けると言います。

[32:48] それ以上の障害が発生した場合。それはもはや可用性がありません。ありがとう。もう一つの種類のフォールトトレランスとして、可用性に加えて、あるいはそれ単独で、回復可能性があります。ありがとう。ありがとう。ありがとう。そしてこれが意味するのは、何か問題が発生した場合、サービスが動作を停止するかもしれないということです。つまり、単にリクエストへの応答を停止し、うーん、誰かが来て問題を修復するのを待ちますが、修復が行われた後は、システムは何も悪いことが起こらなかったかのように続行できるということです。

[33:23] つまりこれは可用性よりも弱い要件のようなものです。なぜならここでは、故障したコンポーネントが修理されるまで何も行わないからです。しかし、正確性を一切損なうことなく再び稼働できるという事実は、依然として重要な要件です。つまり、回復可能なシステムは通常、最新のデータをディスクに保存するなどして、電源が復旧した後にそれを取り戻せるようにする必要があるということです。ええと、そして可用性のあるシステムの中でも、実生活でシステムが役立つためには、通常、可用性のあるシステムが仕様化される方法は、ある数の故障が発生するまでは利用可能であるというものです。あまりに多くの故障が発生すると、可用性のあるシステムは動作を停止するか、まったく応答しなくなりますが、十分な数のものが修理されれば、動作を続けます。したがって、優れた可用性のあるシステムは、あまりに多くの故障が発生した場合には、ある意味で回復可能でもあります。

[34:26] 応答を返さなくなるかもしれませんが、その後は正しく動作を続けます。これこそ私たちが聞きたいことです。これこそ私たちが得たいものです。最大のハンマーとして、この問題を解決するためのいくつかのアプローチを見ていきます。この分野で私たちが持つ最も重要な道具は、二つあると言いました。一つは不揮発性ストレージです。何かがクラッシュした、電源が落ちた、あるいは建物全体の停電かもしれません。ハードドライブやフラッシュ、ソリッドステートドライブなどの不揮発性ストレージを使って、システムの状態のチェックポイントやログを保存し、電源が戻ったり誰かが電源を修理したりしたときに、ハードドライブから最新の状態を読み出してそこから続行できるようにします。

[35:22] つまり一つの道具は不揮発性ストレージです。そして不揮発性ストレージの管理はよく出てくる話題です。なぜなら不揮発性ストレージの更新は高くつく傾向があるからです。そのため、高性能なフォールトトレラントシステムを構築する際の細かい作業の大部分は、不揮発性ストレージへの書き込みをあまり行わずに済む巧妙な方法にあります。昔も今も、不揮発性ストレージへの書き込みとは、ディスクアームを動かし、ディスクプラッタが回転するのを待つことでした。

[35:58] そのどちらも、3ギガヘルツのマイクロプロセッサの尺度からすると、耐え難いほど遅いのです。フラッシュのようなものを使えば、かなりましになりますが、それでも良い性能を引き出すには多くの考慮が必要です。そしてフォールトトレランスのためのもう一つの大きな道具は複製です。ありがとう。そして複製コピーの管理はなかなか厄介です。システム状態の同一のコピーを持つはずの二つのサーバーがある、あらゆる複製システムに潜む問題です。

[36:32] 常に浮上する主要な問題は、二つのレプリカが誤って同期から外れ、レプリカでなくなってしまうことです。これは、複製を使ってフォールトトレランスを得るためにこれから見るあらゆる設計の背後にあります。そしてラボ2、それが皆さんの課題です。フォールトトレランスのための複製コピーの管理です。ご覧のとおり、かなり複雑です。最後の話題、最後の横断的な話題は一貫性です。

[37:11] ありがとう。ありがとう。一貫性とは何かを示す例として、分散ストレージシステムを構築していて、それがキーバリューサービスだとします。つまり二つの操作だけをサポートします。put操作があり、キーと値を渡すと、ストレージシステムはそのキーの値として値をしまい込み、キーと値の大きな表を維持します。そしてget操作があります。クライアントがキーを送ると、ストレージサービスはそのキーに保存された値を返すはずです。

[37:51] これは、分散システムの例として他に思いつかないときに私が持ち出すキーバリューサービスです。とても便利ですよね。ストレージシステムの基本的で単純なバージョンです。もちろん、アプリケーションプログラマーにとっては、この二つの操作に意味が結びついていると助かります。マニュアルを見れば、getを呼び出したときに何が返ってくるかが書かれています。

[38:23] そうです、そして put を呼び出すことがあなたにとって何を意味するかもです。ですから、それらが何を意味するかについて何らかの仕様があると素晴らしいでしょう。そうでなければ、put と get が何をすべきかの説明なしに、どうやってアプリケーションを書けるというのでしょうか。ええと、そしてこれが一貫性のトピックです。そして、これが分散システムで興味深い理由は、ええと、性能のためにもフォールトトレランスのためにも、フォールトトレランスの理由から、データのコピーが複数浮かんでいることがよくあるからです。つまり、単一のサーバーと単一のテーブルだけがある非分散システムでは、常にではないにしても、しばしば、

[39:02] putとgetが直感的に何を意味しうるかについては、たいていほとんど曖昧さがありません。putは表を更新すること、getは表に保存されているバージョンを取得することです。しかし、複製やキャッシュなどによってデータのコピーが複数ある分散システムでは、このキーバリューペアのさまざまなバージョンが多数存在するかもしれません。たとえばレプリカの一つで、あるクライアントがputを発行したとします。サーバーのコピーが二つあり、どちらもキーバリュー表を持っています。

[39:46] そしてキー一の値が両方で20だとします。ありがとう。そこであるクライアントがputを発行します。ここにクライアントがいて、putを送り、キー一の値を21に更新したいとします。このキーバリューサーバーで何かを数えているのかもしれません。そこでキー一、値21のputを送ります。ありがとう。それを最初のサーバーに送り、同じものを送ろうとしています。つまり両方のコピーを更新したいのですよね。

[40:19] それによって同期が保たれる。このputを送ろうとしているところだが、二台目のサーバーにputを送る直前にクラッシュする。電源障害、オペレーティングシステムのバグか何かだ。すると残念ながら残される状態は、このputを送ったので二つのレプリカの一方を値21に更新したが、もう一方はまだ20のままということになる。そこへ誰かが「get」で読みに来る。すると得られるのは……キー一に対応する値を読みたいのだが、21を得るかもしれないし20を得るかもしれない。どちらのサーバーと話すかによる。そして、常に上のサーバーと最初に話すという規則であっても、耐障害システムを構築するなら実際の規則はこうならざるを得ない。上のサーバーと最初に話す、ただしそれが故障した場合は下のサーバーと話す、と。

[41:00] ええと、いずれにせよ、いつかこの古いデータのコピーを将来のgetに晒す危険がある。多くのgetが更新された21を受け取った後、来週になって突然、あるgetが一週間前のデータのコピーを返すかもしれない。だからそれはあまり一貫していない。そうだろう?順序はともかく、そういうことは起こり得る。そうだろう?注意しなければ。レプリケーションによるこの危険を踏まえ、putとgetに関する規則を実際に書き下す必要がある。

[41:37] そして、一貫性には多くの異なる定義があり得ることが分かります。ええと、それらの多くは比較的単純です。多くはこう聞こえます:getは最も最近完了したputによって入れられた値を返す、と。はい。そしてそれは通常、強一貫性と呼ばれます。また、はるかに弱い一貫性を持つシステムを構築することも非常に有用であることが分かります。例えば、getが何も保証しないようなものです。

[42:11] 最も最近のputによって書き込まれた値を見ます。そしてその理由は、強一貫性システムは通常、getが最も最近のputを見るという何らかの形を持っています。私は思うのですが… 詳細を詰める必要があります。弱一貫性もあり、弱一貫性システムにはそのような保証を一切しない多くの種類があります。それについて。そして、例えば、誰かがputをした場合、そのputを見ないかもしれません。putによって更新されなかった古い値を、おそらく無制限の期間見るかもしれません。

[42:47] ええと、そして人々が弱一貫性スキームに非常に興味を持つ理由は、強一貫性、つまり読み取りが実際に最も最近のものを確実に見ることは、実装するのに非常に高価な仕様だからです。ええと、なぜならそれが意味するのはほぼ確実に、強一貫性の何らかの概念を実際に実装するために、誰かが大量の通信をしなければならないということだからです。複数のコピーがある場合、ええと、それは書き手か読み手、あるいは両方がすべてのコピーに問い合わせなければならないことを意味します。この場合のように、ええと、クライアントがクラッシュして一方を更新したが他方は更新しなかったかもしれません。

[43:29] このシステムで強い一貫性をたぶん簡単な方法で実装したいなら、読者に両方のコピー、あるいはコピーが複数あるならすべてのコピーを読ませ、見つけた中で最も新しく書かれた値を使うことになる。ええと、しかしそれは高くつく。一つの値を読むのに大量のやり取りが発生する。だから通信をできるだけ避けるために、特にレプリカが遠くにある場合は、このケースでは古い値の古い読み取りを実際に許すかもしれない弱いシステムを人々は構築する。

[44:01] ええと、これらの弱いスキームをより良くするために、しばしばより多くの意味論が付け加えられますが。そしてこの通信の問題、つまり強一貫性が高価な通信を要求することが本当に厄介になるのは、フォールトトレランスのためにレプリケーションを使っている場合、レプリカが独立した故障確率を持ち、無相関の故障を持つことを本当に望むからです。なので、例えばデータの両方のレプリカを同じラック、同じ機械室に置くのは、おそらく本当に悪い考えです。

[44:38] なぜなら誰かがそのラックの電源ケーブルにつまずけば、データの両方のコピーが死ぬからです。両方とも同じラックの同じ電源ケーブルに接続されているからです。ええと、なのでまともなフォールトトレランスを得るためにレプリカを故障に関してできるだけ独立させることを追求する中で、人々は異なるレプリカをできるだけ遠くに、例えば異なる都市に、あるいは大陸の反対側に置きたいと強く思います。そうすれば、あるデータセンターを破壊する地震が、他のコピーを持つ別のデータセンターも破壊する可能性は極めて低くなります。

[45:13] ええと、ご存知の通り、そうできれば理想的です。そうすると、もう一方のコピーは数千マイル離れており、光の速度の関係で、大陸を越えたデータセンターに通信してデータのもう一方のコピーを更新するには、ミリ秒または数十ミリ秒のオーダーがかかるかもしれません。そのため、強一貫性、良好な一貫性に必要な通信が潜在的に極めて高コストになります。これらのput操作を実行するたびに、あるいは実装方法によってはgetのたびに、データの両方のコピーと通信して両方が更新または確認されることを保証するために、10または20または30ミリ秒待つ必要があるかもしれません。

[45:57] 最新のコピーを見つけるために。ええと、そしてその途方もない費用、そうだろう?これは結局一秒間に十億命令も実行するマシンで10ミリ秒、20ミリ秒、30ミリ秒なのだ。だから待つ間に多くの潜在的な命令を無駄にしている。人々はしばしばはるかに弱いシステムを構築する。最も近いコピーだけを更新する、あるいは最も近いコピーだけを参照することが許される。今や、弱い一貫性保証をどう構造化すればアプリケーションにとって実際に有用になるか、また高い性能を実際に得るためにそれをどう活用するかについて、学術的にも実世界でも膨大な研究がある。

[46:35] ありがとうございます。では、これがこのコースの技術的なアイデアの電光石火的プレビューです。これについて何か質問はありますか?MapReduceについて話し始める前に。では、MapReduceに移りたいと思います。これは詳細なケーススタディの一種で、ここで話してきたアイデアのほとんどを実際に例示することになります。そしてそれが生み出すシステムは、ええと…

[47:06] もともとGoogleによって設計・構築・使用されたもので、論文は2004に遡ると思います。彼らが直面していた問題は、テラバイト単位の膨大なデータに対して巨大な計算を実行していたことです。ウェブのすべてのコンテンツのインデックスを作成したり、最も重要なページや最も権威のあるページを特定するためにウェブ全体のリンク構造を分析したりすることです。

[47:36] そして、ご存知の通り、ウェブ全体は—当時でさえ数十テラバイトのデータでした。ええと…ウェブのインデックスを構築することは、基本的にデータ全体をソートするようなものです。ソートは、ご存知の通り、まあ…かなり高コストです。そしてウェブの全コンテンツに対して単一のコンピュータでソートを実行するとしたら、どれくらいかかったか分かりませんが、ご存知の通り、数週間か数ヶ月か数年か、そんなところでしょう。ですから、当時のGoogleは、数千台のコンピュータ上で巨大なデータに対して巨大な計算を実行できることを切望していました。

[48:09] 計算が迅速に完了できるようにするためです。エンジニアが新聞を読んだりして大きな計算ジョブの完了を待つような時間をあまり費やさなくて済むように、たくさんのコンピュータを購入することは彼らにとって価値がありました。ええと…そしてしばらくの間、彼らは優秀なエンジニアに手書きで書かせていました、ご存知の通り、ウェブインデクサーや何らかのリンク、ウェブリンク分析ツールを書く必要があれば。ご存知の通り、Googleはコンピュータを購入し、「さあ、エンジニア諸君、好きなソフトウェアをこれらのコンピュータで実行してくれ」と言っていました。

[48:40] 彼らは取り組んでいる問題を何であれ、苦労して一種の一回限りの手書きソフトウェアを書いて、どうにかこうにかたくさんのコンピュータに振り分け、その計算を組織化し、データを取り戻していました。ええと、もし分散システムの専門家であるエンジニアだけを雇うなら、おそらくそれでも大丈夫かもしれませんが、それでもおそらくエンジニアリングの労力としては非常に無駄が多いでしょう。しかし彼らは何か別のことに熟練した人材を雇いたかったのです。ええと、そして必ずしも…

[49:13] ええと…分散システムのソフトウェアを書くことにすべての時間を費やしたいエンジニアばかりではありません。ですから彼らは本当に何らかのフレームワークを必要としていました。それによってエンジニアが、そう、やりたい分析の核心部分、たとえばソートアルゴリズムやウェブインデックスやリンクアナライザーなど、そのアプリケーションの核心部分だけを書けばよく、数千台のコンピュータ上で実行できるようにするものです。ええと、作業を数千台のコンピュータにどう分散させるか、必要なデータ移動をどう組織化するか、避けられない障害にどう対処するかといった詳細を気にすることなく。

[49:49] ですから彼らは、非専門家が巨大な分散計算を簡単に書いて実行できるようにするフレームワークを探していました。ええと、そしてそれがMapReduceのすべてです。アーメン。そしてアイデアは、プログラマはアプリケーションの設計者として、この分散計算の利用者として、単純なmap関数と単純なreduce関数を書くだけでよいということです。よし。分散について何も知らなくても。そしてMapReduceフレームワークが他のすべてを処理するのです。

[50:23] ええと、MapReduceがやろうとしていることの抽象的な見方はこうだ。何らかの入力があり、その入力が何らかの形で多数の異なるファイルやチャンクに分割されると仮定することから始まる。想像しているのは、入力ファイル一、入力ファイル二、入力ファイル三などがあるということだ。そしてこれらの入力はおそらく助けになる。

[50:53] ウェブからクロールされたウェブページ、あるいはもっとありそうなのは、たくさんのウェブファイルを含む大きなファイルで、それぞれがたくさんのウェブファイルを含んでいます。ウェブからクロールされたものです。よし、そしてMapReduceが始まる方法は、map関数を定義すると、MapReduceフレームワークが各入力ファイルに対してあなたのmap関数を実行するというものです。ありがとう。そしてもちろんここでお分かりのように、明らかな並列性がいくつかあります。

[51:25] mapを並列に実行できます。ですからこれらの各map関数は自分の入力だけを見て出力を生成します。map関数が生成することを要求される出力はリストです。ファイルを入力として受け取り、ファイルは入力データの何らかの一部であり、出力としてキーと値のペアのリストを生成します。map関数です。そしてたとえば、最も単純なMapReduceの例、単語カウントのMapReduceジョブを書いているとしましょう。目標は各単語の出現回数を数えることです。

[51:59] つまり、あなたのmap関数はキーと値のペアを出力するかもしれない。キーは単語で、値はただの一だ。目にするすべての単語について、このmap関数は入力を単語に分割する。目にするすべての単語について、その単語をキーとして、一を値として出力する。そして後でそれらすべての一を数え上げ、最終的な出力を得る。入力一には単語Aが含まれ、単語Bも含まれている。するとmapが生成する出力は、キーA、値1、キーB、値1となる。

[52:32] 二番目のマップの呼び出しは、中に a と b が入っていて他には何もないファイルを見るかもしれません。その場合、出力 B1 を実装することになります。三番目の入力には A と C が入っているかもしれません。よし、ではこれらのマップをすべての入力ファイルに対して実行します。すると、この中間結果が得られます。論文ではこれを中間出力と呼んでいます。これは各マップについて、出力としてのキーと値のペアの集合です。そして計算の第二段階は、reduce を実行することです。

[53:04] ありがとうございます。ええと、その考え方は、MapReduce フレームワークが各キーワードについて、すべてのマップからのすべてのインスタンスを集め合わせるというものです。つまり、MapReduce フレームワークは、すべてのマップから、キーが A であったすべてのキーと値のペアを集め、それらをすべて集めて、プログラマが定義した reduce 関数の*ノック音*一回の呼び出しに渡します。そして次に、すべての B を集め合わせます。もちろん、これは実際の収集を必要とします。なぜなら、キー B の異なるインスタンスは、異なるコンピュータ上でのマップの異なる呼び出しによって生成されたからです。ですから、ここで話しているのはデータの移動ではありません。

[53:50] ですから、すべての B キーを集めて、すべての B キーを引数として持つ、別の reduce の呼び出しに渡します。C についても同様で、すべての C を集めます。つまり、MapReduce フレームワークは、マップの出力のいずれかに現れたすべてのキーに対して、reduce の呼び出しを一回ずつ手配することになります。ええと、そして我々のちょっとばかげた単語カウントの例では、これらの reduce はすべて、あるいはそのうちのどれか一つがやらなければならないのは、渡された項目の数を数えるだけです。項目を実際に見る必要すらありません。なぜなら、それぞれの項目は――その単語が担当するもので、値としてプラス一が付いていることを知っているからです。それらの一を見る必要はなく、ただ数えるだけです。ですから、この reduce は、ええと、A と、それからカウントを生成します。

[54:43] その入力のうち、これがreduceします。それに関連するキーを生成し、次にその値の数を生成します。これもまた二です。ありがとう。ありがとう。ありがとう。これが典型的な…MapReduceジョブの見た目です。高レベルでは。念のため言っておくと、——失礼。ええと、少し用語の話をします。計算全体はジョブと呼ばれます。mapまたはreduceの一回の呼び出しはタスクと呼ばれます。つまり、ジョブ全体があり、それは多数のmapタスクから成り立っています。

[55:21] そして多数のreduceタスクです。ええと…では、この単語カウントの例で、map関数とreduce関数がどのようなものになるかの例です。ありがとうございます。ありがとうございます。ええと…ありがとうございます。ありがとうございます。map関数はキーと値を引数として取ります。そしてここで話しているのは、C++やJavaなど、普通のプログラミング言語で書かれた関数のことです。

[55:52] ええと、つまりこれは普通の人々が書ける単なるコードです。単語カウント用のmap関数がやることは、キーを分割することです。キーはファイル名で、通常は無視され、ファイル名が何であったかは実際には気にしません。そしてVは「このmapの入力ファイル」の内容です。つまりVにはこのすべてのテキストが含まれています。Vを単語に分割します。ありがとうございます。ありがとうございます。そして各単語について、ありがとうございます。

[56:24] *ノック* *ノック* *ノック* ただemitするだけです。そしてemitは二つの引数を取ります。mapだけが呼べるMITで、MITはMapReduceフレームワークによって提供されます。私たちは生成し、MITにキー、つまり単語を渡し、値、つまりByeを渡します。文字列の一です。map関数については以上です。MapReduceにおける単語カウントのmap関数は、文字通りこれほど単純であり得ます。

[56:56] ええと、では。彼らの一種の約束は…そして、ご存じのとおり、このmap関数は分散や複数のコンピュータ、ネットワークを介してデータを移動する必要があることなどについて何も知りません。これは極めて…単純明快です。そして単語カウント用のreduce関数は、ええと。reduceは次のように呼ばれます。各reduceは、あるキーのすべてのインスタンスとともに呼ばれることを覚えておいてください。MapReduceフレームワークは、それが担当するキーと、mapが生成したすべての値のベクトルをreduceに渡します。

[57:35] そのキーに関連付けられています。キーは単語で、値はすべて一であり、それら自体はあまり気にせず、いくつあったかだけを気にします。ええと。そして、reduceは最終出力としてemitされる値を取るだけの独自のemit関数を持っています。このキーの値として。なので、長さをemitします。ありがとう。この配列の。ありがとう。これもまた、MapReduceにおけるreduce関数がそうであるのとほぼ同じくらい単純です。つまり、極めて単純です。

[58:08] そしてフォールトトレランスやその他について何も知る必要がありません。よろしいですか、基本的なフレームワークについて質問はありますか。はい。そして…必須ではありませんが、これは何かを返すかもしれません。私はそれに取り組んでいます。フランス、フランス、フランスのように。MapReduceフレームワークを使って、たぶんそれはアクセス付きでreduceします。そのステップを何回か。reduceの出力を一種の…として供給できるのか、ということですか。ええ。

[58:43] ありがとう。ああ、はい。ああ、はい、現実では、いいですか。現実では、MapReduceの利用者の間では、ある入力を受け取ってある出力を生成するMapReduceジョブを定義し、次に二つ目のMapReduceジョブを持つことは日常茶飯事です。非常に複雑な多段階の分析や、反復アルゴリズム、たとえばPageRankのようなものをやっているならなおさらです。PageRankはGoogleがさまざまなウェブページの重要度や影響力を推定するために使うアルゴリズムです。それは反復アルゴリズムで、徐々にある答えに収束していきます。そしてそれをMapReduceで実装するなら、おそらく彼らが最初にそうしたのだと思いますが、MapReduceジョブを複数回実行しなければなりません。

[59:28] それぞれの出力は一種の…ご存じのとおり、ウェブページのリストで、各ウェブページの更新された一種の値や重み、重要度が付いています。ですからこの出力を取り、それを別のMapReduceジョブへの入力として使うことは日常茶飯事でした。永遠に続けることはできません。ああ、はい。そうです。すべての涙…「ええ、出力を一種の設定をする必要があり、reduce関数は一種のその知識を持って…」

[1:00:00] 生成物に会いましょう。次のMapReduceジョブに必要な情報を含む、またはその形式のデータです。つまり、これは実はMapReduceフレームワークのちょっとした欠点を浮き彫りにします。それは、素晴らしいということです。もしあなたが、ありがとう。もし実行する必要のあるアルゴリズムが、mapとそれに続くこの種の「キーによるデータのシャッフル、そしてreduce」として簡単に表現でき、それで終わりなら。MapReduceは、その形式に当てはめられるアルゴリズムにとっては素晴らしいものです。

[1:00:30] さらに、各mapは完全に独立している必要があります。引数だけを見て他には何も見ない、関数型の、純粋関数型の関数であることが要求されます。そして、ご存知の通り、それは制約のようなものです。そして、多くの人々が、実に多種多様な処理を含む、はるかに長いパイプラインを実行したいと考えていることが分かっています。そしてMapReduceでは、複数の、そしてMapReduceの、別個のmap生成ジョブからそれを寄せ集めなければなりません。そして、このコースの後半で話す、より高度なシステムは、計算の完全なパイプラインを指定できるようにするのがはるかに優れており、それらが最適化を行います。

[1:01:09] フレームワークは、あなたがしなければならないすべてのことを実現します。はるかに複雑なものを効率的に整理します。最適化します、はるかに複雑なものを。計算を。あなたの質問です。つまり、論文では、彼らはマッパーとmap関数を区別しています。それがおそらく、mapを実行しているプロセスです。何が...そして、プロセスは...プログラマの観点からは、それは単にmapとreduceについてです。

[1:01:43] 私たちの観点からは、それはワーカープロセスについてです。そして、とりわけ、MapReduceフレームワークの一部であるワーカーサーバーについてです。それらを生成物関数から呼び出します。それで...ええ、私たちの観点からは、これが周囲のフレームワークによってどのように組織されるかに大いに関心があります。これは、分散的なものをすべて取り除いた、いわばプログラマの視点です。ええ。はい?ありがとう。すみません、私は...

[1:02:21] もう一度言ってください。すみません、emitはローカルで行うのですか?ああ、emitされたデータはどこへ行くのか、という意味ですか。ありがとう。わかりました。では二つの質問があります。一つは…emitを呼ぶとデータはどうなるのか、もう一つは関数がどこで実行されるのか、です。では、ありがとう。ええと。実際の答えは、まず、ものはどこで実行されるのか。たとえば千台のサーバーがあります。実は、ここで見るべき正しいものは論文の図一です。

[1:02:59] ええと、ただし現実世界ではこの下に、サーバーの大きな集合があります。そしてええと。それらをワーカーサーバー、あるいはワーカーと呼びましょう。そして計算全体を組織する単一のマスターサーバーもあります。ここで起きているのは、マスターサーバーがいくつかの入力ファイル、つまり5,000個の入力ファイルがあることを知っており、mapの呼び出しをさまざまなワーカーに割り振るということです。つまり、ワーカー七にメッセージを送り、このmap関数をしかじかの入力ファイルに対して実行してください、と言うのです。

[1:03:39] そして、MapReduceの一部であり、MapReduceについてすべてを知っているワーカー関数は、ええと、ファイルを読み、入力を読み、どの入力ファイルであれそれを読み、そしてこのmap関数をファイル名の値を引数として呼び出します。そのワーカープロセスが、emitを実装するものです。そしてmapがemitを呼び出すたびに、ワーカープロセスはこのデータをローカルディスク上のファイルに書き込みます。

[1:04:11] では、mapのemitはどうなるのかというと、それらはmapワーカーのローカルディスク上にファイルを生成し、そのワーカー上で実行されたmapが生成したすべてのキーと値を蓄積します。ええ、それでmapフェーズの終わりには、残るのはそれらすべてのワーカーマシンであり、それぞれがそのワーカーマシン上で実行されたmapの出力の一部を持っています。そしてMapReduceのワーカーは、reduceに必要とされる場所へデータを移動させる手配をします。そして、典型的な大規模計算では、このreduceの連携にはキーAに言及したすべてのmap出力が必要になりますが、ご存知の通り、これは一種の単純な例ですが、おそらく一般には、すべてのmap呼び出しがキーAのいくつかのインスタンスを含む多数のキーを生成するでしょう。

[1:05:13] なので通常、順序として、このreduce関数を実行できるようになる前に、MapReduceフレームワーク、つまり千台のサーバーの一台で動いているMapReduceワーカーが、他の千台のサーバーすべてと話をしに行かなければなりません。「ねえ、キーAのreduceを実行するので、あなたのディスクに保存されている中間map出力を見て、キーAのすべてのインスタンスを拾い出してネットワーク経由で私に送ってください」と。なのでreduceワーカーはそうします。すべてのワーカーから取得します。

[1:05:44] 自分が担当する、マスターから担当するように言われたキーのすべてのインスタンスを。そして、そのデータをすべて集め終えると、reduceを呼び出すことができます。そしてreduce関数自体はreduce emitを呼び出しますが、これはmapのemitとは異なります。reduce emitが行うことは、出力をGoogleが使用するクラスタファイルサービス内のファイルに書き込むことです。ここで、私がまだ言及していないことがあります。

[1:06:15] ええ、入力がどこに存在するか、そして出力がどこに存在するかについて言及していませんでした。両方ともバイアルです。ええ、なぜなら入力のどの部分でも、どのワーカーサーバー上でも読み取れる柔軟性が欲しいからです。つまり、入力データを保存するために何らかのネットワークファイルシステムが必要です。ええ、そして実際、論文はGFS、つまりGoogle File Systemと呼ばれるこのものについて述べています。

[1:06:48] ええと、そしてGFSはクラスタファイルシステムです。そしてGFSは実際に、MapReduceを実行するのとまったく同じワーカーサーバーの集合上で動作します。そして入力は、GFSが自動的に、ええと、ご存知のとおり、これはファイルシステムなので、ファイルの読み書きができます。保存した大きなファイルを自動的に分割し、多数のサーバーにまたがって64メガバイトのチャンクに分けます。ですから、もし10テラバイトのクロールされたウェブページの内容があったとして、それをGFSに書き込むと、たとえ単一の大きなファイルとしてでも、GFSはその膨大なデータを自動的に64キロバイトのチャンクに分割し、すべてのGFSサーバー、つまりGoogleが利用可能なすべてのサーバーに均等に分散させます。

[1:07:32] そしてそれは素晴らしい、まさに必要なものです。もし次に、クロールされたウェブ全体を入力として取るMapReduceジョブを実行したいなら、データはすでにすべてのサーバーに均等に分割されて保存されています。つまり、mapワーカーは、千台のサーバーがあれば、千台のmapワーカーを起動し、それぞれが入力データの千分の一を読みます。そして千台のGFSファイルサーバーから並列にデータを読むことができるのです。

[1:08:02] それは…途方もない合計になります。読み取りスループットです。つまり、千台のサーバーの読み取りスループットです。ええ。ありがとう。mapを実行しています。では、GoogleはGFSを動かす物理マシンの集合と、MapReduceジョブを動かす別の物理マシンの集合を一つずつ持っているとお考えですか。二つ持っていると言っているのですか?

[1:08:37] わかりました。それらは必ずしもそうとは限りません。- そう、質問は、ここにあるこの矢印は実際に何を含むのか、ということです。ええと、そしてその答えは、Googleのこのシステム全体の進化に伴い、長年にわたって多少変わってきました。ご存知のとおり、最も一般的なケースでは、大きなファイルが何らかの大規模なネットワークファイルシステムに保存されている場合です。たとえば、GFSはAFSに少し似ていて、Athenaで使ったことがあるかもしれません。そこでは何らかのコレクションにアクセスしに行き、データは大規模なサーバーの集合に分割されていて、データを取得するにはネットワーク経由でそれらのサーバーにアクセスしなければなりません。

[1:09:13] ええと、その場合、この矢印が表すかもしれないのは、ありがとう、map、MapReduceワーカープロセスがネットワークを越えて、入力のその部分を保存している正しいGFSサーバー、あるいは複数のサーバーと通信しに行き、mapを実行するためにネットワーク経由でそれをMapReduceワーカーマシンに取得しなければならない、ということです。そしてそれは確かに最も一般的なケースです。そして最終的にはMapReduceが実際にそう動作するようになりました。しかしこの論文の世界では、そしてもしそうしたなら、それは大量のネットワーク通信になります。

[1:09:47] あなたは10テラバイトのデータについて話していて、そのあと10テラバイトをデータセンターのネットワークを越えて移動しなければなりません。それは…ご存知のとおり、データセンターネットワークは毎秒ギガビットで動作しますが、それでも数十テラバイトのデータを移動するには多くの時間がかかります。ありがとう。それを試みるために、そして実際にこの論文の世界では2004、彼らのMapReduceシステムにおける最も制約となるボトルネックはネットワークスループットでした。なぜなら彼らはネットワーク上で動作していて、評価のセクションまで読めばわかるように、彼らのネットワークは、彼らのネットワークはええと…

[1:10:23] 彼らは数千台のマシンを持っていて、ともかく、マシンを集め、マシンを、たとえば各ラックのマシンをそのラック用のイーサネットスイッチなどに接続していました。しかしその後、それらはすべて互いに通信する必要があります。しかしルートのイーサネットスイッチがあり、すべてのラックのイーサネットスイッチがそれと通信します。そして、ええと、なのでMapReduceワーカーとGFSサーバーを適当に選ぶと、少なくとも半分の確率で、それらの間の通信はこの一つのルートスイッチを通らなければなりません。彼らのルートスイッチにはある程度の総スループットしかなく、それは忘れましたが、ええと…毎秒何ギガビットかです。

[1:11:07] ええと、とにかく、数字は忘れましたが、私が割り算をしたとき、つまりルートスイッチで利用可能な総スループットを、論文の実験で使用されたおよそ2,000台のサーバーで割ったとき、私が得たのは、各マシンのルートスイッチの取り分、つまり総ネットワーク容量の取り分は、彼らの設定ではわずか50メガビット毎秒でした。字幕はAmara.orgコミュニティによる つまり50メガビット毎秒毎マシンです。

[1:11:39] そしてそれは多く見えるかもしれません、50メガビット、なんてこった、何百万も何百万も。しかしそれは、たとえばディスクやCPUが動作する速さと比べると、実際にはかなり小さいものです。そしてそう、彼らのネットワークでは、この50メガビット毎秒は途方もない制限のようなものでした。彼らは論文で説明されている設計において、ネットワークを使わないようにするために本当に逆立ちしていました。そして彼らは、可能な限りネットワーク経由で物を送るのを避けるために、たくさんのトリックを駆使しました。その一つは、彼らがGFSを実行したことです。

[1:12:12] サーバーです。そしてMapReduceワーカーを同じマシンの集合上で動かします。つまり千台のマシンを持ち、その千台のマシン上でGFSを実行し、GFSサービスを実装し、同じ千台のマシン上でMapReduceを実行します。そしてマスターがmap作業を分割し、さまざまなワーカーに割り振るとき、巧みに、次の質問に行きます。mapを実行しようとする直前で、入力ファイル一から読む予定だったなら、GFSからどのサーバーが実際に入力ファイル一をローカルディスクに保持しているかを突き止めるのです。

[1:12:50] そして、その入力ファイルのmapを同じマシン上のMapReduceソフトウェアに送りました。そうすることで、デフォルトでは、この矢印は実際にはローカルディスクからのローカル読み取りであり、ネットワークを関与させませんでした。そしてご存知のとおり、障害や負荷などに応じて、常にそうできるとは限りませんでした。しかしほとんどすべてのmapは、データを保存したまさに同じマシン上で実行され、それによって、そうでなければ入力データをネットワーク経由で移動するのを待たなければならなかった膨大な時間を節約しました。

[1:13:21] ええと、次に彼らが仕掛けたトリックは、先ほども述べたように、mapはその出力を、mapを実行するマシンのローカルディスクに保存するということです。ですから、繰り返しになりますが、mapの出力を保存することは、少なくとも出力がディスクに保存されるという理由から、ネットワーク通信を必要としません。しかし、私たちは確実に知っています。何らかの方法で、MapReduceが定義されている方法のすべてをまとめるために、与えられたキーに関連するすべての値をまとめて、あるマシン上で単一の呼び出しに渡して生成するためには、これはネットワーク通信を必要とするということです。

[1:13:59] 私たちは――ええと、私たちは――必要があるのは――私たちは それがAのすべてであり、それらを単一のマシンに渡すにはネットワークを介して移動させなければなりません。そして、このシャッフル、つまりキーのこの移動は、元々はmapを実行した同じマシン上でRoweによって保存されていた種類のものから行われます。私たちはそれらを本質的に、reduceを担当するマシン上で列ごとに保存する必要があります。この行ストレージから本質的に列ストレージへの変換は、論文ではシャッフルと呼ばれています。そしてそれは本当に、すべてのデータを移動させることを必要としました。

[1:14:30] ネットワークを介して。それを生成したmapから、私たちが必要としていたreduceへと。そしてそれがMapReduceの、ええと、高くつく部分でした。ええ。なぜ彼らはやらなかったのでしょうか? ある種、あなたが持っているように、あなたがあなたのものを保つような、何かを作らなかったのでしょうか。すでに持っている状態で。どれか一つを選べば、一晩中待つことになったでしょう。その通りです、あなたはよりストリーミング的なreduceを持つ、別の定義を想像することができます。よく考えたわけではありませんが、わかりません。なぜかはわかりません。それが実現可能かどうかは。確かにプログラマーインターフェースに関する限り、もし目標が、彼らの第一の目標が本当に、プログラミングを簡単にできるようにすることだったなら。

[1:15:11] システムの中で何が起こっているのか全くわかっていなかった人々によって。ですから、この仕様、これが本当にreduce関数の見た目なのかもしれません。C++か何かで。このストリーミング版は今、どう見えるかわかりませんが、こんなに単純ではないでしょう。しかし、ええと、多分そのようにできるかもしれません。そして実際、多くの現代のシステムでは、人々はずっと洗練されてきました。MapReduceの後継である現代のもので。そしてそれらは実際、この非常にバッチ的なアプローチではなく、しばしばデータのストリームを処理することを伴います。すべてのデータを取得するまで待ってから処理するという意味では、バッチ的アプローチです。

[1:15:55] ですからまず第一に、有限の入力という概念が必要になりますよね? そして現代のシステムは実際しばしばストリームを使います。そして... それによって何らかの効率性を活用することができます。ありがとう。しかしMapReduceはそうではありません。ありがとう。ええと... わかりました、つまりここがシャッフルのポイントで、すべてのネットワークトラフィックが発生する場所であり、これは実際に膨大な量のデータになり得ます。ですから、ソートを考えると、ソートしている場合、ソートの出力はソートへの入力と同じサイズです。つまり、入力が10テラバイトのデータで、ソートを実行しているなら、この時点で10テラバイトのデータをネットワーク経由で移動していることになります。

[1:16:37] そして出力もまた10テラバイトになり、これはかなりの量のデータであり、実際にすべてではありませんが多くのmap生成ジョブにとってそうです。これらの段階でデータ量を大幅に削減します。私は... 誰かが言いました、reduceの出力を別のMapReduceに供給したい場合はどうするのかと。そして実際、それはしばしば人々がやりたかったことでした。いずれにせよ、reduceの出力は、ソートやウェブインデックス作成のように、膨大になる可能性があります。それが生成する出力は10テラバイトの入力に対してです。reduceの出力は再び10テラバイトになるでしょう。ですからreduceの出力もGFSに保存されました。

[1:17:10] そしてシステムは――ええと、reduceはただこれらのキーと値のペアを生成するだけで、しかし、ありがとう。MapReduceフレームワークがそれらを集めて、GFS上の巨大なファイルに書き込みます。ええと、そして各reduceの出力を、その生成物を保存するために必要なGFSサーバーに届けるために、別のラウンドのネットワーク通信が必要でした。あなたは彼らが... reduceを実行したMapReduceワーカーをたまたま実行していたGFSサーバーに出力を保存するという、同じトリックを出力に対して使えたかもしれないと思うかもしれません。

[1:17:48] そしておそらく彼らはそうしたかもしれませんが、GFSはパフォーマンスのためにデータを分割するだけでなく、フォールトトレランスのために二つか三つのコピーを保持します。つまり、何があっても、データの一つのコピーをネットワーク経由で別のサーバーに書き込む必要があります。したがって、ここにもたくさんのネットワーク通信があり、ここにもたくさんあります。ええと、そしてこのネットワーク通信が本当に制限していたのは... 2004のThruppidimapidusです。ええと、2020では、このネットワーク配置がデータセンターで人々がやりたい多くのことにとって非常に制限的な要因であったためです。

[1:18:22] 現代のデータセンターネットワークは、ルートでこれよりもはるかに高速です。ええと、今日見られる典型的なデータセンターネットワークには、実際に多くのルートがあり、すべてが通過しなければならない単一のルートスイッチの代わりに、多くのルートスイッチがあり、各ラックスイッチはこれらの複製されたルートスイッチのそれぞれに接続し、トラフィックはルートスイッチ間で分割されます。したがって、現代のデータセンターネットワークははるかに多くのネットワークスループットを持っています。ええと、そのため、実際に、現代の-- 私はGoogleが数年前にMacrodeuceの使用をやめたと思いますが、ええと、彼らがそれをやめる前に。

[1:19:01] 現代のMapReduceは実際にもはやmapをデータが保存されていたのと同じマシン上で実行しようとはしません。彼らはネットワークが極めて高速であるとただ仮定していたので、どこからでもデータをロードして構わないと考えていました。わかりました。MapReduceの時間がなくなりました。来週の終わりにラボがあり、そこで皆さんは自分たちのやや簡略化されたMapReduceを書くことになります。では、それを楽しんでください。そして木曜日に会いましょう。

英語の原文字幕を見る

[0:01] All right, let's get started. This is 6824, distributed systems. Um, Thank you. So I'd like to start with just a brief explanation of what I think a distributed system is. Thank you. The core of it is a set of cooperating computers that are communicating with each other over network to get some coherent task done. The kinds of examples that we'll be focusing on in this class are things like storage for big websites, or big data computations such as MapReduce, Um, And also somewhat more exotic things like peer to peer file sharing.

[0:43] Those are all just examples of the kinds of case studies we'll look at. Um, And the reason why all this is important is that a lot of critical infrastructure out there is built out of distributed systems. Infrastructure that requires more than one computer to get its job done or sort of inherently needs to be spread out physically. Um. So the reasons why people build this stuff, First of all, before I even-- talk about distributed systems, I just want to remind you that If you're designing a system, you need to solve some problem, if you can possibly solve it, on a single computer.

[1:17] you know, without building a distributed system, you should do it that way. And there's many, many jobs you can get done on a single computer, and it's always easier. So distributed systems, you should try everything else before you try building distributed systems 'cause they're not simpler. So the reason why people are driven to use lots of cooperating computers are They need to get high performance. And the way to think about that is they want to get, achieve some sort of parallelism. Lots of CPUs, lots of memories, lots of disk arms moving in parallel.

[1:54] Another reason why people build this stuff is to be able to tolerate faults. Wow. . have two computers do the exact same thing. If one of them fails, you can cut over to the other one. Another is that some problems are just naturally spread out in space. Um, You want to do interbank transfers of money or something. Bank A has this computer in New York City, and Bank B has this computer in London.

[2:25] you know, you just have to have some way for them to talk to each other and cooperate in order to carry that out. So there's some natural sort of physical reasons systems that are inherently physically distributed, And the final reason that people build this stuff is in order to achieve some sort of security goal. So often by, if there's some code you don't trust, or you need to interact with somebody, They may be malicious or maybe their code has bugs in it. So you don't want to have to trust it. You may want to split up the computation so, you Your stuff runs over there on that computer, my stuff runs here on this computer, and they only talk to each other.

[3:03] to some sort of narrow, narrowly defined network protocol. So we may be worried about security, And that's achieved by splitting things up into multiple computers so that they can be isolated. Um. The-- Most of this course is going to be about performance and fault tolerance, although the other two often work themselves in by way of the sort of constraints on the case studies that we're going to look at. Um, You know, all the distributed systems of these problems are, because they have many parts and the parts execute concurrently, because there are multiple computers.

[3:42] You get all the problems that come up with concurrent programming, all the sort of complex interactions and weird timing dependent stuff. And that's part of what makes distributed systems hard. Another thing that makes... distributed systems hard is that Because again you have multiple pieces plus a network. you can have very unexpected failure patterns that is If you have a single computer, it's usually the case that either the computer works or maybe it crashes or suffers a power failure or something. But it pretty much either works or doesn't work.

[4:12] Distributed systems made up of lots of computers, you can have partial failures. That is, some pieces stop working, other pieces continue working. Or maybe the computers are working, but some part of the network is broken or unreliable. um So partial failures is another reason why uh... distributed systems are hard. So this is sort of basic challenges. Bye. Thank you. Thank you.

[4:44] Bye. Subtitles by the Amara.org community Thank you. Thank you. And a final reason why it's hard is that, you know, the original reason to build a distributed system is often to get higher performance. to get 1,000 computers worth of performance, or 1,000 disc arms, worth of performance. But it's actually very tricky to obtain that thousand X speed up with a thousand computers. There's often a lot of roadblocks thrown in your way. Um, Hello.

[5:15] Thank you. Thank you. It often takes a bit of careful design to... make the system actually give you the performance you feel you deserve. So solving these problems, of course, can be all about, you know, addressing these issues. Um, The reason to take the course is because often the problems and the solutions are quite just technically interesting and They're hard problems. For some of these problems, there's pretty good solutions known for other problems They're not such great solutions, no.

[5:46] Distributed systems are used by a lot of real world systems out there, big websites often involved. you know, vast numbers of computers that are, you know, put together as distributed systems. When I first started teaching this course, It was. distributed systems were something of an academic curiosity. You know, people thought, "Oh, you know At a small scale, they were used sometimes, and people felt that, oh, someday they'd be... might be important. but now particularly driven by the rise of giant websites.

[6:17] that have you know, vast amounts of data and entire warehouses full of computers, distributed systems in the last 20 years have gotten to be Very-- seriously important part of computing infrastructure. Okay. This means that there's been a lot of attention paid to them, a lot of problems have been But there's still quite a few unsolved problems. So if you're a graduate student or you're interested in research, There's a lot of problems yet to be solved in distributed systems You could look into his research.

[6:49] And finally, if you like building stuff, This is a good class because it has a lab sequence in which you'll construct some fairly realistic distributed systems focused on performance and fault tolerance. So you've got a lot of practice. building distributed systems and making them work. All right. Let me talk about course structure a bit before I... get started on real technical content. You should be able to find the course website.

[7:20] using Google. And on the course website is the lab assignments course schedule, and also linked to a Piazza where you can post questions, get answers. Um, The course staff, I'm Robert Morris, will be giving the lectures. I also have four TAs. You guys want to stand up and show your faces? Um, Thank you. The TAs are experts at in particular at solving the labs, They'll be holding office hours, so if you have Questions about the labs, you should go to office hours.

[7:54] or you could post questions to Piazza. Um, Thank you. The course has a couple of important components. Um, One is his lectures. There's a paper for almost every lecture. Thank you. Thank you. There's two exams. Thank you. Thank you. Thank you. Bye. There's the labs, programming labs, and Um, there's an optional final project that you can do instead of one of the labs.

[8:27] Thank you. Subtitles by the Amara.org community The lectures will be about big ideas in distributed systems. There will also be a couple of lectures that are more about sort of lab programming stuff. A lot of the lectures will be taken up by case studies, a lot of the way that I sort of try to bring out the um, content of distributed systems is by looking at papers some academic, some written by people in industry, describing real solutions to real problems.

[9:04] Um, These lectures actually would be videotaped. and I'm hoping to post them online so that you can that if you're not here, or you want to review the lectures, you'll be able to look at the videotape lectures. Amen. The papers, again, there's one to read per week. Most of them are research papers. Some of them are classic papers. Like today's paper, which I hope some of you have read on MapReduce. It's an old paper, but it was the beginning of, it spurred an enormous amount of interesting work, both academic and in the real world. So some are classic and some are more recent papers.

[9:38] sort of talking about more up-to-date research, what people are currently worried about. And from the papers, I'll be hoping to tease out what the basic problems are, what ideas people have had that might or might not be useful in solving distributed system problems, Um, We'll be looking at sometimes at implementation details in some of these papers. Because a lot of this has to do with actual construction of of software-based systems. And we're also going to spend a certain amount of time looking at evaluations. people evaluating how fault tolerant their systems by measuring them or people measuring how much performance or whether they got performance improvement at all.

[10:14] Um, So I'm hoping that you'll all read the papers before coming to class. The lectures are... maybe not gonna make as much sense if you haven't already read the lecture, because there's not enough time to both explain all the contents of the paper and have a sort of interesting reflection on what the paper means. online class you really gotta be papers before coming to class and hopefully one of the things you learn in this class is how to read a paper rapidly and efficiently, and skip over the parts that maybe aren't that important sort of focus on teasing out the important ideas.

[10:50] On the website, there's for every link to by the schedule, there's a question. that you should submit an answer for for every paper. I think the answers are due at midnight. And we also ask that you submit a question you have about the paper. Um, to the website in order both to give me something to think about as I'm preparing the lecture and if I have time I'll try to answer at least a few of the questions by email. And the question and the answer for each paper are due midnight. the night before.

[11:21] There's two exams, there's a midterm exam in class, I think on the last class meeting before, uh Spring break. Um, and there's a final exam during final exam week at the end of the semester. The exams are going to focus mostly on papers and the labs. and probably the best way to prepare for them as well as attending lecture and reading the papers. um a good way to prepare for the exams is to look at old exams.

[11:52] 20 years of old exams and solutions. And so you look at those and sort of get a feel for what kind of questions that I like to ask. And indeed, because we read many of the same papers, Inevitably, I ask questions each year that can't help but resemble questions asked in previous years. Thank you. The labs, there's four programming labs. The first one of them is due Friday next week. um They're...

[12:23] Thank you. Lab one is a... Thank you. A simple MapReduce lab. to implement your own version of the paper. in which I'll be discussing in a few minutes. Um, Lab two. involves using a technique called raft in order to get fault, in order to, sort of allow, in theory, allow any system to be made fault tolerant by replicating it and having this raft technique. manage the replication and manage sort of automatic cut over if there's a failed if one of the replicated servers fails.

[12:59] So this is RAF for fault tolerance. Um. Thank you. Subtitles by the Amara.org community *kiss* In lab three, you'll use your raft implementation in order to build a fault tolerant key value server. Thank you. Amen. Thank you. It'll be replicated and fault tolerant. And in lab four, you'll take your replicated key value server and clone it into a number of independent groups. and you'll split the data Um, in your key value storage system across all of these individual replicated groups to get parallel speed up.

[13:37] by running multiple replicated groups in parallel and you'll also be responsible for moving the various chunks of data between different servers as they come and go. without dropping any balls. what's often called a sharded, Bye. key values service. Bye. you Sharding refers to splitting up the data, partitioning the data. among multiple servers in order to get parallel speedup.

[14:10] um Thank you. If you want, instead of doing lab four, You can do a project of your own choice. And the idea here is if you have some idea for a distributed system you know, in the style of... some of the distributed systems we talk about in the class, if you have your own idea that you want to pursue, and you like to build something and measure whether it worked Explore your idea. you can do a project. Um, And so for a project, you'll pick some teammates because we require that projects are done and teams of two or three people.

[14:45] Nam. So like some teammates and send your project idea to us and we'll think about it and say yes or no and maybe give you some advice. um, And then if you go ahead and do, if we say yes, and you want to do a project, you do that instead of Lab 4, and it's do. at the end of the semester. You know, you'll... you should do some, uh, design work and build a real system, and then in the last day of class, you'll demonstrate your system. as well as handing in a short... sort of written report to us about what you built. And I posted on the website some some ideas which might or might not be useful for you to sort of spur thoughts about what projects you might build, but really the best projects are one where you have a good idea, for the project. And the idea is if you want to do a project, you should choose an idea that's sort of in the same vein as the systems that we're talk about in this class.

[15:40] Okay, back to labs. The lab grades that we give you, you hand in your lab code, and we run some tests against it, You're graded based on how many tests you pass. We give you all the tests that we use, so there's no hidden tests. So, If you influence the lab and it reliably passes all the tests, then chances are good, unless there's something funny going on, which there sometimes is. Chances are good that if your code passes all the tests when you run it, it'll pass all the tests when we run it. and you'll get a full score. So hopefully there'll be no mystery about what score you're likely to get.

[16:13] on the labs. Um, Let me warn you that Debugging these labs can be time consuming. Because they're distributed systems, and have a lot of concurrency and communication, Um, sort of strange, difficult to debug errors can crop up. You really ought to start the labs early. Don't leave them. A lot of trouble if you leave the labs to the last moment. You got to start early. If you're-- problems, please come to the TA's office hours.

[16:44] and please feel free to ask questions. about the labs on Piazza. And indeed, I hope if you know the answer that you'll answer people's questions on Piazza as well. All right. Any questions about the mechanics of the course? Yes? Bye. Yeah. Thank you. So the question is, how do these things factor into grade? I forget, but it's all on the...

[17:18] It's on the website under-- something. Um. I think it's the labs are the single most important. component. Thank you. Okay. Thank you. Um... All right, so this is a course about infrastructure. for applications. And so all through this course, there's going to be a sort of split in the way I talk about things between applications, which are sort of other people, the customer, somebody else writes.

[17:49] The applications are going to use the infrastructure that we're thinking about in this course. And so the kinds of infrastructure that tend to come up a lot. Thank you. Thank you. are storage Thank you. communication Thank you. and computation. And we'll talk about systems that provide all three of these kinds of infrastructure.

[18:19] Um, the storage Turns out that storage is going to be the one we focus most on because it's a very well-defined and useful abstraction. And thank you. usually fairly straightforward abstractions. So people know a lot about how to use and build storage systems and how to build sort of replicated fault tolerant high performance distributed implementations of storage. We'll also talk about some of our computation systems, like MapReduce for today.

[18:50] is a computation system. Um, And we will talk about communication some, but mostly from the point as a tool that we need to use to build distributed systems. Like computers have to talk to each other, over a network, you know, maybe you need reliability or something. And so we'll talk a bit about but we're actually mostly... consumers of communication. Um, If you want to learn about communication, systems as or how they work, that's more the topic of 6829. So for storage and computation, A lot of our goal is to be able to discover abstractions, Um, ways of simplifying the interface to these, Storage and computation distributed storage and computation infrastructure so that it's easy to build applications on top of it.

[19:41] And what that really means is that we need to, we'd like to be able to build abstractions that hide the distributed nature of these. of these systems. So the dream, which is rarely fully achieved, but the dream would be to be able to build an interface, That looks to an application as if it's a non distributed storage system just like a file system or something that everybody already knows how to program and has a pretty simple model semantics. We'd love to be able to build interfaces that look and act just like non-distributed, storage and computation systems, but are actually-- you know, vast, extremely high performance, fault tolerant, distributed systems underneath.

[20:23] Um. So we'd love to have abstractions. Thank you. Subtitles by the Amara.org community Thank you. And as you'll see as the course goes on, we sort of, you know only part of the way there. It's rare that you find an abstraction for a distributed version of storage or computation that has simple behavior, behaves just like Um, the non-distributed version of storage that everybody understands. People are getting better at this and...

[20:54] um We're going to try to study the ways in what people have learned about. building such abstractions. Okay. What kind of, what kind of, Topics show up as we're considering these abstractions. The first one, the first topic, general topic that we'll see a lot is in a lot of the systems we look at, have to do with implementation. Thank you. um So, for example, the kind of tools that you see a lot for for ways people learn how to build these systems are things like remote procedure call, whose goal is to mask the fact that we're communicating over an unreliable network.

[21:38] um Another kind of implementation A topic that we'll see a lot is threads. which are a programming technique, that allows us to harness multi-core computers, but maybe more important for this class, Threads are a way of structuring concurrent operations. in a way that's hopefully simplifies the programmer view of those concurrent operations. Um, And because we're gonna use threads a lot, it turns out we're gonna need to also just from an implementation level, spend a certain amount of time thinking about concurrency control, things like locks.

[22:18] Um. you Thank you. And the main place that these implementation ideas will come up in the class, there will touched on in many of the papers, but you're going to come face to face with all of this in a big way in the labs. You need to build distributors. you know, do the programming for distributed systems. These are like a lot of the sort of important tools beyond just sort of ordinary programming, Um, These are some of the critical tools that you'll need to use. I'm back. to build distributed systems.

[22:50] Another big topic that comes up in all the papers we're going to talk about is performance. Thank you. Bye. Thank you. Thank you. Um, Usually the high level goal of building a distributed system is to get what people call scalable speedup. So we're going to look in for scalability. And what I mean by scalability or scalable speedup is that If I have some problem that I'm solving with one computer, and I buy a second computer to help me execute my problem.

[23:30] If I can now solve the problem in half the time, or maybe solve twice as many problem instances. you know, per minute. on two computers as I had on one, then That's an example of scalability. Sort of. two times the computers or resources, um gets me two times the performance or throughput. And this is a huge hammer. If you can build a system that actually has this behavior, Namely that If you increase the number of computers you throw at the problem by some factor, You get that factor, more throughput, more performance.

[24:14] out of the system. That's a huge win. Because You can buy computers with just money. Right? Whereas if in order to get the alternative to this, Um, is that in order to get more performance, you have to pay programmers to restructure your software to get better performance, to make it more efficient, to apply some sort of specialized techniques, better algorithms or something. If you have to pay programmers, the fix your code to be faster.

[24:44] an expensive way to go. We'd love to be able to just, oh, buy a thousand computers instead of 10 computers and get You know, 100 times more throughput. That's fantastic. And so this sort of scalability idea is a huge idea in the backs of people's heads when they're like building things like big websites that run on a you know, building full of computers. If the building full of computers is there to get a sort of corresponding amount of data performance. you have to be careful about the design in order to actually get that performance. Um, So, often the way this looks when we're looking at diagrams or writing diagrams in this course is that That's supposing we're building a website.

[25:26] Ordinarily, you might have a website that you know, has a HTTP server, or let's say it has some has some users. um, running web browsers, And they talked to... you know, web server running Python or PHP or whatever, Sort of web server. And the web server talks to some kind of database. Um, You know, when you have one or two users, have one computer running both, or maybe a computer for the web server and a computer from the database, Maybe all of a sudden you get really popular and you You know, 100 million people sign up for your service.

[26:10] Right? How do you... No. How do you fix your-- you certainly can't-- support millions of people on a single computer, Um, except by extremely careful labor intensive optimization. Um, but you don't have time for. So, Typically the way you're going to speed things up, the first thing you do is buy more web servers and just split the users so that you know, half your users or some fraction of the user go to web server one and the other half You send them to web server two.

[26:40] and because maybe you're building I don't know what, Reddit or something, where all the users need to see the same data ultimately, you have all the web servers talk to the back end. And maybe you can keep on adding web servers for a long time here. Thank you. Um, Thank you. And so this is a way of getting parallel speed up on the web server code. You know, if you're running PHP or Python, maybe it's not too efficient. Um, Uh, as long as each individual web server doesn't put too much load on the database, you can add a lot of web servers.

[27:13] before you run into problems. But. this kind of scalability is rarely infinite, unfortunately. um Certainly not without serious thought. And so what tends to happen with these systems is that at some point after you have 10 or 20 or 100 web servers all talking to the same database, Now all of a sudden the database starts to be a bottleneck. and adding more web servers no longer helps. So it's rare that you get full scalability through sort of infinite numbers of adding infinite numbers of computers.

[27:45] At some point you run out of gas because The place at which you are adding more computers is no longer the bottleneck. by having lots and lots of web servers, we basically move the bottleneck Um, I think it's limiting performance from the web servers to the database. Um, And at this point, actually, you almost certainly have to do a bit of design work. because It's rare that you can take, that there's any straightforward way to take a single database and sort of refactor things. with it for. you can take data sorted in a single database and refactor it so it's split over multiple databases.

[28:21] Um, but it's often a fair amount of work. and Because it's awkward, but many people actually need to do this. Um, We're going to see a lot of examples in this course in which the distributed system people talking about is a storage system. because the authors were running You know, something like a big website that ran out of gas on a single database or storage servers. Um, Anyway, so the Scalability story is we love to build systems that scale this way, but um you know it's hard to make it, or it takes work often, design work, push this idea infinitely far.

[29:04] Amen. Thank you. Thank you. Okay, so. Another big topic that comes up a lot is fault tolerance. Thank you. . If you're building a system with a single computer in it, well, A single computer often can stay up for years. Like, I have servers in my office that have been up for years without crashing. Um, You know, the computer's pretty reliable, the operating system's pretty reliable, Apparently the power in my building is pretty reliable. So it's not uncommon to have single computers that just stay up for amazing amounts of time.

[29:44] However, If you're building systems out of thousands of computers, then even if each computer can be expected to stay up for a year, With a thousand computers that means you're gonna have like about three computer failures per day. And in your set of computers. solving big problems with big distributed systems turns sort of very rare fault tolerance, very rare failure problems, into failure problems that happen just all the time. In a system with a thousand computers, there's almost certainly always something broken. There's always some computer that's either crashed or mysteriously running incorrectly or slowly or doing the wrong thing.

[30:25] Or maybe there's some piece of the network, like with a thousand computers, We got a lot of network cables. and a lot of network switches. You know, there's always some network cable that somebody stepped on and is unreliability, or network cable that fell out, or some network switch whose fan is broken and the switch overheated and failed. There's always some little problem somewhere in your building-sized um, distributed system. So Big scale turns problems from very rare events, you really don't have to worry about that much, into just constant problems.

[30:57] The... failure has to be really, or the response, the masking of failures, the ability to perceive about failures just has to be built into the design. because there's always failures. Um... And, you know, as part of building, you know, convenient abstractions for application programmers, We really need to be able to build infrastructure that as much as possible hides the failures from application programmers or masks them or something. so that every application programmer doesn't have to have a complete complicated story for all the different kinds of failures that can occur.

[31:32] Um, there's a bunch of different notions that you can have about what it means to be fault tolerant. about a little more. but exactly what we mean by that. And we'll see a lot of different flavors, but among the more common ideas you see, one is availability. Thank you. Amen. So, you know, some systems are designed so that under, some certain kinds of failures, not all failures, but certain kinds of failures, the system will keep operating despite the failure while providing undamaged service.

[32:15] Uh, the same kind of service it would have provided, even if there had been no failure. So some systems are available in that sense, So if you build a replicated service that maybe has two copies, You know, if one of the replicas replica servers fail fails, maybe the other server can continue operating They both fail, of course, you can't. You know, you can't promise. Um. availability in that case. So available systems usually say, well, under a certain set of failures, We're going to continue providing service. We're going to be available.

[32:48] More failures than that occur. It won't be available anymore. Thank you. Another kind of fault tolerance you might... you might have or in addition to availability or by itself is recoverability. Thank you. Thank you. Thank you. And what this means is that if something goes wrong, maybe the service will stop working. That is it all. simply stopped responding to requests, Um, and it'll wait for someone to come along and repair whatever went wrong, but after the repair occurs, the system will be able to continue as if nothing bad had gone wrong.

[33:23] So this is sort of a weaker requirement than availability, because here we're not going to do anything while until the failed component has been repaired, But the fact that we can get up get going again without, you know, but... without any loss of correctness, is still a significant requirement. It means, you know, recoverable systems typically need to do things like save their latest date on disk or something where they can get it back you know, after the power comes back up. Um, And even among available systems, In order for a system to be useful in real life, Usually what the way available systems are specced is that They're available until Some number of failures have happened. If too many failures have happened, an available system will stop working or will stop responding at all, But when enough things have been repaired, it'll continue operating. So a good available system will sort of be recoverable as well in the sense that if too many failures occur,

[34:26] um It'll stop answering, but then we'll continue correctly after that. Um, So this is what we love to hear. This is what we'd like to obtain. The biggest hammer, we'll see a number of approaches to solving these problems. I said, sort of Two things that are the most important. tools we have in this department. One is non-volatile storage. so that, you know, something crashed, power failed, or whatever, Maybe there's a building-wide power failure. We can use non-volatile storage like hard drives or flash or solid state drives or something to sort of store a checkpoint or a log the uh state of the system and then when the power comes back up or somebody repairs our power supply, who knows what, we'll be able to read our latest state off the hard drive and continue from there.

[35:22] So. So one tool is sort of non-volatile storage. And the management of non-volatile storage is something that comes up a lot, because non-volatile storage tends to be expensive to update. And so a huge amount of the sort of nitty-gritty of building sort of high performance fault-tolerant systems is in clever ways to avoid having to write the non-volatile storage too much. In the old days and even today you know, what writing non-volatile storage meant was, moving a disc arm and waiting for a disk platter to rotate.

[35:58] both of which are agonizingly slow. on the scale of, you know, 3 gigahertz microprocessors. With things like flash. Life's quite a bit better, but still requires a lot of thought to get good performance out of it. And the other big tool we have for fault tolerance is replication. Thank you. and the management of replicated copies is sort of tricky You know, that sort of problem lurking in any replicated system where we have two servers each with a supposedly identical copy of the system state.

[36:32] Um, The key problem that comes up is always that the two replicas will accidentally drift out of sync and will stop being replicas. And this is just-- you know, at the back of every design that we're gonna see for using replication to get fault tolerance. And Lab 2, and that's what you're all about. management of replicated copies for fault tolerance. Um. As you'll see, it's pretty complex. Um, A final topic, final cross-cutting topic, um is consistency.

[37:11] Thank you. Thank you. So as an example of what I mean by consistency supposing we're building a distributed storage system and it's a key value service so it just supports. two operations, maybe there's a put operation, and you give it a key, and a value and the storage system sort of stashes away the value under as the value for this key, so it maintains just a big table of keys and values. And then there's a get operation. the client sends it a key and the storage service is supposed to respond with the value that's stored for that key.

[37:51] And this is kind of the When I can't think of anything else as an example of a distributed system, I'll whip uh, key value services. And they're very useful, right? They're just sort of the fundamental Um, simple version of a storage system. So. Of course if you're an application programmer. It's helpful if... These two operations kind of have meanings attached to them. You can go look in the manual and the manual says you know, what it what it means, what you'll get back if you call get.

[38:23] right, and sort of what it means for you to call put So it would be great if there was some sort of spec for what they meant, otherwise, like, How can you possibly write an application without a description of what Pudding getters are supposed to do. Um, And this is the topic of consistency. And the reason why it's interesting in distributed systems is that Um. both for performance and for fault tolerant reasons, fault tolerance reason, we often have more than one copy of the data floating around. So, you know, in a non-distributed system where you just have a single server with a single table, there's often, although Not always.

[39:02] There's often relatively no ambiguity about what put and get could possibly mean intuitively. You know, what put means is update the table, and what get means is just, get me the version that's stored in the table, Um, But in a distributed system, where there's more than one copy of the data, due to replication or caching or Who knows what? There may be lots of different versions um of this key value pair floating around. Like if one of the replicas, you know, supposing some client issues a put, and You know, there's-- two copies of the The server, so they both have a key value table.

[39:46] Right, and maybe key one has value 20 on both of them. Thank you. and then some client issues a put. We have a client over here. and it's gonna send a put, it wants to update the value of one to be 21. Maybe it's counting stuff in this Key value server, so it sends a put Thank you. with key one and value 21, it sends it to the first server and it's about to send The same, you know, it wants to update both copies, right?

[40:19] It keeps them in sync. It's about to send this put, but just before it sends the put to the second server, it crashes. power failure, bug in operating system or something. So now the state we're left in, sadly, is that we sent this put and so we've updated one of the two replicas to have value 21, but the other one's still with 20. Now somebody comes along and reads with a "get" And they might get... They want to... Read the value associated with key one, they might get 21 or they might get 20, depending on who they talk to. And even if the rule is you always talk to the top server first, If you're building a fault tolerance system, the actual rule has to be Oh, you talk to the top server first, unless it's failed, in which case you talk to the bottom server.

[41:00] Um, So either way, someday you risk exposing this stale copy of the data. to some future get. It could be that many gets get the updated 21 and then Like next week, all of a sudden, some get yields, you know, a week old copy of the data. So that's not very consistent. Right? in order, but you know, it's, the kind of thing that could happen. Right? and we're not careful. We need to actually write down what the rules are going to be about puts and gets given this danger of due to replication.

[41:37] And it turns out there's many different the definitions you can have of consistency. Um, Many of them are relatively straightforward. Many of them sound like, well, I get yields the you know, value put by the most recently completed put. All right. And so that's usually called strong consistency. It turns out also it's very useful to build systems that have much weaker consistency. That for example, do not guarantee anything like I get it.

[42:11] sees the value written by the most recent put. And the reason, so there's strongly consistent systems - - They usually have some version of get seeing most recent puts. I think you have to... There's a lot of details to work out. There's also weakly consistent, many sort of flavors of weakly consistent systems that do not make any such guarantee. on that. and it may guarantee you well you know, if, someone does a put, then you may not see the put. You may see old values that weren't updated by the put for an unbattered amount of time maybe.

[42:47] Um, And the reason for-- people being very interested in weak consistency schemes. is that Strong consistency, that is, having RIS actually see, be guaranteed to see the most recent right. That's a very expensive spec to implement. um because what it means is almost certainly that you have to, somebody has to do a lot of communication in order to, actually implement. some notion of strong consistency. If you have multiple copies, Um, It means that either the writer or the reader, or maybe both, has to consult every copy. Like in this case, um where maybe a client crashed, left one updated, but not the other.

[43:29] If we wanted to implement strong consistency in maybe a simple way in this system, we'd have readers read both of the copies or if there's more than one copy, all the copies. and use the most recently written value that they find. Um. but that's expensive. That's a lot of chit chat. to read one value. So in order to avoid communication as much as possible, Um. particularly if replicas are far away, people build weak systems that might actually allow the stale read of an old value in this case.

[44:01] Um, although there's often more semantics attached to that to try to make these weak schemes And where this communication problem, you know, strong consistency. requiring expensive communication. Where this really runs you into trouble is that If we're using replication for fault tolerance, then We really want the replicas to have independent failure probability, to have uncorrelated failure. So, for example, putting both of the replicas of our data in the same rack, in the same machine room, is probably a really bad idea.

[44:38] because if someone trips over the power cable to that rack, both of our copies of our data are gonna die. Because they're both attached to the same power cable on the same rack. Um, So in the search for making replicas as independent in failure as possible in order to get decent fault tolerance, People would love to put different replicas as as far apart as possible, like in different cities. or maybe on opposite sides of the continent. So an earthquake that destroys one data center will be extremely unlikely to also destroy The other data center that has the other copy.

[45:13] Um, You know, so we'd love to be able to do that. If you do that, then the other copy is thousands of miles away, And the rate at which light travels means that it may take on the order of milliseconds or tens of milliseconds to communicate to a data center across the continent in order to update the other copy of the data. And so that makes this The communication required for strong consistency, for good consistency, potentially extremely expensive. Like every time you want to do one of these put operations, or maybe a get, depending on how you implement it, You might have to sit there waiting for like 10 or 20 or 30 milliseconds in order to talk to both copies of the data to ensure that they're both updated or both checked.

[45:57] to find the latest copy. Um, And That tremendous expense, right? This is 10 or 20 or 30 milliseconds on machines that, after all, will execute like a billion instructions per second. So we're wasting a lot of potential instructions while we wait. People often build much weaker systems. You're allowed to only update the nearest copy or only consult the nearest copy. Now, I mean, there's a huge sort of amount of academic and real world. research on had us. structure weak consistency guarantee so they're actually useful to applications and how to take advantage of them in order to actually get high performance.

[46:35] Thank you. All right, so that's a lightning preview of the... technical ideas in the course. Any questions about this? before I start talking about MapReduce. All right, I want to switch to MapReduce. That's a sort of detailed case study that's actually going to illustrate most of the ideas. that we've been talking about here. And that produces a system that was Uh...

[47:06] originally designed and built and used by Google, I think the paper dates back to 2004. The problem they were faced with was that they were running huge computations on terabytes and terabytes of data. creating an index of all of the content of the web or analyzing the link structure of the entire web in order to identify the most important pages or the most authoritative pages.

[47:36] And so, you know, the whole web is-- was even in those days tens of terabytes of data. Um... Building an index of the web is basically equivalent to a sort running sort of the entire data. Sort, you know, it's like... reasonably expensive. and to run a sort on the entire content of the web on a single computer I don't know how long it would have taken, but you know, weeks or months or years or something. So, Google at the time was desperate to be able to run giant computations on giant data on thousands of computers.

[48:09] in order that the computations could finish rapidly. It was worth it to them to buy lots of computers so that their engineers wouldn't have to spend a lot of time reading the newspaper or something waiting for their big compute jobs to finish. Um... And so for a while, they had their clever engineers sort of hand write, you know, if you needed to write a web indexer or some sort of link, web link analysis tool. you know, Google bought the computers and they say, "Here, engineers, you know, do--run whatever software you like on these computers."

[48:40] they would laboriously write the sort of one-off manually written software to take whatever problem they were working on and sort of somehow farm it out to a lot of computers and organize that computation and get the data back. Um, If you only hire engineers who are skilled distributed systems experts, Maybe that's OK, although even then, it's probably very wasteful of engineering effort. But they wanted to hire people who were skilled at something else. Um, And not necessarily...

[49:13] Um... engineers who wanted to spend all their time writing distributed system software. So they really needed some kind of framework that would make it easy to just, have their engineers Right? the kind of guts of whatever analysis they wanted to do, like sort algorithm or web index or link analyzer or whatever. Just write the guts of that application and not run, be able to run it on a thousands of computers. um without worrying about the details of how to spread the work over the thousands of computers, how to organize whatever data movement was required, how to cope with the inevitable failures.

[49:49] So they were looking for a framework that would make it easy for non-specialists to be able to write and run giant distributed computations. Um, And so that's what MapReduce is all about. Amen. And the idea is that the programmer just write the application designer, consumer of this distributed computation and just be able to write a simple map function and a simple reduce function, Good. don't know anything about distribution. and the MapReduce framework would take care of everything else.

[50:23] Um, So an abstract view of what MapReduce is up to is It starts by assuming that there's some input and the input is split up into some a whole bunch of different files or chunks in some way. We're imagining that You know, We have input file one, input file two, input file three, Etc. You know, and these inputs are maybe Help.

[50:53] web pages crawled from the web or more likely sort of big files that contain many web--each of which contains many web files. crawl from the web. All right, and the way MapReduce starts is that you define a map function and the MapReduce framework is going to run your map function on each of the input files. you Thank you. And of course you can see here there's some obvious parallelism available.

[51:25] can run the maps in parallel. So each of these map functions only looks at its input and produces output. The output that a map function is required to produce is a list. Takes a file as input and a file as some fraction of the input data, and it produces a list of key value pairs as output. the map function. And so, for example, let's suppose we're writing the simplest possible MapReduce example, a word count MapReduce. job, who's is The goal is to count the number of occurrences of each word.

[51:59] So your map function might emit key value pairs where the key is the word, and the value is just one. So for every word it sees, so this map function will split the input up into words. For every word it sees, it emits that word as the key and one as the value. And then later on we'll count up all those ones. in order to get the final output. Input one has the word. A in it. and the word B in it. And so the output the map is going to produce is Key A value 1, key B value 1.

[52:32] Maybe the second map indication sees a file that has a a b in it and nothing else so it's going to implement output B1, Maybe this third input has an A in it. and a C in it. All right, so we run all these maps on all the input files. And we get this intermediate, what the paper calls intermediate output. which is for every map, a set of key value pairs as output. Then the second stage of the computation is to run the reduces.

[53:04] Thank you. Um, And the idea is that the MapReduce framework collects together all instances from all maps of each keyword. So the MapReduce framework is going to collect together all of the A's you know, from every map, every key value pair whose key was A, it's gonna take Collect them all. and hand them to *knocking* one call of the programmer-defined reduce function. And then it's going to take all the bees and collect them together. Of course, it requires real collection because they were different instances of Key B were produced by different indications of map on different computers. So we're not talking about data movement.

[53:50] So we're going to collect all the B keys and hand them to a different call to reduce that's has all of the B keys. as its arguments, and same with C, all the C's. So this is gonna be the MapReduce framework will arrange for one call to reduce for every key that occurred in Amen. any of the map output. Um, And for our sort of silly word count, example all these reduces have to do or any one of them has to do is just count the number of items passed to it. It doesn't even have to look at the items because it knows that each of them is--the word is responsible for plus one as the value. You don't have to look at those ones, we just count them. So this reduce is gonna produce Um, A and then the count.

[54:43] Of its inputs, this reduce. It's gonna produce the key associated with it and then count of its values, which is also two, Thank you. Thank you. Thank you. So this is what a typical... MapReduce job looks like. the high level. Just for completeness, the--I'm sorry. Well, a little bit of terminology. The whole computation is called the job. any one invocation of map or reduce is called a task. So we have an entire job and it's made up of a bunch of map tasks.

[55:21] and then a bunch of reduced tasks. Um... So an example for this word count, you know, what the map and reduce functions would look like. Thank you. Thank you. Um... Thank you. Thank you. The map function takes a key and a value as arguments. And now we're talking about functions like written in an ordinary programming language like, C++ or Java or who knows what.

[55:52] um So this is just code ordinary people can write. What a map function for word count would do is split the key is the file name, which typically is ignored, we don't really care what the file name was. And the V is the content of "this maps input file." So V just contains all this text. We're going to split V into words. Thank you. Thank you. And then for each word, Thank you.

[56:24] *knocking* *knocking* *knocking* We're just gonna emit. And emit takes two arguments. MIT's call only map can make, and MIT is provided by the MapReduce framework. We get to produce, we hand a MIT a key, which is the word... and a value which is Bye. string one. So that's it for the map function. A word count map function in MapReduce literally could be this simple.

[56:56] Um, So. their sort of promise to make the And, you know, this map function doesn't know anything about distribution or multiple computers the fact we need to move data across the network, or who knows what. This is extremely... straightforward. And the reduce function for... word count um The reduce is called with Remember each reduce is called with sort of all the instances of a given key on the MapReduce framework calls reduce with a the key that it's responsible for and a vector of all the values that the maps produced.

[57:35] associated with that key. The key is the word, the values are all ones, we don't really care about them, we only care about how many there were um And so, reduce has its own emit function that just takes a a value to be emitted as the final output. as the value for the This key. So we're going to admit the length. Thank you. of this array. Thank you. So this is also about as simple as reduced functions are. in MapReduce, namely, Extremely simple.

[58:08] and requiring no knowledge about fault tolerance or Anything else? All right, any questions about... The basic framework, yes. and not... necessary but this might return something. I'm at it. Like France, France, France. using the MapReduce framework that maybe it's reduce with access. that step some number of times. You mean can you feed the output of the reduces sort of-- Yeah.

[58:43] Thank you. Oh, yes. Oh yes, in real life, all right. In real life, it is routine among MapReduce users to you know, define a MapReduce job that took some inputs and produced some outputs and then have a second MapReduce job, you know, if you're doing some very complicated multi-stage analysis. or iterative algorithm. like PageRank, for example, which is the algorithm Google uses to sort of, Estimate how important or influential different web pages are. That's an iterative algorithm is sort of gradually converges on an answer. And if you implement a MapReduce, which I think they originally did, You have to run the MapReduce job multiple times.

[59:28] The output of each one is sort of-- you know, list of web pages, with an updated sort of value or weight or importance for each web page. So it was routine to take this output and then use it as the input to another MapReduce job. We can't do it forever. Oh yeah. it is. all the tears "Well, yeah, you need to sort of set things up the output, you need to-- the reduced function sort of in the knowledge though.

[1:00:00] Meet the produce. data that's in the format or has the information required for the next MapReduce job. I mean, this actually brings up a little bit of a shortcoming in the MapReduce. framework, which is, it's great. if you're Thank you. if the algorithm you need to run is easily expressible as a map followed by this sort of "shuffling of the data by key, followed by a reduce, "and that's it." MapReduce is fantastic for algorithms that can be cast in that form.

[1:00:30] And furthermore, each of the maps has to be completely independent. required to be uh... functional, pure functional functions that just look at their arguments and nothing else. And you know, that's like, it's a restriction. And it turns out that many people want to run much longer pipelines that involve lots and lots of different kinds of processing. And with MapReduce, you have to sort of cobble that together from multiple--and MapReduce. distinct map-produced jobs. and more advanced systems, which we will talk about later in the course, are much better at allowing you to specify the complete pipeline of computations, and they'll do optimization.

[1:01:09] the framework realizes all the stuff you have to do. organize much more complicated efficiently. optimize, much more complicated. Computation. Your question. So in the paper, they distinguish between mappers and map functions. I guess that's the-- like the processes that are running the map. What are the... and welcome the processes that are-- From the programmer's point of view, it's just about map and reduce.

[1:01:43] From our point of view, it's gonna be about the worker processes. and the worker servers that that are part of MapReduce framework, among many other things. call them out from produce functions. So-- um Yeah, from our point of view, we care a lot about how this is organized by the surrounding framework. This is sort of the programmers view with all the distributed stuff stripped out. Um. Yes? Thank you. Sorry, I got to...

[1:02:21] Say it again. Sorry, do you emit locally? Oh, you mean where does the emit data go? Thank you. Okay, so there's two questions. One is... When you call emit, what happens to the data? and the other is where the functions run. So, Thank you. Um. The actual answer is that First, where does the stuff run? There's a number of, say, a thousand servers. Actually, the right thing to look at here is figure one in the paper.

[1:02:59] Um, Though sitting underneath this in the real world, there's some big collection of servers. And Um. We'll call them maybe worker servers or workers. And. There's also a single master server that's organizing the whole computation. And what's going on here is the master server knows that there's some number of input files, you know, 5,000 input files. and it farms out invocations of map to the different workers. So it'll send a message to worker seven saying, please run this map function on such and such an input file.

[1:03:39] And then the worker function which is, you know, part of MapReduce and knows all about MapReduce, well then, Um, Read the file, read the input, whatever, whichever input file. and call this map function with the file name value as arguments. than that worker process. will is what implements emit. And every time the map calls emit, The worker process. will write this data to files on the local disk.

[1:04:11] So what happens to map emits? is they produce files on the map worker's local disk that are accumulating all the keys and values produced by the mapped run on that worker. um So at the end of the math phase, What we're left with is all those worker machines Each of which has the output of some of whatever maps were run on that worker machine. Then the MapReduce workers arrange to move the data to where it's going to be needed for the reduces and since I And a typical big computation This reduced syndication is gonna need all map output that mentioned the key A, but it's gonna turn out, you know, this is a sort of simple example, but probably, In general, every single map invocation will produce lots of keys, including some instances of key A.

[1:05:13] So typically in order, before we can even run this reduce function, the MapReduce framework that is the MapReduce worker running on one of our thousand servers, is going to have to go talk to every single other of the thousand servers and say, "Look, I'm gonna run the reduce for key A, please. Look at the intermediate map output stored in your disk and fish out all of the instances of key A and send them over the network to me. So the reduced worker is going to do that. It's going to fetch from every worker.

[1:05:44] all of the instances of the key that it's responsible for, that the master has told it to be responsible for. And once it's collected all of that data, then it can call reduce. And the reduce function itself calls reduce emit, which is different from the map in it. What reduces emit does is writes the output to A file. in a cluster file service that Google uses. So here's something I haven't mentioned.

[1:06:15] Um, I haven't mentioned where the input lives. and where the output lives. They're both vials. Um, because any piece of input We want the flexibility to be able to read any piece of input on any worker server. That means we need some kind of network file system to store the input data. Um, And so indeed, the paper talks about this thing called GFS, for Google File System.

[1:06:48] Um, And GFS is a cluster file system. And GFS actually runs on exactly the same set of workers worker servers that run MapReduce. And the input GFS just automatically, when you, you know, it's a file system, you can read and write files. it just automatically splits up any big file you store on it. across lots of servers in 64 megabyte chunks. So if you write, if you have 10 terabytes of crawled web page contents. and you just write them to GFS, even as a single big file, GFS will automatically split that vast amount of data up into 64 kilobyte chunks distributed evenly over all of the GFS servers, which is to say, all the servers that Google has available.

[1:07:32] And that's fantastic, that's just what we need. If we then want to run a MapReduce job that takes the entire crawled web as input. the data's already stored in a way that's split up evenly across all the servers. And so that means that um the map workers, you know, we're going to launch If we have a thousand servers, we're going to launch a thousand map workers each reading one one thousandth of the input data. and they're gonna be able to read the data in parallel from a thousand GFS file servers.

[1:08:02] That's getting... A tremendous total. read throughput. you know, the read-through bit of a thousand servers. Yeah. Thank you. running the map. So are you thinking maybe that Google has one set of physical machines that run GFS and a separate set of physical machines that run MapReduce jobs. saying that the May I have two?

[1:08:37] Okay. They're not necessarily . - Right, so the question is, what is this arrow here? actually involve. Um, And the answer to that actually sort of changed over the years as Google's of all of this system. You know, with this in the most general case, if we have big files stored in some big network file system. Like, you know, it's like GFS is a bit like AFS. you might have used on Athena. where you go talk to some collection, your data's split over, big collection of servers, you have to go talk to those servers over the network to retrieve your data.

[1:09:13] Um, In that case, what this arrow might represent is Thank you. the map, the MapReduce worker process has to go off and talk across the network to the correct GFS server or maybe servers. that store its part of the input. and fetch it over the network to the-- MapReduce worker machine in order to pass the map. And that's certainly the most general case. And that was eventually how MapReduce actually worked. In the world of this paper though, And if you did that, that's a lot of network communication.

[1:09:47] You're talking about 10 terabytes of data, and then we have to move 10 terabytes across their data center network, which... you know, data center networks run at gigabits per second, but it's still a lot of time to move. tens of terabytes of data. Thank you. in order to try to, and indeed in the world of this paper in 2004, The most constraining bottleneck in their MapReduce system was network throughput. because they were running on a network, if you read as far as the evaluation section. their network, their network was Um...

[1:10:23] They had thousands of machines, whatever, and they would collect machines, they would plug machines into, you know, each rack of machines into, you know, an Ethernet switch for that rack or something. But then, you know, they all need to talk to each other. But there was a root Ethernet switch. that all of the rack Ethernet switches talk to. And this, and you know, so if you just pick some MapReduce worker and some GFS server chances are at least half the time, the communication between them has to pass through this one root switch. Their root switch had only some amount of total throughput, which I forget, uh... you know some number of gigabits per second.

[1:11:07] um Anyway, I forget the number, but when I did the division, that is divided up the total throughput available in the root switch by the roughly 2,000 servers that they used in the paper's experiments. What I got was that each machine's share of the root switch, or of the total network capacity, was only 50 megabits per second. in their setup. Subtitles by the Amara.org community So 50 megabits per second per machine.

[1:11:39] And that might seem like a lot, 50 megabits, gosh, millions and millions. But it's actually quite small compared to how fast, say, disks run or CPUs run. And so this, with their network, this 50 megabits per second was like a tremendous limit. They really stood on their heads in the design described in the paper to avoid using the network. And they played a bunch of tricks to avoid sending stuff over the network when they possibly could avoid it. One of them was They ran the GFS.

[1:12:12] servers. and the MapReduce workers on the same set of machines. so that they have a thousand machines They'd Run GFS, they implement their GFS service on that thousand machines and run MapReduce on the same thousand machines. And then when the master was splitting up the map work and sort of farming it out to different workers, it would cleverly when it was I'M GOING TO GO TO THE NEXT QUESTION. about to run the map. that was gonna read from input file one, it would figure out from GFS which server actually holds input file one on its local disk.

[1:12:50] And it would-- Send the map. for that input file to the MapReduce software on the same machine. so that by default, this arrow is actually local read from the local disk and did not involve the network. And you know, depending on failures or load or whatever, that it couldn't always do that. But almost all of the maps would be run on the very same machine that stored the data, thus saving them um vast amount of time that they would otherwise have had to wait to move the input data across the network.

[1:13:21] Um, The next trick they played is that map, as I mentioned before, stores its output on the local disk of the machine that you run the map on. So, again, storing the output of the map does not require network communication, at least because the output's stored on the disk. however We know for sure that one way or another, in order to group together all of the way the MapReduce is defined, In order to group together all of the values associated with the given key and pass them single invocation to produce on some machine, this is going to require network communication.

[1:13:59] We're going to--you know, we want to--we need to--we're That's all the A's and give them a single machine to have to be moved across the network. And so this shuffle, this movement of the keys from this kind of, you know, originally stored by Rowe on the same machine that ran the map. We need them essentially to be stored on by column on the machine that's going to be responsible for reduce. This transformation of row storage to essentially column storage is called, the paper calls a shuffle. And it really that required moving every piece of data.

[1:14:30] across the network. from the math that produced it to the reduce that we needed. And that was like the expensive part of the... Um. of the MapReduce. Yeah. Why didn't they? make the something that would run sort of like you would have you Keep your... as you have it already. pick one of the then you would have waited all night. You're right, you can imagine a different definition in which you have a more kind of streaming reduce. I don't know I haven't thought this through. I don't know why. whether that would be feasible or not. Certainly as far as programmer interface, like if the goal, their number one goal really, to be able to make it easy to program.

[1:15:11] by people who just had no idea what was going on in the system. So it may be that this spec, this is really the way reduce functions look. in C++ or something. Like a streaming version of this is now starting to look I don't know how it looked. Probably not this simple. But you know, maybe it could be done that way. And indeed, many modern systems People have gotten a lot more sophisticated. with modern things that are the successors of MapReduce. And they do indeed involve processing streams of data often rather than this very batch approach. It is a batch approach in the sense that we wait until we get all the data and then we process it.

[1:15:55] So first of all, you then have to have a notion of finite inputs, right? And modern systems often do indeed use streams. and... are able to take advantage of some efficiencies due to that. Thank you. but not MapReduce. Thank you. Um... Okay, so this is the point at which the shuffle is where all the network traffic happens, this can actually be a vast amount of data. So if you think about sort, If you're sorting, the output of the sort has the same size as the input to the sort. So that means that if your input is 10 terabytes of data, and you're running a sort, you're moving 10 terabytes of data across the network at this point.

[1:16:37] And your output will also be 10 terabytes and so this is-- quite a lot of data and indeed it is for many map-produced jobs, although not all. There significantly reduce the amount of data at these stages. I'm... Somebody mentioned, oh, what if you want to feed the output of reduce into another MapReduce And indeed, that was often what people wanted to do. And in any case, the output of the reduce might be enormous, like for sort or web-in-mixing. the output that it produces is on 10 terabytes of input. the output of the reduce is again gonna be 10 terabytes. So the output of the reduce was also stored on GFS.

[1:17:10] And the system would-- you know, reduce would just produce these key value pairs, but the, Thank you. MapReduce framework would gather them up and write them into giant files on GFS. Um, And so there was another, round of network communication required to get the output of each reduce to the GFS server needed to store that produce. You might think that they could have... Played the same trick with the output of storing the output on the GFS server that happened to run um the MapReduce worker that ran the reduce.

[1:17:48] And maybe they did do that, but because GFS as well as splitting data for performance, also keeps two or three copies for fault tolerance. That means no matter what, you need to write one copy of the data across a network to a different server. So there's a lot of network communication here, and a bunch here also. Um, And it was this network communication that really limited the... Thruppidimapidus. in 2004. Um, In 2020, Because this network arrangement was such a limiting factor for so many things people wanted to do in data centers.

[1:18:22] Modern data center networks are a lot faster at the root than this was. Um, One typical data center network you might see today actually has many root, instead of a single root switch that everything has to go through, you might have-- many root switches and each rack switch as a connection to each of these sort of replicated root switches and the traffic is split up. among the root switches. So modern data center networks have far more network throughput um And because of that, actually, modern-- I think Google sort of stopped using Macrodeuce a few years ago, but Um, before they stopped using it.

[1:19:01] The modern MapReduce actually no longer try to run the maps. on the same machine as the data was stored on. They were happy to load the data from anywhere because they just assumed the network It was extremely fast. Okay. We're out of time for MapReduce. We have a lab. at the end of next week in which you'll write your own somewhat simplified MapReduce. So, Have fun with that. and see you on Thursday.

Vidleafワークベンチで開く

トランスクリプトを検索し、行を選択し、タイムスタンプ付きの引用をコピーし、翻訳します。

ワークベンチで開く →

帰属

MIT 6.824「分散システム」(https://www.youtube.com/@6.824)の「講義 1: はじめに」。CC BY 3.0 (https://creativecommons.org/licenses/by/3.0/) の下でライセンスされています。ソース動画: https://www.youtube.com/watch?v=cQP8WApzIQQ。このページは、段落区切りとタイムスタンプを追加した動画のテキスト文字起こしです。作成者は Vidleaf と提携しておらず、Vidleaf を推奨するものでもありません。Vidleaf は AI による句読点の付加と AI 生成の要約を追加しましたが、元の文言はこのページで引き続き参照できます。

あなたは制作者または権利者ですか?訂正や削除をリクエストする:copyright@vidleaf.app(これらのページについてを参照)。

最終更新