AWS re:Invent 2024 - Dr. Werner Vogels Keynote
はじめに
海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!
📖 AWS re:Invent 2024 - Dr. Werner Vogels Keynote
この動画では、Amazon.comのVice President兼CTOであるDr. Werner Vogelsが、進化し続ける巨大な分散システムにおける複雑さへの取り組み方を多面的に示しています。S3の初期段階から「ピザ2枚チーム」の組織論を導入し、シンプルなAPIを維持しつつ内部的にはマイクロサービス化やErasure codingなどで複雑化するストレージシステムを管理してきた経験が語られます。さらに、CloudWatchやCanva、Too Good To Goといった事例を通じて、Evolvabilityを重視することやアーキテクチャを細分化する戦略、Cell-based architectureによる影響範囲の限定、コスト考慮を含めたアーキテクチャ選定など、計6つの教訓が示されます。また、Amazon Aurora DSQLの設計思想を取り上げ、グローバル規模で強整合性を保ちつつ高スループットなトランザクションを実現する手法を紹介しています。その中で、Amazon Time Sync Serviceが提供するマイクロ秒単位の精度で同期されたクロックが鍵となり、複雑な分散アルゴリズムが大幅に簡略化できる点も強調されます。これらの手法によって、複雑さを予測可能な形で扱い、進化可能なアーキテクチャを築くための具体的な方法論が、豊富な実例とともに提示されています。
※ 画像をクリックすると、動画中の該当シーンに遷移します。
re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!
本編
Simplexityエピソード:S3の複雑さとシンプルさの物語
今日は、シンプルな起源から複雑さがどのように成長していくかという概念について探っていきます。私たちの初期のサービスの多くには、「Simple」という言葉が付いています。例えば、S3(Simple Storage Service)のように。Simpleという名前かもしれませんが、実際にはものごとをシンプルにすることは、非常に複雑になり得るのです。このSimplexityのエピソードでは、世界最大級のストレージシステムの1つと、それをシンプルに保つために取り組むイノベーターたちのチームの物語をお伝えします。
S3の誕生と「2枚ピザチーム」の概念
2000年代初頭のことでした。私たちは4、5人程度でした - 私、Werner、Al、そして今はもういない数人のメンバーです。それはREST APIと少数の機能だけでした。Alexは、S3の背後にあるシンプルさの多くにインスピレーションを与えました。Wernerは、他の誰も気づかなかった何かを彼に見出したのです。彼は私のアプローチを本当に評価してくれていると思います。私はとにかくシンプルさを重視しています。
ある夜、私たちがピザを注文したときのことです。彼が6メートルほどの高さのピザの箱の山を持って入ってきました。地面に落としてほとんどのピザを落としてしまい、「チームあたり2枚のピザ」という言葉を発しました。どうやら2枚のピザは救済できたようです。そこから「2枚ピザチーム」のコンセプトが生まれました。私たちは機能的な階層構造を分解し、小規模な自律的チームに組織を再構成しました。各チームを2枚のピザで満足させられるほど小規模なチームにしたのです。
ストレージコストを削減する方法を検討していたとき、私はとてもシンプルな計画を考案しました。Alexがピザカッターを持って現れ、スライスをシャーディングし始めたのです。今、私はFranken pizzaに取り組んでいます。これは無料のピザです。Erasure codingの世界へようこそ。私たちはストレージエンジン全体を書き直さなければなりませんでした。Glacierインシデントのことを聞いたことがありますか?Alexは人々に彼らのピザの半分を冷凍庫に直接入れさせ続けていました。余りものがたくさんありました。
Glacier ストレージクラスについて教えていただけますか?異なるアクセスパターンに対する異なるコスト層のことですね?私たちは、自分たちにとってどれだけ複雑さが増すとしても、お客様にとってシンプルであり続けることを常に目指しています。これは私たちが学び、受け入れ、さらには大切にすることを学んだことです。本当にAlexがこれらすべてのイノベーションのきっかけを作ったのかどうか、誰にもわかりません。彼は家具の一部のようになりました。それは強烈です。それは2016年のことです。彼がいます。このやつは君のことが大好きなんです。
このような成功は、実はシンプルなピザがきっかけでした。これは複雑さとシンプルさに関するドキュメンタリーだと思っていたのですが。はい、その通りです。実際、シンプルさを追求するために雇った長年の協力者、あのMaverickがここにいます。この人は誰でしょう?Alexを雇ったのではありませんでしたか?彼は2枚のピザチームのアイデアを提案しました。初期のS3の主要開発者であるAlを連れてくるように言ったはずです。
Dr. Werner Vogelsの20年間のAWS journey
Amazon.comのVice President兼CTOのDr. Werner Vogelsをお迎えしましょう。おはようございます。
毎年、皆さんの熱意に対してより一層の謙虚な気持ちになります。朝早くからACMで 列に並んで私の話を聞きに来てくださる皆さんの期待に応えられることを願っています。今年は少し特別な年です。20年前、45歳の若くもない私が、学術の道を諦めて本屋で働くことを決意しました。当時の私に、同じ雇用主のもとで20年も働くことになるとは思いますかと聞かれていたら、その人を 精神病院に連れて行っていたでしょう。しかし、Amazonでの20年は本当に驚くべきものでした。毎年が異なり、この20年間で成し遂げた技術的な成果は信じられないほどです。まだ私は終わっていません。
この20年間で一貫していたのは、継続的な学びでした。というのも、学者として、自分が何に足を踏み入れようとしているのか、本当のところわかっていなかったからです。学術界では実際のユーザーのためにシステムを構築していると思っていたかもしれませんが、正直なところ、顧客と直接関わることは一度もありませんでした。それに関しては本当に厳しい教訓を得ることになりました。私は頭を切り替える必要がありました。当時の私は意気込みに満ち、エネルギッシュで、 独断的で傲慢でしたが、学術的なバックグラウンドは、これから起こることに対して十分な準備になっていませんでした。マシンは停止することで故障するとか、障害には相関関係がないといった学術的な前提は、完全に非現実的なものでした。
就職して数ヶ月後、Jeff BezosとRick Dalzellが私にCTOの職を引き受けないかと尋ねてきました。ほぼ全ての人が使うことになる、世界最大の分散システムを構築する機会を逃すわけにはいきませんでした。当時CTOだったAlvin Mullinsは、その職を望まず、エンジニアに戻って次世代の技術を自らコーディングすることを本当に望んでいました。私たちはAlに非常に感謝すべきです。なぜなら、彼がAWSの基礎を築いたからです。裏で動作している全てのコアな技術は彼の手によるもので、AWS内の技術文化には明らかに彼の足跡が残されています。私は非常に大きな靴を履くことになりましたが、誰もCTOの仕事が何を意味するのか知らなかったため、私の傲慢さが勝って、その仕事を引き受けることにしました。
この20年間には多くのハイライトがありましたが、その中でも特に初回の re:Inventは印象的でした。というのも、皆さんとお話しし、次世代の開発について私が考える原則を示す機会を得られたからです。私たちは、常々そうありたいと思っていながらもこれまで実現できなかった方法で、アプリケーションを抜本的に構築しようとしていました。この最初のプレゼンテーションで、私は4つのカテゴリーのアドバイスを示しましたが、それを振り返ってみましょう。
初回re:Inventでの4つのカテゴリーのアドバイス
いくつかは本当にうまくいったと思います。多くの方々が本番環境のワークロードを少なくとも2つのAvailability Zoneで実行されているのを見て、とても嬉しく思います。継続的インテグレーションと継続的デプロイメントは、必ずしも私が言ったからではありませんが、今では誰もが当たり前のように行っていることです。一方で、より議論を呼んだり、時間がかかったりした項目もありました。システムを小さな構成要素に分解し、疎結合でステートレスなサービスにすることは、Amazonでは常に行ってきたことで、これによって私たちはスケールアップし、信頼性を確保し、各部分を独立して進化させることができました。しかし、これはモノリスかサービスか、マイクロサービスかナノサービスかという、ある種の宗教論争の真っ只中に踏み込むことになりました。アーキテクチャは、要件に基づいて、時には選択した技術に基づいて決定するものです。
Railsを使用している場合、自動的にモノリスを選択することになるため、ナノマイクロサービスを構築するのは非常に困難です。私はAll Things Distributedで、モノリスとマイクロサービスの違い、そしてこのシナリオで何をすべきかについて記事を書きました。
もう一つ提案したのは、ビジネスサイドと協力することです。結局のところ、私たちは技術者として自分たちのために技術を作っているわけではなく、顧客のために作っているのです。その顧客が社内のビジネス部門であれ、外部の顧客であれ、何らかの目的があって構築しているのであり、そのためにはビジネスサイドと密接に協力し、彼らがコントロールできるようなアーキテクチャを構築する必要があります。アプリケーションを層に分け、ビジネスサイドと対話するようアドバイスしました。例えば、各層がどの程度の信頼性を必要とするかについて。ビジネスサイドは「すべてを100%信頼性の高いものにする必要がある」と言うでしょうが、そこでそのコストを説明すれば、建設的な対話が可能になります。
先ほど述べたように、コストを考慮したアーキテクチャ設計は、誰もが完全に無視していました。突然、様々なことが可能になり、自社のデータセンターの物理的なハードウェアによる制約もなくなったからです。コストをアーキテクチャに組み込んで考え始めたのは、ようやく昨年になってからでした。昨年のFrugal Architectがその点で何らかの指針を示せたことを願っています。私たちは現在、アーキテクト向けWebサイトを一新し、多くのエンジニアがフルーガリティ(倹約)を実践している方法について、数多くのポッドキャストと共に、非常に深い内容のコンテンツを追加しています。
Resilienceと複雑さの管理
Resilienceについて見てみましょう。私によく引用される有名な言葉があります。ただし、この引用は常に不完全なものとなっています。単に「すべてのものは常に故障する」だけではないのです。実は2番目の文が最も重要でした。故障を想定して計画を立てれば、何も故障しないのです。生存は偶然に任せるものではなく、計画的に取り組む必要があります。
あの最初のプレゼンテーションを振り返ってみると、多くの原則は今でも通用すると思いますが、現在では追加したい点がいくつかあります。Evolvability、つまり時間の経過とともに変化に対応できる能力、そしておそらくデータベースの選択に関するガイダンスですね。2012年当時はそれほど多くの選択肢がありませんでしたが、現在では目的別に構築されたデータベースが豊富にあるため、特定のケースでどれを使うべきかというガイダンスが必要でしょう。
しかし、2012年当時にまだ十分に練り上げられていなかったことが1つありました。当時、私はそれをオッカムの剃刀として紹介しました - 必要以上に物事を複雑にしてはいけないという原則です。高校で習わなかった人のために説明すると、これは「シンプルに保つ」という意味です。KISSの原則 - Keep it simple, stupid(シンプルに保て、バカ)というものがありますが、シンプルに保つ人をバカと呼ぶ理由は分かりません。複雑さは常に忍び寄ってくるもので、それを本当にコントロールする必要があります。複雑さをどう管理するかを考える必要があるのです。
実際、私たち多くにとって複雑さは避けられません。システムは時間とともにより複雑になっていきますが、これは良いことです。より多くの機能を追加し、スケールアップし、セキュリティの問題に対処する必要があるからです。多くのAWSサービスが今でも「Simple」という名前を持っていることを覚えておいてください - SimpleDB、Simple Storage Service、Simple Queue Service、Simple Notification Serviceなどです。これらのサービスは内部的にはもはやシンプルではなく、すべて本当に複雑になっていますが、なぜか私たちはそれを実現することができました。複雑さを管理することができ、多くのサービスがこの複雑さに非常にうまく対処しています。途中でつまずくこともありましたが、私たちは苦労して複雑さを管理してきました。
今日は、Amazonにおけるこれら複雑なシステムの進化について、どのように安全に、セキュアに、そしてシンプルに実現しているかについてお話ししたいと思います。シンプルさに対抗して構築された複雑なシステム、管理可能性のための原則についてです。この文脈で関連する法則の1つが、Teslerの法則です。
Teslerの法則と複雑さの種類
Teslerの法則では、複雑さは作り出すことも破壊することもできず、ただ別の場所に移動するだけだと述べています。私がAmazonに入社した時、Larry Teslerはそこにいて、彼から多くのことを学びました。彼は主にユーザーインターフェースとその背後にある機能、特にお客様に提供する機能について関心を持っていました。複雑さは避けられないものだという事実を根本的に考えることは非常に重要でした。
しかし、すべての複雑さが同じというわけではありません。 明らかに意図的な複雑さというものが存在し、それは必要不可欠です。システムの拡張性を高め、新機能に対応し、変化する顧客ニーズを満たすのに役立ちます。これは意図的なもので、明確な目的があります。一方で、 技術の変化やアーキテクチャの監視不足によってこっそり忍び込んでくる意図しない複雑さもあります。これはシステムの開発速度を低下させ、保守を困難にします。両方のタイプを見分けることが重要で、それができないと、システムは柔軟性のあるものから脆弱なものへと急速に変化してしまいます。
意図しない複雑さが忍び込んでいる兆候とは何でしょうか?私たちは皆、経験があるのでよく知っています。機能開発の速度低下は間違いなくその一つです。Amazonでは、モノリスからサービスへ、サービスからマイクロサービスへ、そしてマイクロサービスから共有サービスインフラストラクチャへと移行した際、その主な要因はイノベーションが遅くなっていることに気付いたからでした。 裏側での困難な作業が、新機能の実装をより難しくしていたのです。エスカレーションが頻発し、チケットが増え、コードベースが大きくなりすぎて誰も全体像を把握できなくなります。これらのパターンはすべて、進捗を妨げ、システムを柔軟かつ信頼性の高い状態に保つことを困難にします。
複雑さがどのように移動するかの良い例として、私はお客様とAWSについて考えています。お客様はアプリケーションルーターを持ち、その下にドメイン固有のアプリケーションがあり、それらすべてがAWS上で動作しています。ほとんどのお客様は基盤となるサービスを実装し、各アプリケーションで共有されるドメイン固有の共有サービスも実装しています。私たちはお客様と協力して、共有サービス層の複雑さを確認し、私たちが十分にシンプルにできていなかったために お客様が実装せざるを得なかったものがないか検討します。
そのような例の一つが、結果整合性とAmazon S3です。2006年のローンチ時、 システムを確実に信頼性の高いものにし、障害から回復させるにはそれしか方法がないというのが一般的な考え方でした。多くのお客様にとって、これは非常に扱いづらいものでした。バケットを作成して即座に書き込みを行う必要があっても、バケットがまだ利用できない状態であり、これは良いカスタマーエクスペリエンスとは言えませんでした。多くのお客様がAmazon S3上で強整合性を実装しようとしましたが、これはリスクの高い選択でした。なぜなら、強整合性の実装は難しく、すべてのエッジケースに対応する必要があったからです。
正しい対処方法は、複雑さを取り除くことではなく、あるべき場所に移動させることでした。そこで私たちは、Amazon S3の強力な整合性をS3の内部に実装し、複雑さを本来あるべき場所に移動させました。自動推論を使用することで、すべてが正しく、あらゆるエッジケースが適切に処理されていることを確認することができました。このような複雑さへの対処方法は、私だけでなく、Amazonの他のメンバーも、そしてAmazon以外の企業でも同様に行っています。私たち全員が複雑さに向き合っているのは、アプリケーションが時間とともに進化し続けているからです。
複雑さを示すシグナルと自転車の例え
さて、複雑さを示すシグナルを見てみると、よく誤解されているシグナルが1つあります。多くの人は、複雑さはシステム内のコンポーネント数によって決まると考えがちですが、それは全く違います。コンポーネントの数を数えることは、複雑さを正確に測る方法ではありません。
むしろ、複雑さとは、システムがどれだけカオス的であるかということです。Colm McCarthyによる素晴らしい例え話があります。自転車に乗ることを考えてみましょう。この場合、一輪車を最もシンプルな形態として考えてみましょう。コンポーネントの数が非常に少なくシンプルで、乗りこなせれば素晴らしいものです。その場で回転することもできますが、実際に乗るのはとても難しいのです。
システム全体のシンプルさを測る指標として、単にコンポーネントの数を数えるだけでは不十分です。三輪車を例に取ると、乗るのは非常に簡単で、簡単には転びません。ほとんどの人が三輪車で自転車の乗り方を学びますが、曲がり角を曲がるのが実際にはかなり難しいため、柔軟性に欠けます。そこで、自転車が理想的な解決策となります。コンポーネントの数は多いものの、優れた柔軟性を提供します。習得するのは三輪車より難しいですが、一輪車よりははるかに簡単です。複雑さを示すのは全体的な体験なのです。自転車はコンポーネントの数は多いですが、全体的な観点から見ると最もシンプルな形態なのです。
私が育った場所を見てみると、自転車は至る所にあります。Amsterdamでは自転車を使って荷物の配達を行っており、郵便サービスも自転車を使って各家庭に手紙を配達しています。シンプルさについて考えると、それは偶然ではありません。複雑さを加えながらシンプルさを保つには規律が必要です。設計が、オリジナルの設計チームに属していないチームにも理解できるのであれば、それは良い兆候だと言えます。
Canvaの成長と技術的課題
物事をシンプルに保ちながら、その裏で途方もない複雑さを隠している企業が1社あります。その企業の話を聞いてみましょう。Canvaのブレンダン・ハンフリーズCTOをお迎えします。 Canvaは10年以上前に、世界中の人々にデザインの力を与えるというミッションのもとに設立されました。私たちは、スキルレベルに関係なく、誰もが美しいビジュアルコンテンツを大規模に作成できる製品を開発してきました。
現在、Canvaは190カ国で2億2,000万人以上のユーザーに利用されており、プレゼンテーションやビデオ、ホワイトボードなど、さまざまなコンテンツの作成やコラボレーションに活用されています。ここにはエンジニアの方々がいらっしゃるので、少し自慢の数字をご紹介させていただきます。私たちのプラットフォームは毎秒約120万件のリクエストを処理しています。162PB以上のメディアを管理しており、これは毎日約230TBずつ増加しています。これまでに300億以上のデザインが作成され、ユーザーは毎秒450以上の新しいデザインを追加しています。
これらの数字がほぼゼロだった頃、この旅の始まりにまで遡ってお話ししたいと思います。私は2014年にCanvaに入社しましたが、その当時はほんの数人しかいませんでした。当時のバックエンドエンジニアリングチームのほとんどがこの写真に写っていますが、この頃は安い家賃の1部屋に集まっていて、ヒューズボックスも怪しい状態でした。冬には、ヒーターを使うか、外部モニターを使うか、選択を迫られました。もちろん、私たちはモニターを選び、環境に適応しました。この写真はその頃のもので、寒すぎて指なし手袋をしながらコーディングしている私です。
当時、私たちの頭を悩ませていたのはアーキテクチャに関するジレンマでした。どうすれば素早く市場に投入できるものを構築しながら、アーキテクチャを迅速に進化させてスケールできるような方法で作れるのか。いずれはマイクロサービスアーキテクチャが必要になることは分かっていました。これにより、コンポーネントを個別にスケールでき、プラットフォームで生産的に働くエンジニアの数もスケールできるようになります。そこで、このマイクロサービスの未来を見据えながら、モノリスを構築してリリースしました。
これは完全にステートレスで、Amazon Elastic Load BalancingとAuto Scalingを使って水平方向にスケールできました。私たちが特定した主要なエンティティを慎重にモデル化し、将来分解可能にするためのシンプルなルールでこのモデルを実装しました。各エンティティはサービスインターフェースでカプセル化され、サービスインターフェースはシンプルなCRUDの動詞セットを中心に一貫性を保つよう努めました。すべてのビジネスオーケストレーションは、このサービス抽象化レイヤーの上で行う必要がありました。
これらのルールのおかげで、モノリスを比較的簡単に分解することができました。スケールの必要性が出てきたとき、サービスインターフェースはRPCスタブとなり、1つの実行ユニットが1サービスごとに進化していきました。当初のアーキテクチャは単一のAmazon RDS MySQLデータベースでしたが、スキーマの設計においても、同様にスケールを見据えていました。エンティティ間の関係を厳密に分離して維持していたのです。複数のエンティティを含むビジネスオーケストレーションが必要な場合は、サービス上のCRUD操作を組み合わせて実現する必要がありました。魅力的ではありましたが、永続化層でのクロスドメインの結合は厳密に禁止されていました。
このおかげで、1つのMySQLインスタンスを複数のMySQLインスタンスに簡単に分解できました。スケールの必要性が出てきたとき、各MySQLインスタンスでさらにスケールを追加できました。読み取りレプリカでスケールアウトし、インスタンスサイズでスケールアップできたのです。そして最終的に、指数関数的な成長が爆発的になると、多くのサービスがAmazon DynamoDBに移行し、グローバルなスケールを実現し続けています。
正直に申し上げますと、この永続化の進化のプロセスが常にスムーズだったとは言えません。指数関数的な成長というのは、人間にとって、エンジニアでさえも理解するのが難しいものです。これを私たちはMediaサービスで痛感しました。Canvaの爆発的な人気により、MediaサービスのMySQLが突然巨大化してしまったのです。DynamoDBへの移行が必要だと分かっていましたが、シームレスな移行を実現するための時間を稼ぐため、永続化層に抽象化レイヤーを設けながら、同時にMySQLの限界まで使い続けました。当時のMySQLは、数億行のテーブルサイズで、毎日数千万行ずつ増加する重圧に耐えながら、Amazon RDSの新しい制限に次々と遭遇していました。
シドニーでCanvaを開発する喜びの1つは、アメリカのトラフィックピークがシドニー時間の午前1時過ぎだということです。そのため、これらの制限に気づくのは、深夜のオンコールアラートでぼんやりしている時でした。MySQLの容量を限界まで引き延ばすには、多くのデータベースの裏技が必要でした。まず、ダウンタイムなしのスキーマ移行を妨げる外部キーをすべて削除しました。次に、そのサイズではJOINでさえも非常にコストがかかるため、スキーマの非正規化を始めました。最後に、スキーマ管理をアプリケーション層に持ち上げるため、データをJSONブロブとしてテキストカラムに統合し始めました。
DynamoDBへの切り替えの準備ができた頃には、MySQLを怪しげなKey-Valueストアに変形させており、真夜中の呼び出しにもうんざりしていましたが、なんとかそこにたどり着きました。現在、DynamoDBを基盤とするMediaサービスは930億のアイテムを管理し、1日約9,000万アイテムのペースで成長しており、非常に印象的なパフォーマンスと信頼性を実現しています。Canvaでスケールに向けて進化する上で重要なのは、アーキテクチャ内で提供する抽象化に慎重に投資することです。私たちは、それらを強力で一貫性があり、組み合わせ可能なものにするよう努めています。この焦点と注意深さを、誰でもCanva上で機能を構築できる強力なAPIの開発にも引き継いでいます。
私たちはApps SDKを提供しており、これによってCanvaに組み込み機能を構築することができます。そしてConnect APIを通じて、お客様のプラットフォームにCanvaの機能を組み込むことができます。現在、120カ国以上から数千人の開発者がCanvaで開発を行っており、300以上(そして増加中)のアプリが存在する活気あふれるマーケットプレイスに貢献しています。これらのアプリは、ユーザーによって10億回以上使用されています。
私のお気に入りの一つがCrikey 3Dアニメーションアプリです。Canvaでのリリース後最初の1ヶ月で、Crikeyは試用したCanvaユーザーの中で10%という転換率を達成しました。Canvaのエンジニアリングの歩みの一部をご紹介させていただき、ありがとうございます。私たちの創業者のMelは、世界の82億人全員の手にCanvaを届けたいと考えています。彼女はよく「まだ道のり1%」と言っています。でも、Melには申し訳ないのですが、2億2,000万人のアクティブユーザーがいる現在、私の計算では実際には2.72%まで来ています。これから10年、そしてその先にどんな展開が待っているのか、とても楽しみです。皆様にもぜひこの旅に加わっていただきたいと思います。
システムの進化と複雑さの管理
ありがとう、Brandon。素晴らしい話ですよね?でも、その裏側を見てみると、多くの私たちが経験する進化の過程があります。彼らは素晴らしい、比較的シンプルなアプリケーションを持っていますが、顧客により多くの機能を提供するために、バックグラウンドではどんどん複雑になっていっています。これは今や私たち全員が経験していることだと思います。
進化は根本的なものです。ダーウィンでさえ、複雑な生物に至る唯一の道は、数多くの連続的な小さな修正を通じてであることを既に理解していました。そしてヘラクレイトスは紀元前500年よりもずっと前に、「変化は常に存在する」という有名な言葉を残しています。私たちの世界を止めて、何も変化しない状態を作り出せるという考えは、単なる幻想です。現実の世界は常に変化し続けており、デジタルシステムもその影響を受けます。ヘラクレイトスはまた、「世界は絶え間なく流動している。同じ川に二度と入ることはできない」という有名な言葉も残しています。私たちの環境、要件、実装において、変化は絶えず起こっています。
実は、これは新しい議論ではありません。1960年代に、Lehmanはソフトウェア進化の法則について一連の法則を示しました。これは分散システムやクラウド、現代のシステム構築方法とは関係ありません。なぜなら、彼はメインフレームについて考えていたからですが、これらはソフトウェアの法則なのです。進化しないソフトウェアは無意味になります。新機能がなければ、顧客は私たちのシステムの品質が低下していると感じるでしょう。そのため、私たちのデジタルシステムは常に進化の必要性に直面しているのです。
そこで私たちの助けとなるように、Amazonで学んだ基本的な6つの教訓をまとめてみました。これらが、複雑さが制御不能になるのを防ぐために、環境をどのように管理するかを考える際の参考になれば幸いです。ただし、シンプルさを保つには初日からの規律が必要です。設計を始める時点から、そのことを考え始める必要があります。初日はシンプルかもしれませんが、時間とともに複雑になっていくものです。
Evolvabilityを要件とする重要性
第一の教訓は、いつものように最も重要なものです。Evolvability(進化可能性)を要件にすることです。システムは時間とともに成長し、これまでに行った設計上の選択を見直す必要が出てくる可能性があることを認識しておく必要があります。Amazon S3の初期に私たちが本当にうまくできたことの一つは、1年後や2年後には同じアーキテクチャを使用していないだろうということを知っていたことです。初期の頃は、スケールが1桁変わるたびにアーキテクチャを見直す必要があると考えていました。
複雑さに対応していくためには、制御可能な方法で進化できるアーキテクチャを構築することが重要です。私はEvolvabilityを、将来の変更に容易に対応できるソフトウェアシステムの能力と定義しています。これはMaintainability(保守性)とは異なります。Evolvabilityは長期的で、粗い粒度の、根本的な機能的・構造的な拡張を指します。一方、Maintainabilityは細かい粒度の、短期的な局所的変更を指します。これらの変更は多くの場合、修正的、適応的、または予防的なものです。システムをより完璧にしたいと思うかもしれませんが、それはMaintainabilityであってEvolvabilityではありません。Evolvabilityとは、時間の経過とともに複雑さに対処するための長期的な戦略を持つことです。
進化可能なシステムを構築する際に、私たちはいくつかの重要な教訓を学びました。ビジネスコンセプトと内部の詳細を細かいインターフェースでモデル化することで、焦点を絞ったコンポーネントを構築できるようにすることです。そして、スマートなエンドポイントを構築し、分散化を活用し、コンポーネントを独立してデプロイ可能にすることで、これらの部分を個別に進化させることができます。高いEvolvability、高い観測可能性、そして複数のパラダイムのサポートにより、システムの異なる部分を実際にどのように実装するかについて柔軟性を持つことができます。
私はよくAmazon S3について話をしますが、冒頭の動画でもS3は重要な役割を果たしていました。なぜなら、シンプルなサービスが時間とともに内部的により複雑になっていきながら、お客様にとってのシンプルさを保ち続けるという素晴らしい例だと思うからです。S3を見てみると、驚くべきことではありませんか?これは18年前、クラウドストレージの進化がシンプルなAPIから始まった時のことです。当初は耐久性、可用性、コスト効率性に焦点を当てていましたが、その当初の原則がその後のすべてのイノベーションの基盤となりました。その一部はお客様によって推進され、多くの場合、大規模な書き換えが必要でしたが、システムが進化する中でも高い可用性と耐久性を維持し続けました。
誰かが私に素晴らしい例え話をしてくれました。S3の進化は、単発エンジンのCessnaから始まり、737に移行し、最終的には380の機体群全体へと発展していく過程のようなものだと。その間、顧客に気付かれることなく移行し、空中給油をしながら進めていくのです。 S3の構築はまさにそんな感じでした。毎年、顧客に提供している機能に影響を与えることなく、新しい機能を追加してきました。Strong Consistencyの実現により、もはや私たちの核となる属性を妥協する必要がなくなりました。モジュール性により、Rustのような言語での実験も可能になりました。
当初から、マイクロサービスアーキテクチャによる複雑性に対する明確な戦略がありました。その下にあるマイクロサービスの進化を見ると、実に驚くべきものです。初日は6つのマイクロサービスからスタートし、現在では300以上まで成長しています。私たちは皆、この複雑性が裏側で大きく成長していることに気付かずにS3を使用しています。
これは、完全なコントロールがあるからソフトウェアが進化しやすいというだけの話ではありません。私たちが本当に変更しなければならなかったのは、ハードウェアインフラストラクチャでした。ネットワークデバイスは一般的に、すべての機能がASICに組み込まれており、変更のたびにネットワークデバイス全体を交換する必要がありました。これは2006年当時の常識でしたが、私たちの顧客は常にネットワークを再構成しており、当時のネットワークボックスはそれに適していませんでした。2006年に提供していたネットワーク機能が、2010年、そして2020年には大きく異なるものになることは分かっていたので、進化のための基盤を作る必要がありました。そこで、Blackfootと呼ばれるイノベーションの基盤を作りました。これは基本的に、多数のラインカードを備えたデバイスで、当初はLinuxカーネルをサイドに置いていましたが、時間とともにネットワークを進化させることを可能にしました。
Amazon CloudWatchの進化と複雑さの分割
最初のデバイスは毎秒10ギガビットの回線速度を提供していましたが、現在では数百ギガビットまで進化し、同時にネットワークのセキュリティも進化させてきました。このように、ホストと同様に、進化のための基盤を作り上げたのです。
ある時点で、私たちのホストの構築方法が進化のための適切なプラットフォームではないことに気付きました。AWS Nitro Systemのように、機能をカード付きの別ボックスに分離することは、ホストシステムを進化させるために重要でした。初期の頃、プロセッサーが非常に高速になり、仮想マシンのルートI/O仮想化が障害となっていました。ネットワーキングをボックスの外に移動することで、完全な回線速度へのアクセスを維持しながら仮想化を継続することができました。回線速度での暗号化が可能になり、EBSへのアクセスのためのPCIeインターフェースを構築することができました。
Evolvabilityは意識的な決断です。進化できる環境を作り出す必要があります。複雑性を管理するための前提条件として、Evolvabilityを要件にしなければなりません。時間とともに複雑性がどのように増大するかについて、私はこのたとえ話が好きです:カエルを沸騰したお湯に入れると、何かがおかしいと気づいてすぐに飛び出します。しかし、カエルを冷水に入れてからゆっくりと温めていくと、カエルは快適に感じ続けます。小さな警告サインはありますが、無視されてしまいます。カエルはただ徐々に上がっていく温かさに順応するだけです。危険に気づいた時には、もう逃げ出すには遅すぎるのです。なお、このたとえ話でカエルが傷つくことはありませんでした。
この教訓は、警告サインを無視してはいけないということです。小さな変化は最初は管理可能で、簡単に対応できるように見えます。しかし、警告サインを無視し続けると、システムはより複雑になり、管理や理解が困難になっていきます。これに対処するには、複雑性を分割する必要があります。良い例として、Amazon CloudWatchがあります。現在、私たちは皆Amazon CloudWatchを使用していますが、これは1日に何百兆ものメトリクスと観測データを扱い、1日にほぼ0.5エクサバイトのログを取り込む巨大なサービスです。これはAWSにおける重要な基盤サービスです。
しかし、最初からこのような規模だったわけではありません。初期のAmazon CloudWatchは非常にシンプルなサービスでした。立ち上げ時はこのような状態で、メトリクスデータの保存と受信のためのサービスに過ぎず、バックエンドサービスも少なく、システムのあらゆる部分を理解している小規模なエンジニアチームで運営されていました。しかし時間とともにシステムは成長し、フロントエンドが新機能実装の場となっていきました。これは時間とともに成長し、より複雑になり、私が「メガサービス」と呼ぶアンチパターンが現れました。メガサービスは、分割が必要な複雑性を生み出すというアンチパターンです。
現在、フロントエンドは基本機能のみを扱い、システム全体の複雑性は個々の部分に分散されています。私たちが繰り返し使用する原則は:システムを分割し、高い凝集性を持ちながら他との結合度が低く、明確に定義されたAPIを持つコンポーネントを構築する必要があるということです。これが現在のAmazon CloudWatchの姿で、非常にシンプルなフロントエンドサービスを持っています。実際、初期の頃から残っているコードは、おそらく元のリクエストを処理する部分だけで、他のすべては時間とともに書き換えられ、新機能も常に追加されています。
システムを変更しなければならない理由は、新機能の追加だけではありません。例えば、私たちが直面している複雑性の問題の1つはエンジニアリングに関するものです。Amazon CloudWatchの多くの大容量データストアはC言語で書かれていますが、このレベルで実際に運用できるCプログラマーを雇用することは非常に困難です。そのため、これらの分割されたコンポーネントを個別に扱える方法について検討を始めています。
どのプログラミング言語を選ぶかは、実はそれほど重要ではありません。 今回の場合、私たちはこれらの大規模インターフェースの実装にRustを使い始めました。システムをより小さな構成要素に分解すると、機能面だけでなく、使用するライブラリやプログラミング言語に関しても、時間とともに進化させることができます。
よく受ける質問として、システムを分割する際、各サービスはどのくらいの規模であるべきかというものがあります。一般的に、この選択の余地はそれほど多くありません。チームの数、成功の度合い、顧客からの需要など、外部要因によって決まることが多いのです。Amazon CloudWatchには多くのマイクロサービスがありますが、それぞれの規模は実際には成長過程に依存しています。そのため、具体的にどの程度の規模であるべきかについて、明確なアドバイスを提供することは難しいのです。
新しい機能を追加する際には、 2つの選択肢があります。既存のサービスを拡張するか、新しいマイクロサービスを作成するかです。拡張は既存のコードを再利用できるため多くの場合より早く実装できますが、メガサーバーのアンチパターンのリスクがあります。新しいサービスを作成すれば、サービスを管理しやすい規模に保てますが、初期の段階でより多くの労力が必要になります。警告サインとしては、マイクロサービスがエンジニアの理解の範囲を超えて大きくなりすぎた時です。 頭の中で全体像を把握できなくなったら、一般的にそのサービスは大きくなりすぎていると言えます。
S3チームの組織と複雑さへの対応
このような課題に日々取り組んでいる人物として、Andy Warfieldがいます。Amazon S3がこのような複雑さにどのように対処しているかについて、Andy自身が共有してくれますので、彼を歓迎したいと思います。 みなさん、こんにちは!私はS3チームのエンジニアのAndyです。今日は組織と複雑さについて、そして私たちがチームと組織をどのように構築して 複雑さに対処しているかについてお話しします。
Wernerが言及したように、S3は18年間存在しています。これは私にとって驚くべきことです。私のキャリアの中で最も素晴らしいプロジェクトです - 単一の分散システムと単一のチームが18年間継続して運用されているという事実は。組織がどのように機能しているかについて、興味深く、成功している点をいくつか指摘したいと思いますが、まず免責事項から始めさせてください。私がここに立って、組織の複雑さという問題を解決したと皆さんに伝えているように思われたくありません。 実際にはまだ解決できていません。私たちにはまだ学ぶべきことが多く、日々学習を続けています。システムは進化し続け、チームも大きくなり続けています。
しかし、私たちが最高のパフォーマンスを発揮している時、いくつかのことをうまくやれていると思います。そしてそれらは共有する価値があると考えています。2つのうまくいっていることについてお話しする前に、皆さんに質問があります。これが何かわかる人はいますか?こういうものを見たことがある人はいますか?前輪がないのがお分かりですね。これは私が子供の頃のトラクターPullで使用されたソリです。私はカナダのOttawaで育ちました。町から1時間ほど離れたところに親戚が住んでいて、毎年夏の終わりに、私たちは車でShaw, Quebecの田舎の祭りに行っていました。
その祭りには、田舎の祭りの素晴らしいものが全部ありました。一番大きな野菜を競うコンテスト、遊園地、そしてもちろんトラクターPullです。トラクターPullでは、農家の人たちが自分のトラクターを持ち寄ります。トラクターをソリに取り付けて、トラックを走らせるのです。雨が降ると特に素晴らしかったです。泥だらけになりますから。トラクターのパワーとドライバーの技術を組み合わせて、トラックをできるだけ遠くまで引っ張っていくのです。しかし、ソリを引っ張れば引っ張るほど、上部のバケツに入った重りによってソリはどんどん重くなっていきます。
これは少し変わった図ですが、これが基本的に私がソフトウェア開発について考えている方法です。トラクターPullと大規模な分散システムの開発には、驚くべき共通点があります。その共通点とは、引っ張れば引っ張るほど、重くなっていくということです。最初の日、空のバッファを見つめている時が、可能性に満ち溢れ、負担が最も少ない最高の時期です。しかし引っ張れば引っ張るほど、どんどん重くなっていきます。複雑さが蓄積され、純粋なパワーと意志の力だけである程度の距離は進めます。
しかし最終的には、ソリの重さを認識しなければなりません。一般的な観察として、私たちの組織は、私たちが構築するソフトウェアと少なくとも同じくらい複雑であり、同じような注意を払う必要があることを認識しなければなりません。
私が指摘したい最初の観察は、S3チームがかなりうまくやっていると思うのですが、成功しているチームは常に、自分たちがやっていることが間違っているのではないかという不安を少なからず抱えているということです。常に、完全には正しくないものを探しているのです。物事が本当にうまくいっている時こそ、何か見落としているのではないかという不安が最も大きくなります。少し不安を感じ、質問し、改善しようとすること、これがS3チームがうまくやっていることです。
一例をご紹介しましょう。 約6年前、私たちは大きな成長期を迎え、多くの新しいエンジニアをチームに迎え入れていました。S3は耐久性において絶対に失敗が許されません。耐久性はエンジニアリングチームの中核であり、私たちのアプローチの根幹をなすものですが、優秀ではあるものの、このような環境での経験がない新しいメンバーを迎える中で、耐久性への注力と投資を維持していく必要がありました。そこで、私たちはSeth Oracleと一緒に、この課題にどう取り組むかについて話し合い、セキュリティエンジニアリングからアイデアを借りることにしました。それが、脅威モデルという考え方です。
セキュリティ上の脅威を文書化し、モデルが防御策と一致しているかを評価するという考え方を取り入れ、耐久性の脅威モデルという概念を開発しました。S3に変更を加えるチームが、予想される耐久性のリスクとその対策を文書化する仕組みを構築しました。そして、チームに長年在籍し、耐久性に関する運用とエンジニアリングの豊富な経験を持つ少数のエンジニアに、耐久性レビュアーとして活動してもらいました。耐久性の脅威モデルを巡って生産的な議論を行い、穴を見つけて改善点を探りながら、同時に教育も行うというアプローチを取りました。
これは一例に過ぎません。チームをスケールさせるために実施してきたメカニズムは、おそらく何百もあるでしょう。しかし、重要なのは、私たちが疑問を投げかけ、意識的に現状に挑戦することを奨励しているということです。Grace Hopperの言葉を借りれば、「これまでずっとこのやり方でやってきたから」という理由で物事を行っているのを見かけたら、それは、もっと疑問を持ち、もっと警戒すべきだという警告サインかもしれません。
二つ目の観察点として、Ownershipという考え方についてお話ししたいと思います。Ownershipは、S3において、そしてAWSのエンジニアリング全般において、さらにはAmazonのものづくり全体において、非常に興味深い特徴です。ただし、このOwnershipを説明するのは本当に難しいものです。簡単な演習を通じて説明してみましょう。皆さんの経歴や人生の中で、本当に好きで大切に思えるものに取り組んだ時のことを思い出してください。その時、どれだけ一生懸命働いたか、品質にどれだけこだわったか、そしてそれを届けることにどれだけワクワクしたかを考えてみてください。
次に、言われたからやらなければならない、つまり、その利点や成果が理解できないけれど、指示されたからやらなければならないことに取り組んだ時のことを思い出してください。その時、どれだけ努力したか、どれだけ早く終わらせたかったか、そして品質はどうだったかを考えてみてください。この二つの違いこそが、Ownershipという特性です。自分たちが取り組んでいるものに対してOwnershipを持つチームは、最初のカテゴリーに該当するのです。
私が一緒に仕事をしている最も効果的なリーダーたちを見ると、彼らは所有権を推進することに長けており、2つのことを実践しているのが分かります。1つ目は、彼らが一緒に働くチームの中にAgencyの感覚を築くことです。Agencyとは、チームが本当の意味で成果を出すための幅広い裁量とサポートを持っていると感じられることを意味します。Agencyを構築する最初のステップは、チームに何をすべきか、どのようにすべきかを指示することではありません。チームに課題を持ち込み、その重要性を説明し、チームを巻き込み、最終的に彼らを信頼して、彼らが構築するものの所有権を与えることです。それを与えることで、実際にアイデアを所有させ、その成功を祝うことができます。なぜなら、それは彼らのものだからです。チームがAgencyを持っているとき、私が特にS3で一緒に働いてきた効果的なリーダーたちが行う2つ目のことは、緊急性を推進することです。
最高のチームでさえ、スピードを落とす理由を見つけてしまいます。予期せぬことを発見したり、リリースに関して心配事を見つけたりするものです。そして、リリースする際には常に決断と妥協を迫られます。リーダーとして速く進むということは、所有権を確立し、一歩引いてチームに任せることですが、同時にアクセルを踏み続け、確認を怠らず、問題解決を支援し、チームが確実にサポートを受けながら成果を出す必要性を感じられるようにすることです。つまり、所有権とはAgencyと緊急性のこの組み合わせなのです。
私が話した2つのことは、少し怖さを感じるべきということと、所有権を2ピザチームのレベルまで完全に委譲し、そのチームに彼らが提供するものを本当に所有させ、彼らが自分の仕事を愛せるようにすることに焦点を当てながら、サポートしつつ成果を出すよう推進すべきだということでした。ありがとうございました。Andyについては、AWSがアーキテクチャの観点だけでなく、組織的な観点からどのように進化してきたかについて、素晴らしい話がたくさんあります。私たちにはこのようなDistinguished Engineerが多くいて、Andyもその一人です。時間とともに、皆さんに素晴らしい話を語ることができるDistinguished Engineerがさらに増えることを願っています。
Cell-based Architectureによる運用の複雑さ管理
さて、レッスン4では、私たちはものごとをより小さな構成要素に分解し、私たちの組織を望ましいアーキテクチャの形に合わせてきました。しかし、それらを構築するだけでなく、運用もしなければならない段階に来ています。Amazonでは、運用の複雑さをどのように管理しているのでしょうか?私たちはこれを、Cell-based architectureと呼ぶ方法でアプリケーションを組織化することで実現しています。アプリケーションを構築し、フロントエンドがあり、中間に一部コンテナがあり、バックエンドにデータストレージがあるとします。そして、成功し始めると、物事は成長し始め、運用上のどんな障害でもすべての顧客に影響を及ぼすことになります。
パフォーマンスに影響が出たり、特定の顧客が負荷を与えたり、どこかで障害が発生したりすると、全体のサーバーがダウンし、すべての顧客に影響が及びます。このアーキテクチャでは、これを管理することは非常に複雑です。そのため、再び物事を分解して、独立して動作する小さな構成要素に分解する必要があります。ここでの本当の目的は、影響の範囲を縮小することです。これはCell-based architectureのような複雑なシステムにおいて不可欠です。システムを独立した isolated cellに分割し、決定論的なアルゴリズム(多くの場合はハッシュ関数)を選択して、顧客を特定のセルにマッピングし、これらのセルが複雑なシステムの中に秩序を作り出します。
Cellは特定のユニットに問題を隔離し、他のユニットへの影響を防ぐものです。これを実現するには、シンプルなRouterが必要になります。このRouterは非常にシンプルで、リクエストを適切なCellに転送するだけの機能があれば十分です。ちなみに、顧客をCellに割り当てる非常に優れたアルゴリズムとしてShuffle Shardingがあり、AWS Builder's Libraryに素晴らしい記事がありますので、興味のある方はぜひご覧ください。これは全体的な可用性を最大化する独自の方法です。さて、Cellがどのように見えるかについてですが、これは最初にどこからスタートしたかによって少し異なります。リージョナルサービスの場合、Cellもリージョナル単位のままで、単により小さな構成要素となります。ゾーンベースのサービスの場合は、より多くのCellが存在することになりますが、やはり複雑さを管理しやすくするために小さなブロックに分解します。
では、AWSの各種サービスではCellをどのように使用しているのでしょうか?どのようなIDでルーティングしているのでしょうか?Amazon CloudFrontはDistribution ID、Amazon Route 53はHosted Zone ID、そしてAmazon EC2やLoad BalancerなどのバックエンドであるHyperplaneはCustomer IDを使用しています。これは実際、利用可能な場合の優れたデフォルトオプションです。また、異なるCellを管理するために、Control Planeも少し開発する必要があります。新しい顧客がオンボードされる際には、新しいCellを作成したり、既存のCellに分散させたりすることができます。
これらはすべて、サービスと同様にコントロール可能です。サービスの規模をどの程度にすべきかという問題と同じように、Cellの規模をどの程度にすべきかという問題があります。Cellは想定される最大のワークロードを処理できる大きさである必要がありますが、同時にフルスケールのワークロードでテストできる程度の小ささである必要もあります。
おそらく正解は中間あたりにあります。主な理由はスケールメリットを活かしたいからです。サービスが大きくなればなるほど、問題が発生した際により多くの顧客に影響が及ぶ可能性が高くなり、小さくすればするほどスケールメリットが減少します。つまり、いつものように、バランスを取ることが重要です。Cell-based Architectureを導入すると、これらを管理する必要があるため、複雑さが増加します。
これは事前に行う必要がありますが、システムの構築時間は、そのシステムを運用する時間と比べると非常に短いことを覚えておく必要があります。そのため、管理のしやすさに事前に投資することは、セキュリティやコスト管理への事前投資と同様に重要です。Cellへの分解は、時間の経過とともに顧客の信頼性とセキュリティを維持するのに役立ちます。AWS Well-Architected Frameworkには、これに関する素晴らしい記事があり、さまざまな詳細が説明されています。Cell-based Architectureを構築したい場合は、ぜひこの記事を読むことをお勧めします。
システムからの不確実性の排除
システムが複雑になると、発生する問題の影響を抑える必要があるため、セルの整理は非常に重要です。また、私たちが学んだもう一つの教訓は、システムから不確実性を排除する必要があるということです。不確実性は扱いが非常に困難だからです。そのため、複雑さを軽減することを念頭に置いて、システムを事前に設計する必要があります。例えば、Hyperplaneのような設定システムの設計を任されたとしましょう。私たちには多数のロードバランサーがあり、特に何百万ものお客様がいる場合、お客様は継続的にロードバランサーの設定を変更しています。これは常に発生していることです。
一般的なアプローチとしては、設定変更をデータベースに保存し、Amazon SQSキューを通じてイベントを送信し、AWS Lambda関数を起動してロードバランサーを再設定するという、イベント駆動型のアーキテクチャを使用することでしょう。しかし、これが継続的に発生すると、ロードバランサーがどれだけの再設定負荷を処理しなければならないか予測できなくなります。ここで意外な展開ですが - 私たちはこの方法を採用しませんでした。なぜなら、ロードバランサーでの処理が完全に予測不可能になってしまうからです。
私たちが採用したのは、もっとシンプルなアプローチです。すべての変更をファイルに書き込んでAmazon S3に保存し、ロードバランサーは数秒ごとの固定ループでS3から新しい設定を取得します。このファイルには固定数のエントリが含まれており、常にすべてのエントリを処理します。このため、再設定は完全に予測可能です。これは、シンプルさを活用して高度に予測可能なシステムを構築する例です。一見すると魔法のようなアーキテクチャの変更には見えませんが、シンプルさが予測可能な処理の実現に役立つのです。私たちはこれを「Constant Work」パターンと呼んでいます。
Amazon S3からファイルを定期的に取得することで、スパイク、バックログ、ボトルネックを回避でき、Amazon S3の比類のない可用性により、自然に自己修復も可能になります。次に、Constant Workを活用している別のサービスの例をご紹介しましょう。それはAmazon Route 53とヘルスチェッカーです。私たちには、ノードが利用可能かどうかを確認するために設定された大規模なヘルスチェッカーのフリートがあります。変更があるたびにプッシュするのではなく、ヘルスチェッカーは定期的に、担当するすべてのノードの完全な設定ファイルをアグリゲーターにプッシュします。
アグリゲーターはこれらのリクエストをすべてマージしてより大きなテーブルにし、それをAmazon Route 53にプッシュします。Route 53は、そのテーブルを受け取っても何もしません。数秒ごとにテーブルが届いても、DNSリクエストが到着してIPアドレスのセットに解決される時まで何も起こりません。その時点で、ホストが利用可能かどうかをこのテーブルでチェックします。このシステムでの処理はもはやイベントによって駆動されることはなく、高度に予測可能であり、その結果、複雑さは消え去り、シンプルさを保つことができます。
しかし、この意図的なシンプルさを実現するには規律が必要です。予測可能なシステムを設計しなければならず、それは主に不確実性の影響を軽減するためです。複雑さを管理する方法に関する最後のレッスンは、複雑さを自動化することです。これは、複雑な大規模システムを管理する上で不可欠です。AWSは耐久性、キャパシティ、そして実際には新しいリージョンの構築にも自動化を活用しており、人間の関与はほとんどありません。先ほどネットワーキングの例で示したように、お客様は継続的にネットワーク機能を再構成するため、私たちはそれを完全に自動化する必要がありました。
複雑さの自動化とセキュリティの取り組み
では、何を自動化すべきでしょうか?正しい問いかけは、何を自動化しないのか?ということです。人間が本当にループに入る必要がある判断だけを明確にする必要があります。自動化が標準であるべきで、人間がループに入ることが例外であるべきです。手動入力は、本当に人間の判断が必要な領域でのみ必要とされるべきです。一般的な方法として、ミスを防ぐために、一人が命令を入力し、もう一人がその様子を確認するという方法があります。
私たちが多くの自動化と自動処理を行っている分野の一つがセキュリティです。AWSでは、全員がセキュリティの仕事を担っています。お客様を守るためには、セキュリティを最優先に考える必要があるため、私たち全員がセキュリティエンジニアなのです。最初からセキュリティを設計することで、後から追加するのではなく、サービスの作成時にセキュリティを組み込んでいます。セキュリティチームは、安全なサービスの構築を支援するだけでなく、特に自動化された脅威インテリジェンスに関する技術も開発しています。
私たちは世界中に巨大なネットワークを持ち、そこでの変化の影響を目の当たりにしています。1日に文字通り兆単位のDNSリクエストを処理し、毎日10万件以上の悪意のあるドメインを容易に特定しています。これはすべて自動化されたプロセスによるものです。ニューラルネットワークがこれらのリクエストを処理し、自動的に悪意のあるものを検出します。その情報は自動的にGuardDutyに流れ込み、お客様を保護します。もしこれを手作業で行うとすれば、圧倒されてしまうでしょう。ここでの自動化により、増え続けるデータを整理し、このインテリジェンスをGuardDutyに提供することができます。
セキュリティチーム内で私が見てきたもう一つの分野は、私たち全員が注目していることです。私たち全員がサポートチケットを持っており、これらのサポートチケットのほとんどは実際には人間が処理することを想定しています。しかし、新しいテクノロジーを使えば、これらのサポートチケットの多くを自動処理できるようになると考えています。
このプロセスの一部を自動化するために、Agenticワークフローを実装して、チケット解決の複雑さを軽減することができます。 Agenticワークフローとは、タスクを独立して実行するシステムです。エージェントは非常に明確で限定的なユースケースに特化しており、このプロセスを自動化するために計画を立て、反復し、ツールを使用する能力を持っています。
これは、私たちがAgenticチケットトリアージシステムをどのように使用しているかの例です。 エージェントの目標はサポートチケットを効率的に解決することで、そのプロセスにはチケットの読み取り、ツールの使用、反復が含まれます。分析に基づいてチケットを分類し、優先順位を付け、取るべきアクションを判断します。自動的に解決するか、 人による確認のためにエスケレーションするかを決定します。
チケットを開いて、確認が必要な様々な情報を見たことが何度あるでしょうか?データベースはこちら、顧客に関する情報はあちら、といった具合です。人間として高度な判断を下してチケットを解決する必要がある場合、私たちは包括的な全体像を提示できるはずです。このAgenticワークフローに興味がある方は、Clare Liguoriさんが公開している非常に興味深いGitHubリポジトリをご覧ください。このようなサーバーレスのプロンプトチェーンを構築するための優れた基盤を提供しています。 また、Amazon Bedrockを使用したサーバーレスおよびAgenticワークフローの作成に関する優れた自己学習コースもあります。
これにより、問題の自動解決に集中することができます。これは本当に素晴らしいことです。なぜなら、特にチケット解決のような多くのタスクは、正直なところ退屈だからです。絶対に必要だけれど、できれば避けたい面倒な作業です。高度な判断を使って、これは完璧だと判断できれば早いほど良いのです。つまり、複雑さを自動化し、高度な判断を必要としないものはすべて自動化するのです。
Simplexityの教訓とAWS Heroesの紹介
これが私のAmazonでの20年間と、多くの教訓、特に複雑さに関する教訓について考えたことです。これらが最も重要な教訓です。Amazonのディスティングイッシュド・エンジニアに話を聞けば、もっと多くの教訓が得られるはずです。私たち全員がこれに関する傷跡を持っており、苦労して学んできたからです。Simplexityにより、システムを安全に、より複雑になるように時間とともにスケールさせることができます。したがって、進化可能性を要件とし、複雑さを分割し、組織をアーキテクチャに合わせ、セルに分割し、予測可能なシステムを設計し、複雑さを自動化するのです。
私はここで自分の教訓を共有しましたが、皆さんにも独自の教訓があるはずです。そして、会場にいるHeroesの皆さんを称賛したいと思います。なぜなら、Heroesとは世界中の人々と継続的に教訓を共有し、コミュニティを構築している人々のグループだからです。53カ国から257人のHeroesがいます。彼らは、このプラットフォームで他の人々の成功を支援する現場の実践者たちです。彼らの話に耳を傾け、交流してください。彼らは、あなた自身のシステムを構築する上で価値のある教訓を持っています。
彼らは教訓を共有していますが、テクノロジーを活用して多くの善を成し、特に世界の食品廃棄問題に取り組んでいる企業がToo Good To Goです。彼らの進化について、VP of Engineeringの Robert Christiansenをお迎えしたいと思います。
Too Good To Goの成長と技術的進化
皆さん、まだ食べられる食品をゴミ箱に捨てたことがある人は手を挙げてください。あなたは一人ではありません。世界中で生産される食品の40%が廃棄されているのをご存知ですか?これは、お気に入りのピザ屋さんでピザを4切れ箱から取り出し、床に落として、そのまま腐るのを放置して立ち去るようなものです。食品廃棄は
食品廃棄は世界の温室効果ガス排出量の10%を占めており、航空産業全体の4倍にもなります。私たちが直面している環境問題の中で、食品廃棄は間違いなく最も愚かな問題です。Too Good To Goは2015年にコペンハーゲンで、レストランで廃棄される大量の食品に対する解決策を見出そうとした若い起業家たちによって設立されました。彼らは、人々が食品を廃棄させるくらいなら、割引価格で購入することを好むということを知っていました。
そのシンプルなアイデアは、余剰食品の世界最大のマーケットプレイスへと成長しました。ローンチ後の最初の数週間で、何百もの企業が余剰食品をマーケットプレイスアプリにアップロードし、何千人ものユーザーが売れ残った余剰食品の詰め合わせを受け取り、地球と財布の両方にとってWin-Winの関係を生み出しました。私たちの創業者たちは、強い信念とスマートなアイデアを持って始めた起業家でしたが、明らかに開発者ではありませんでした。当時のアプリの技術基盤は最も堅牢とは言えず、急速な成長に伴って問題が発生しました。
2018年、登録ユーザー数が100万人を突破した頃、プラットフォームは限界を迎え始めました。 当時のアプリケーションは、単一のMySQL instanceを使用した典型的なPHPアプリケーションでした。システムは毎日のように過負荷状態になっていました。私たちは宇宙船を作るようなことは望んでいませんでした。10人のエンジニアで、シンプルに保ちながらスケールすることだけを目指していました。そこで私たちは何をしたのでしょうか?まず、手の届く簡単な選択肢から始めました。Amazon Auroraの最大15個のリーダーノードをサポートする機能を活用することで、かなりの余裕を確保することができました。ユースケースを特定し、それらのインスタンスで個別のコネクションプールを使用しました。
次に、アプリケーションをSpringアプリケーションに書き換えることにしました。エンドポイントを1つずつ移行していきました。これにより、リソース管理、コネクションプーリング、キャッシュ、メッセージキューの統合、処理などの利点を活用できるようになりました。宇宙船を作る必要はありませんでした。既存のコンポーネントを組み合わせて少しカスタマイズするだけで、特に大量のトラフィックを扱う結果整合性のエンドポイントで、スケーラブルで高性能なものを実現できました。100万ユーザーの時点では限界に近かったのですが、これらの小さな改善により、サービス開始からわずか4年で1,000万人の登録ユーザーを達成することができました。
ユーザー数の成長は加速し続け、同時にビジネスサイドは新機能を求め、それが新たな課題をもたらしました。開発者が同じようなスケーリングの要件に直面した時、中央のツールボックスから選択できるようにしたいと考えました。シンプルさを保ちたかったのを覚えていますよね。そこで、言語とフレームワークを固定した集中型のアーキテクチャを採用しました。トランザクション処理、キャッシング、メッセージング、セキュリティ、バックグラウンドプロセスなどの共通パターンには要件が設定され、すべてのサービスで統一されました。これらのケースで言語とアーキテクチャを固定することで、技術的な複雑さが低減され、エンジニアの負担が大幅に軽減されました。
この時点で、私たちはトラフィックの大部分を結果整合性のあるソース、キャッシュ、Amazon OpenSearchから提供し、トランザクショナルデータベースを大量の読み取りトラフィックから保護していました。そしてこれにより成長が可能になりました。2020年までに、16の市場で2,400万人の登録ユーザーを獲得しました。しかし、食品廃棄は地球上のあらゆる場所で発生しています。より大きなインパクトを目指すことは、さらなる成長を意味し、その後、私たちは最初の新大陸である北米に進出しました。2020年、私たちは異なるパートナー、異なる習慣、異なるタイムゾーンに直面しました。初日から低レイテンシーで優れた顧客体験を提供する、ローカルなサービスを目指しましたが、USで新しいアプリやインフラを構築したくはありませんでした。シンプルに保つことを忘れないでください。AWSを利用していたことで、グローバルに展開されているリージョンを活用し、北米でローカルに処理することが可能でした。
しかし、複数のリージョンで展開するということはどういうことを意味するのでしょうか?既存のものを拡張しながらシンプルさを保ちたいと考えましたが、それは決して容易なことではありませんでした。顧客やパートナーのトランザクションを彼らのホームリージョンに固定し、トラフィックの大部分を処理するデータを分散させるアプローチを採用しました。これには、ローカルでデータが更新されるたびに他のリージョンに更新を配信するためのAmazon SNSトピックとAmazon SQSキューを組み込む必要があり、開発者が使用できる新たなパターンが作られました。
うまく機能しましたが、多大な労力を要し、地域の数が増えていくとどうなるか想像できるでしょう。この仕組みを活用して、今年はPhoenix、Detroit、Clevelandなど、北米全域での展開を続けることができました。同じ青写真を使って、今度は別の大陸であるオーストラリアでも、最小限の労力で展開することができました。そして現在、私たちは1億人以上の登録ユーザーと17万5,000のアクティブなビジネスパートナーを抱える活気あるコミュニティとなっています。
これまでToo Good To Goは4億食以上の食品廃棄を防いできましたが、私たちはさらに大きなインパクトを生み出したいと考えています。今年、私たちは新製品のToo Good To Go Parcelを立ち上げました。賞味期限が近づいた食品を購入できるようにすることで、製造段階での食品廃棄を防ぐことができます。スタートアップにとって成長は望ましいものですが、技術的な観点からは波乱の道のりとなることがあります。ひとつ確実なことは、Too Good To Goでの食品救済は、シンプルであり続けなければならないということです。なぜなら、現在私たちは1秒間に4食を救っていますが、同じ1秒間に8万食が廃棄されているからです。私たちの地球の健康はこれにかかっているため、大きな可能性が私たちの前にあります。最後に質問を投げかけさせていただきます:あなたはどのように食品廃棄を減らしていきますか?ありがとうございました。
Amazon Aurora DSQLと同期された時間の重要性
素晴らしいですね。RobertやToo Good To Goのようなお客様の話を聞くのは大好きです。彼は、成長、拡大、そして複数の地域にまたがるデータの取り扱いに直面した複雑さを見事に表現してくれました。このような企業とその課題を見ていく中で、私たちはこれをもっと簡単にするためにどのようなテクノロジーを構築すべきかを考えています。複雑さの負担について考えると、私たちは常にシンプルなシステムを構築することで、お客様が直面している複雑さの負担をより多く引き受けられるようにしたいと考えています。
目標は、例えばデータベースを扱うお客様の体験をできる限りシンプルにすることです。しかし、時間の経過とともに複雑さの負担を見ていくと、最初にAWSを始めた頃は、おそらくお客様自身がデータベースを運用していたか、あるいは今でもよく見られるように、オンプレミス環境のアーキテクチャをクラウドにリフト&シフトして、Amazon EC2上で自前のデータベースを運用し、他のAZにリードレプリカを置くなどしていました。複雑さの負担は本当にお客様側にありました。最初のステップとして、Amazon RDSでそれらのデータベースを管理するようにしました。これにより運用の複雑さは大幅に軽減されました。パッチ適用、アップグレード、バックアップ、読み取りのスケーリングなどが不要になり、高可用性の維持という複雑さにも確実に対応し、リカバリプロセスも簡素化されました。
しかし、Amazon RDSの中では依然として標準的なデータベースを実行していました。正直なところ、これはデータベース作業のイノベーションを行うための良い基盤とは言えませんでした。なぜなら、ほとんどのデータベースは変更が非常に困難な一つの大きなモノリスとして構築されているからです。最初に取り組んだのは、コンピュートをストレージから切り離すことでAmazon Auroraを構築することでした。これにより、ログがデータベースとなり、より迅速に進めることができるようになりました。ストレージをエンジンから分離することで、ストレージを気にすることなく、よりシームレスにスケールできるようになりました。
私たちは、ServerlessやAurora Limitlessのような革新的な技術で、ゼロまでスケールダウンすることを実現してきました。そして火曜日、MetaはAmazon Aurora DSQLという、Auroraの次世代製品を発表しました。DSQLは、Too Good To Goが直面したような、世界中の顧客にサービスを提供できるアプリケーションを可能にします。もし彼らがDSQLを利用できていたら、彼らのアーキテクチャは異なるものになっていたでしょうか?DSQLは中断のないフェイルオーバーを可能にし、パフォーマンスとコンプライアンスの両方に最適化されたデータ配置を実現できます。何億人もの顧客にサービスを提供するために必要な回復力を備えた、グローバルに分散されたアプリケーションを構築するためのツールを提供します。
DSQLのすべての機能について詳しく説明するつもりはありませんが、先ほどお話しした教訓を、DSQLの設計段階で複雑さを管理し、時間とともに進化するための適切な基盤となるようにどのように適用したかの例として、DSQLを取り上げたいと思います。これは、それぞれが分散され回復力のある独立したコンポーネントの階層構造であり、先ほど説明した原則と同じものを使用しています。システムの分解、より小さなビルディングブロックへの分割、それぞれのビルディングブロックが特定のタスクに特化した高い凝集性を持ち、低い結合度を実現し、それらのコンポーネント間の明確に定義されたAPIを通じて通信することで、個々のコンポーネントを独立してスケールできるようになっています。
これにより、システムをきめ細かくコントロールすることができ、各コンポーネントのニーズに応じて個別にスケールすることが可能になります。また、各コンポーネントの特定の要件に応じてセキュリティをカスタマイズすることもできます。DSQLの主要なビルディングブロックを見ると、フロントエンド、SQLの処理のほとんどを担うQuery Processor、トランザクションをどこでコミットできるかを調整するAdjudicator、短期ストレージを提供するJournal、そしてこれらを長期ストレージにマージするCrossbarがあります。
これらのコンポーネントはそれぞれ異なる方法でスケールします。Query Processorはセッション数に応じてスケールし、Adjudicatorはトランザクション数に応じてスケールし、Journalはこれらのストレージシステムで実際に処理できるスループット量に応じてスケールし、CrossbarはJournalの数とデータベースのサイズに応じてスケールします。これらを従来のデータベースのように1つの大きなモノリスにまとめてしまうと、これらのコンポーネントの中で最大のスケールに合わせてすべてをスケールしなければならず、非常に非効率的で管理が難しくなります。今のアプローチでは、コンポーネントを独立して進化させることができます。
これらのコンポーネントがどのように連携して動作するのか、簡単な読み取りトランザクションから見ていきましょう。ここLas Vegasのローカルなレストランでピザを注文しようとしているユーザーを想像してください。皆さんも書いたことのあるSQLクエリです:評価が4以上のレストランを検索するSelect文です。この時、バックグラウンドで何が起こっているのでしょうか?アプリケーションはフロントエンドに接続し、Query Processorを割り当てます。Query Processorは、各セッションのために構築され割り当てられる非常に小さな独立したコンポーネントです。SQLがそこに到着すると、トランザクションの開始時にタイムスタンプを取得し、ローカルクロックを読み取ってからリクエストを送信します。その前に、Shard Mapと呼ばれるものを参照します。
ストレージでは、データはデータベースキーに従って実際にシャーディングされているため、どのストレージエンジンがこのデータを保持しているかを理解するためにシャードマップを確認する必要があります。これは読み取り操作なので、トランザクションパスを経由する必要はなく、 データを取得するために直接ストレージにアクセスします。
Amazon Aurora DSQLのストレージは、一般的なデータベースストレージとは異なります。通常のデータベースストレージではデータを含むページを取得しますが、DSQLのストレージはデータベースを理解できる特徴を持っています。 つまり、フィルタリングなどの操作を実行できるため、ストレージエンジンに特定の行を要求すると、 必要なデータをすべて含む完全なページではなく、その特定の行または行のセットのみを取得します。これは、従来のデータベースにおける最大のボトルネックの1つを解決しています。
結果が返されユーザーに表示された後、ユーザーはピザを購入することを決定します。これは対話型トランザクションと呼ばれるものです。Amazon Aurora DSQLの開発者であれば、対話型トランザクションに馴染みがあるでしょう。トランザクションを開始し、データを取得し、クライアントで作業を行い、判断を下し、さらにSQLを書き、顧客に戻り、最終的にコミットします。これは、すべての作業を一度に行う必要があるAmazon DynamoDBのトランザクションとは大きく異なります。クエリはより長くなり、レストランを選び、メニューからアイテムを選択し、注文を行ってからコミットを実行することになります。
SQL全体がパッケージとしてQuery Processorに送信され、そこですべてが統合されます。DSQLでは、Query Processorはスナップショット分離を使用するホールディングタンクとして機能し、ローカルメモリ上でデータの読み取りと書き込みを実行できます。コミット時にAdjudicatorに完全なトランザクションを送信するまで待機します。すべての単純なSQL文は、Query Processorが存在する1つのリージョン内で処理され、リージョン間の相互作用は、Adjudicatorが異なるリージョンで実行されているときのコミット時にのみ発生します。これは、読み取り、書き込み、更新が単一のリージョンデータベースと同じくらい高速であることを意味します。
Query Processorは、小さなFirecracker VM内で実行され、ベアメタルであるQuery Processorホスト上に配置されるという点でユニークです。ベアメタルホスト上のmicroVM内で数千のQuery Processorを実行できます。顧客の判断とコミットを待っている間にクライアントとQuery Processor間の接続が休止状態になった場合、このmicroVMを一時停止できます。顧客が操作を再開すると、ミリ秒単位でmicroVMのスナップショットを復元でき、長時間実行されるトランザクションに最適化されています。
Query Processorでは、 Snapshot Isolationを採用しています。これにより、各トランザクションはそのトランザクションが開始した時点のデータベースの一貫性のあるスナップショットに対して操作を行います。この仕組みによって、読み取り操作が書き込み操作をブロックすることなく、またその逆も可能となります。トランザクションが開始されてSQLの実行フェーズに進むと、この一貫性のあるスナップショットが見えるようになり、insertやupdateなどの書き込み操作が発生した場合でも、すぐにはストレージに適用されない仕組みになっています。
その代わりに、これらの書き込みはトランザクション専用のワークスペースにローカルにスプールされます。これにより仮想的な書き込み機能が実現され、同じトランザクション内での後続の読み取りでは、保留中の変更をすべて確認することができます。トランザクションには、Write Setと完全なPost Image(すべての更新が適用された後のデータベース内の行の状態)の両方が含まれます。このWrite SetとPost ImageはAdjudicatorに送信されます。
Adjudicatorは、SQLの書き込みパスに位置し、トランザクションのコミットの可否を判断します。その役割は、トランザクション間の競合を検出・解決し、書き込みの一貫性を確保することです。Query Processorは、判断に必要なすべての情報を含むペイロードを作成してAdjudicatorに送信します。このペイロードには、トランザクションによって変更されたすべての項目を含むWrite Set、トランザクションの影響を受けるすべてのテーブル行のコピーを含むPost Image Set、そしてトランザクションのコミットまたはアボートの判断に重要なトランザクション開始時刻が含まれています。
ほぼ同時にAdjudicatorに送信された2つの並行トランザクションを見てみましょう。Transaction AがTransaction Bよりもわずかに早くコミットを送信した場合、Adjudicatorはトランザクション開始時刻とWrite Setを確認してQuery Processorからのペイロードを比較します。Adjudicatorは、T startの後に提案された書き込みの中で、重複または一致するキーでインデックス付けされたテーブル行への書き込みがないかを確認します。両方のトランザクションがキーCで識別される行を更新しようとしているのを確認した場合、同時に行を変更することはできません。そのため、Transaction Aはコミットできますが、Transaction Bはアボートしなければなりません。トランザクションのWrite Setが互いに交差しない場合、Adjudicatorはコミットを許可し、トランザクションにコミットタイムスタンプが割り当てられます。
従来のデータベースでは、永続性はストレージレイヤーで実現されています。トランザクションは、ストレージレイヤーに永続的に書き込まれた時点でコミットされたとみなされ、障害発生後のコミット済みトランザクションのリカバリを処理し、リカバリのためにメモリ内のデータとストレージを同期させる必要があります。私たちはこれをよりシンプルにすることにしました。Amazon Aurora DSQLでは、Journalが短期的な永続性を担当します。トランザクションはJournalに書き込まれた時点でコミットされたとみなされ、Journalは各ストレージエンジンのスループット能力に基づいて水平方向にスケールできます。これにより、Journal内にコミット済みトランザクションの完全な順序付けされたストリームが作成され、この順序付けはシステム全体の一貫性を維持するために重要な役割を果たします。その後、CrossbarがJournalからトランザクションの取り出しを開始し、ストレージエンジンに移動させます。
ここでは、審査担当者がジャーナルに移動し、その時点で取引が完了したことを示す確認応答をお客様に送り返すことができます。このシステムの各コンポーネントは独立して動作しており、これは複雑さを管理する原則に従ったアーキテクチャの素晴らしい例です。ここで簡単に触れたことがありますが、startとcommitというこの2つのことを覚えておいてください。これは、異なるコンポーネント間のシンプルな連携を維持しながら、複雑さに対処する素晴らしい例です。これらのstartとcommitのタイムスタンプはローカルクロックを読み取りますが、分散システムではクロックを使用することはほぼ不可能です。時間の概念は私たちの生活の中で基本的なものです。
皆さんは私が8時30分に始めたことを知っていて、今も時計を見ながら、いつ終わるのかと考えているでしょう。私たちのほとんどが手首に時計を着けています。私たちにとって、多かれ少なかれ正確な時間で十分で、おおよその時間で問題ありません。
分散システムで時間を使用することは、常に不可能だと考えられてきました。一貫性を作り出し、リーダー選出を行い、2フェーズコミットを実行するなど、時間を使用できないために必要だった、これらすべてのことを実現するために、驚くべき素晴らしいアルゴリズムが時間とともに開発されてきました。70年代末にLeslie Lamportが書いた非常に有名な論文があります - 彼はこの研究でTuring Awardを受賞しました。「Time, Clocks, and the Ordering of Events in a Distributed System」は、基本的に時間を使用することはできないと述べており、実際に時間を使用できないために考慮しなければならない他のさまざまな機能があると説明しています。
分散ロック、ベクトルクロック、時間を使用できないために発明されたこれらすべての仕組みを見てみると、数年後に非常に興味深いことが起こりました。1991年に、同じくTuring Award受賞者のBarbara Liskovが、同期されたクロックの実用的な使用法に関する論文を書きました。彼女がクロックにアクセスできさえすれば、はるかにシンプルに構築できるこれらのアルゴリズムすべてについて説明し始めたのは素晴らしいことです。彼女はまた、これらの分散クロック、同期されたクロックがシステムで利用可能になったのはごく最近のことだと書いています。
さて、「ごく最近」とは30年後のことを指します。30年後、ついに高精度な同期クロックを手に入れ、それによってシステムや複雑なアルゴリズムをよりシンプルな方法で構築できるようになりました。現在、データセンター内には完全に異なるインフラストラクチャ、第3のバックボーンがあり、それは1つのことだけのために専用化されています:正確な同期された時間を提供することです。実際に行っているのは、衛星からの時刻同期で、それを完全に分離されたこのバックボーンを通してNitroに搭載されている部分に伝送し、そこでAmazon Time Sync Serviceを使用して正確な時間を取得できるようにしています。
クロックの精度はマイクロ秒単位です。昨年、Peter O'Bradyは基調講演で、これをマイクロ秒レベルのクロックにまで改善し、各Amazon EC2インスタンスで利用可能になったことについて話しました。その仕組みはこうです:衛星が原子時計に到達し、この完全な第3レベルのバックボーン上で、FPGAハードウェアと特殊なNitroカードを使用して、ドライバーやネットワークバッファなどを排除しています。これらは、数十ミリ秒以上の精度が得られなかったネットワークタイムプロトコルであるNTPを常に制限していた要素です。これらのクロックの精度は、1マイクロ秒台に収まっています。
ここで注目すべき点は、TコミットとTスタートがこのハードウェアクロックから取得されているということです。つまり、トランザクションがいつ開始され、いつコミットされたかについて、正確な比較が可能になります。これはAWS以外ではほとんど実現できない、ユニークな環境です。正直に申し上げますと、これらのクロックが非常に正確だと言えるものの、完全に正確なクロックは実際には存在しません。わずかなドリフトや通信の差異、どこかでの遅延が常に存在し、取得する時刻それぞれにエラーの範囲が存在します。そこで私たちはClockBoundというシステムを構築しました。これはEC2インスタンス上で動作するデーモンで、GitHubで公開されているライブラリとして利用できます。これにより、正確な現在時刻だけでなく、その周辺の潜在的なエラーの範囲も得ることができます。
これらのエラーの範囲は、最も早い時刻は何か、そしてこれが正確な時刻かを考えることで活用できます。最も早い時刻のドリフトはどの程度か、そしてこの時点での最も遅い時刻は何かを判断し、どのクロックを採用するかを決定します。これにより、ナノ秒の精度を持つナノ秒クロックが実現します。また、潜在的なエラーがどの範囲にあるかという境界も得られます。これは悪くありません - このエラーの範囲を利用して、あるイベントが発生した可能性のある最も遅い時刻と最も早い時刻を考慮することができます。
同期された時間を利用できるため、その仕組みは非常にシンプルになります。これは、現在では強い整合性も提供しているAmazon DynamoDBのグローバルテーブルで使用しているのと同じテクノロジーです。同期された時間にアクセスできるため、世界規模での強い整合性を実現できます。正確なクロックは複雑さを大幅に軽減します。私が取り組んできたこれらのアルゴリズムをご覧ください - 分散トランザクション、コンフリクト解決、リーダー選出、2フェーズコミット、Paxos、Raft - これらはすべて、単純に時間を使用できれば、はるかにシンプルになるはずです。
Mattも火曜日のプレゼンテーションで、次世代システムを構築するためのビルディングブロックを提供したいと常に考えてきたと話していました。Compute、Storage、Database、Network、Securityが必要で、これらが元々のビルディングブロックでした。しかし今、私たちはこれらすべてにさらに基本的なビルディングブロックを追加しました。それが「時間」です。皆さんには、アプリケーションで構築しているアルゴリズムやメカニズムを見直し、同期された時間がシステムの複雑さを大幅に軽減できるかどうかを検討していただきたいと思います。
今後1年の取り組み: 世界中の難題解決の支援
以上が本日お伝えしたい内容でした。ご清聴ありがとうございました。これから1年間、私が取り組もうと考えていることについて、皆さんの注目を集めたいと思います。Now Go Build TVシリーズをご覧になった方はご存知かと思いますが、私は若い企業や組織が世界の難しい問題の解決に取り組むことに非常に情熱を持っています。国連の持続可能性目標によると、2050年までに世界の人口は20億人増加すると言われています。彼らの食料をどうするのか?医療をどう提供するのか?経済的に持続可能な未来をどのように確保するのか?
これらの問題に取り組もうとしている若い企業や組織が多くあり、私は彼らを本当に支援したいと考えています。その取り組みの一つとして、Tech Rescueという組織を立ち上げました。AI for Changemakersのためのコホートシステムを持ち、CTOのためのFellowshipも設立しました。私のチームは彼らの技術力の向上を支援しており、これらの若い企業が世界のために技術を活用する方法についてアドバイスをしてくれるヒーローたちに、大変感謝しています。
これらの組織から聞く話として、技術者の数が非常に少なく、時には2週間や1ヶ月程度の誰かの時間があれば本当に助かるということがあります。もし皆さんが自分の仕事で何か良いことをしたい、そして技術力を活かして本当の意味で違いを生み出したいと考えているなら、これらの組織に目を向けてみてください。皆さんの時間を提供してください。大規模システムを構築してきた経験を活かして、この世界に本当の変化をもたらすことができます。技術者として、私たちは美しいものだけを作ってきたわけではありませんが、技術を使って世界の難しい問題を解決することも私たちの責任なのです。
さて、真面目な話はここまでです。今夜はこのパーティーで過ごすつもりです。Las Vegas Festival Groundsで皆さんにお会いできることを楽しみにしています。今夜はWeezerとZeddがLas Vegas Festival Groundsで演奏します。では、そこでお会いしましょう。パーティーの時間です!
※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。
Discussion