📖

re:Invent 2024: AWSが提案するMicroservicesの適切なサイジング戦略

2024/01/01に公開

はじめに

海外の様々な講演を日本語記事に書き起こすことで、隠れた良質な情報をもっと身近なものに。そんなコンセプトで進める本企画で今回取り上げるプレゼンテーションはこちら!

📖 AWS re:Invent 2024 - Right-sizing your application services: Rethinking microservices (ARC324)

この動画では、AWSのSolutions Architectとして11年の経験を持つTod Goldingが、Microservicesのサイジングについて語ります。多くの組織がMicroservicesを採用する際、他社の実装をそのまま真似たり、サービス数の多さを価値の指標としたりする問題点を指摘。代わりに、Domain-driven DesignやEvent Stormingなどの手法を用いつつ、チームのスキルセット、ビジネス課題、運用プロファイル、ワークロードの性質といったコンテキストを考慮した適切なサイジングの重要性を説明します。また、システムの進化に合わせて粗粒度なサービスから始め、実際の運用データに基づいて段階的に分割していく具体的なアプローチも提示しています。
https://www.youtube.com/watch?v=ZOQwxxgvKJs
※ 動画から自動生成した記事になります。誤字脱字や誤った内容が記載される可能性がありますので、正確な情報は動画本編をご覧ください。
※ 画像をクリックすると、動画中の該当シーンに遷移します。

re:Invent 2024関連の書き起こし記事については、こちらのSpreadsheet に情報をまとめています。合わせてご確認ください!

本編

Tod Goldingによる自己紹介とMicroservicesの進化

Thumbnail 0

皆様、本セッションにお越しいただき、誠にありがとうございます。この時点で、re:Inventで皆様のエネルギーも大分消耗されているかと思いますが、朝早くからお集まりいただき、大変嬉しく思います。本日のトークを皆様にお届けできることを楽しみにしております。スライドにもありますように、私はTod Goldingと申します。AWSのSolutions Architectとして約11年間、クラウドアプリケーションアーキテクトおよびクラウドインフラの分野で、SaaSソリューションやAWS上のあらゆる種類のアプリケーションを構築・提供するさまざまな段階の組織と協力してきました。

私は、多くの興味深いアプリケーションアーキテクチャ戦略が登場し始めた初期からこの分野に携わる幸運に恵まれました。Microservicesが広く採用される前の、まさにその黎明期から関わることができました。Microservicesについて講演をしていた当時、人々がそれについて初めて耳にする時代だったことを覚えています。現在では、Microservicesが一般的なアプリケーションアーキテクチャとして、そしてクラウドの価値提案に非常に適していることが分かっています。スケール、レジリエンス、消費の最適化など、アプリケーションで実現しようとするすべてのことに対して、Microservicesは素晴らしい適合性を示しています。今日でも、私が関わる多くの組織がMicroservicesをソリューション構築の主要な方法として積極的に採用しています。

Microservicesの課題:コンテキストの重要性

私たちはしばらくの間Microservicesの段階にあり、多くの人々がこの戦略を採用してきました。私が見てきた懸念の1つは - これは普遍的なものではなく、皆様全員に当てはまるわけではありませんが - Microservicesの方法論と価値提案を取り入れた後、他の人々がどのように実装しているかという型にはまったモデルをそのまま採用してしまうことです。彼らは優れたMicroservicesアーキテクチャの例を見て、それを丸ごと自分たちの組織に持ち込んでしまいます。私が感じる課題は、Microservicesの意図と価値提案は間違いなく正しく良いものですが、コンテキストが欠けているということです。

原則として価値のあるものであっても、それらの原則を私たちの組織の現実に合わせて適用する必要があります。どのようなチームがいるのか、チームのスキルセットはどうなのか、どのようなビジネス課題を解決しようとしているのか、組織の運用プロファイルはどうなのか、そしてワークロードの性質はどうなのか、といった点です。私には、私たちが何をしているのか、なぜそれをしているのか、そして私たちの組織にはどのようなタイプのMicroservicesが適しているのか、というコンテキストが途中で失われてしまったように感じます。その代わりに、組織は適切な考慮なしにMicroservicesを特定して進めてしまっています。

私が組織を訪れると、大規模で重厚なMicroservicesベースのソリューションを構築し、現在はそれを解体している組織に出会います。それは複雑さが増しすぎたか、価値が見えないためです。彼らが行ったことと得られた価値とのトレードオフがうまく合っていないのです。これはMicroservicesが悪いアイデアだったからではなく、システムにどのMicroservicesを組み込むかを決定し構築を始めた時に、これらのコンテキスト情報をすべて考慮しなかったためです。私にとって、特定の環境に適したサービスの適切なサイズは何か、そして適切な粒度は何かについて、より多くの問いかけを始めることが本当に重要だと感じています。

私たちは、あらゆるMicroservices環境で目指すべき良い特性を追求し続けますが、何が良いMicroservicesアーキテクチャなのかについては、より柔軟な姿勢で考え、組織それぞれに適したMicroservicesのスタイルを見つけてもらおうと思います。これが、今日のトークのポイントです。300レベルのトークとして、コードを書くことはせず、システムをMicroservicesに分解する際に考慮すべきパラメータについての考え方のモデルを議論します。それらのサービスがどのように誕生し、適切なMicroservicesを実現できているかを評価するための新しい視点をどのように追加できるか、そしてアーキテクチャの境界線をどこに引くべきかを見極めながら、リアルタイムでアーキテクチャをシフトさせ、進化させていく方法について見ていきます。皆さんがここに来た理由や期待と合致していることを願っています。

Thumbnail 310

始める前に、Microservicesの基本原則は正しく、有効で、システムを分解して構築するための優れたアプローチであることを明確にしておきたいと思います。私たちは今でも、アジリティ、イノベーション、より小さな影響範囲、疎結合といった価値の実現を目指しています。自律的なチームが、これらのサービスで作業し、ストレージをカプセル化し、契約に基づいて作業することを望んでいます。ここで話されている原則、論文、そして他のプレゼンテーションで語られているこれらの原則は、すべて堅実な基礎原則であり、私たちは今でもこれらの成果を達成したいと考えています。

これらの成果を達成するために、環境内のサービスサイズが前提として決まっているとは思いません。環境に応じて、Microservicesのサイズを変えることができ、現実的な要因を考慮に入れることができます。アジリティ、効率性、影響範囲は、異なるアーキテクチャによって異なる意味を持ち、それが集中する場所や、私たちが注力したい場所は組織によって異なります。他の人々が行っているブループリントをそのまま採用するのではなく、コンテキストを加えたいのです。このプレゼンテーションでは「コンテキスト」という言葉を何度も聞くことになりますよ。

Microservicesのサイジングに関する誤解と課題

Thumbnail 400

Thumbnail 420

私たちがこの状況に至った理由の一つは、Shiny Object Syndromeだと思います。私はエンジニアで、新しいものが好きです。新しいツールや技術を見ると、正直に言って楽しいので、それに夢中になりたくなることはわかります。Microservicesの初期の例を見ると、企業が環境内の大規模なサービスのウェブを見せてくれて、彼らが行っているクールなことや、それらをデプロイ可能にし、Circuit Breakerを実装し、フォールバックパターンを実装するために構築している素晴らしいツールについて示してくれました。Netflixはこの分野で様々なクールで興味深いことを行っており、今でもそれを続けています。しかし、これらの人々は非常に複雑な耐障害性プロファイルを持つ、大規模なスケーラブルシステムを構築しているのです。

Thumbnail 460

その結果、人々はMicroservicesの数を、ソリューションの品質と価値を示す指標のように見なすようになってしまいました。人々は部屋に入って「私たちはMicroservicesを使っています」と言うことに誇りを持っていましたが、それだけではありません。「500個のMicroservicesがあります」と言うのです。500個あるという事実が、すごく素晴らしいことをしているという印象を与えると考えていたのです。私がいつも疑問に思うのは、本当に組織に500個のMicroservicesが必要なのか?どうやってその数に至ったのか?ということです。

私が思うに、それはユニバースに対する魅力と見方でした。誰もが「サービスが小さければ小さいほど良い」と考え、大きな図の中により多くのサービスを表示してマイクロサービスをたくさん持っていることを示せば示すほど、マイクロサービスの価値提案を実現できているという安心感を得られると考えていました。500個のマイクロサービスを持つあの企業にとっては、それが正解だったのかもしれません。ただ、マイクロサービスの数が推進要因となり、まるで何か良いことや価値のあることを成し遂げたかのような指標になってしまうことに、私は不安を感じるのです。

Thumbnail 560

私はそういった考え方から離れ、むしろマイクロサービスの数に関係なく、それらから本当の価値を得られているかどうか、そして組織とその運用、さらにはこれらのサービスを構築・デプロイ・作成する全体的なプロファイルが、そもそもマイクロサービスを採用した理由となった広範な価値を得られているかどうかを重視したいと考えています。 これは、サイズに対するバイアスと、多くの問題の発端に関係しています。少し古い話になるかもしれませんが、私たちの多くは、アーキテクチャに対して何らかの粗粒度な概念を持つユニバースからスタートしました。WebアプリケーションやStorageティアを持つN層アーキテクチャで仕事をした経験が誰にでもあり、すべてをこのティアに入れ、その中にサービスの概念を持っていました。しかし、結合はおそらく少しタイトで、デプロイの単位は通常ティア全体でした。あるサービスで何かを修正する場合、そのサービスを修正し、ティア全体をデプロイすることが私たちのデプロイ単位でした。もちろん、これがこれほど多くの問題を引き起こした理由です。テスト、デプロイの影響範囲、デプロイの頻度 - すべてが重たかったのです。Monolithをデプロイする際、それらは重たいものでした。これが、大きいものや粗粒度なものは本質的に悪いという考えにつながりました。

Thumbnail 620

Monolithicアーキテクチャの根源が、粗粒度なものはすべて問題があるという感覚を私たちに与えたのです。 マイクロサービスが登場したとき、細粒度が良いという考えが生まれました。マイクロサービスという概念は、サイズに対するこだわりを持ち、サービスが小さければ小さいほど良いという示唆を含んでいました。プレゼンテーション後によく人々が私のところに来て、適切なサイズについて質問し、ほとんど何もしないサービスについて議論し、極めて小さいことが優れているという信念を持っていました。

Thumbnail 670

Thumbnail 710

私たちの環境でマイクロサービスに到達する方法を見ると、様々な方法論が登場してきたことがわかります。Domain-driven designは以前から存在していましたが、サービスを特定する方法としてこの分野に大きく適用されるようになりました。これらの方法論は、組織がマイクロサービスを決定し、それらを実装するために使用できる技術を特定するのに役立ちました。Domain-driven designは確かに、Bounded Contextsやその他のマイクロサービスの機会を特定する効果的な方法です。 また、Event Stormingがマイクロサービスへのもう一つのアプローチとして採用されているのも見てきました。一部の組織では両方の方法論を組み合わせて実装しており、これらのアプローチにはさまざまな組み合わせがあります。

Thumbnail 750

これらはマイクロサービスに到達する有効な方法ですが、主にドメインの観点からのみ - ドメインオブジェクトや名詞に焦点を当てて - 検討しています。 私がオブジェクト指向プログラミングを最初に学んだとき、システムについての文章を書いて名詞に下線を引き、それらをオブジェクトの候補とするように教えられました。製品やカタログなどの要素を特定し、これらが私たちの環境におけるマイクロサービスになるはずだと考えました。スケールや効率性を考慮しましたが、このプロセスには私が最も強調している「コンテキスト」が欠けています。ドメインのコンテキストは持っていますが、ビジネス、チーム、その他の重要な考慮事項のコンテキストが欠けているのです。

Value-driven Microservicesサイジングの提案

Thumbnail 790

システム内のサービスを検討する際、盲目的なサイジングから脱却し、データと価値に基づいたサイジングに移行したいと考えています。私たちが開発してきたMicroservicesのセットに疑問を投げかけ、そのサイズが本当に適切な価値をもたらすのかを問い直す必要があります。これらが優れたMicroservicesなのか、それとも不適切なのか、どのようなデータが判断材料となるのかを考える必要があります。以前、ある組織と仕事をした際、最初の候補となるMicroservicesについての議論から2ヶ月後、200個のMicroservicesをリストアップしたスプレッドシートが返ってきました。これだけ多くのサービスを作ることに本当に価値があるのか、そしてこれほど広範な分割を支持するデータは何なのかという疑問が生まれました。

Thumbnail 890

Thumbnail 900

私にとって、この問題の一部は用語の見直しから始まります。 Microservicesという概念は、最初に登場した時には適切な呼び方でした。 なぜなら、「Micro」という言葉は、より小さなサービスを作るという私たちの目標を強調していたからです。「Micro」という用語は、小規模なサービスを開発したいという私たちの意図を効果的に伝えていました。

Thumbnail 920

しかし、何年もMicroservicesを実装してきた今、「Micro」という言葉は、サイズが必ず小さくなければならないという含意を持つようになってしまいました。 私としては、Microservicesという言葉から離れ、システム内のサービスとして単純に呼びたいと思います。その中には小さいものもあれば、そうでないものもあります。結果的にすべてが小さなサービスになったとしても、それはそれでいいのですが、それはMicroという考え方に従わなければならないと感じたからそうなったのでしょうか?

Thumbnail 950

興味深いことに、昨年本を書いていた時、ある章で一貫してMicroservicesという言葉を使っていました。 技術レビュアーからフィードバックをもらった際、なぜそれらをMicroservicesと呼んでいるのかと質問されました。サービスをMicroservicesと呼ぶことが私のデフォルトの言い方になっていましたが、実際にはそれらのサービスは必ずしも小さくなかったのです。レビュアーは単にServicesと呼ぶことを提案しました。そこで私は章全体を改訂し、用語をServicesに変更しました。それの方が包括的で、Microが必ずしも小さくなくてもいいという考え方を促進できると感じたからです。業界全体がMicroservicesという呼び方をやめるべきだと主張しているわけではありません - その用語で構いません。ただし、実際の作業をする際には、「Micro」という名称に縛られて、すべてを小さくしなければならないと考えないでください。

Thumbnail 1000

Thumbnail 1010

Domainを超えて考えてみましょう。Domainはこれにアプローチする良い方法ですが、これらの環境のサイジングに関して他に何が重要なのかを考える必要があります。 他にどのような要因を考慮すべきでしょうか? 環境のサイジングを考える際の重要な点を挙げるとすれば、Bounded Contexts、相互作用、Loose Couplingについての適切な質問をすることは間違いありません。しかし、Operational Complexityについても考える必要があります。システムを分割することで、Blast Radiusの改善や、より小規模で頻繁なデプロイメントといった優れた運用上のメリットが得られますが、高度に分割された環境は分散型であるがゆえに、依然として管理が難しいのです。

私が関わっている組織の中には、構築したマイクロサービスの運用の複雑さが増しすぎて、DevOpsチームが対応に追われているために、マイクロサービスを見直している組織があります。また、レジリエンスのプロファイルも考慮する必要があります。つまり、システムのある部分が全く変更されない、あるいは障害が発生しても他のシステムに影響を与えないような部分なのかどうかということです。環境における消費のボトルネックはどこにあるのでしょうか?80-20の法則に従って、ユーザーが特に集中して利用する部分はどこで、小規模化することがスケールにとって本当に価値があるのはどの部分なのかを把握する必要があります。

ビジネス上のプレッシャーも考慮する必要があります。完全に分解された環境を実現することがどれだけ重要なのでしょうか?あるいは、システムの中で最も価値のある部分にターゲットを絞ってマイクロサービスを実装し、他の部分はより粗粒度のままにしておくことで、良い結果を得られるのではないでしょうか?リリース頻度も重要な要素です。システムのある部分がめったに変更されないのであれば、デプロイの俊敏性やサービスを小規模にすることによる他のメリットからは、あまり価値を得られないことになります。

チームのプロファイルは、疑問視する人もいるかもしれませんが、重要な考慮事項です。マイクロサービスの価値提案の重要な部分、特に何千人もの規模の大きな組織では、チームの自律性でした。チームは自分たちのサービスに関する契約を持ち、他のサービスと連携しながら素早く動くことができました。しかし、20人の開発者で200のマイクロサービスを持つ組織ではどうでしょうか?そのモデルでの所有権はどうなるのでしょうか?チームの自律性はどのように整合性を取るのか、あるいは全てのチームメンバーが200のサービス全てを知っている必要があるのでしょうか?これらのサービスを構築するだけでなく、サポートしてトラブルシューティングできることも考慮する必要があります。小規模であることで理解しやすくなりますが、それでもオーバーヘッドを考慮する必要があります。私にとっては、左側にあるこれらの要因を全て考慮し、Domain-Driven DesignやEvent Stormingなど、マイクロサービスを見極めるのに役立つ手法を活用することが重要です。

Thumbnail 1210

そして、組織に適したサイズになるようにします。常に正しい判断ができるわけではなく、途中で学んでいくことになります。しかし、私が許容したいのは、上部に大きな紫色のサービスがあっても、それが間違いだとは感じないということです。なぜなら、もし全てが下部の緑色のボックスのようでなければならないとすれば、なぜそうする必要があるのか疑問に思うからです。これらの要因によって、異なる粒度が示唆される場合が確実にあるからです。

Microservicesの適切なサイジングを決定する要因

Thumbnail 1250

私にとって、複雑さに対するリターンという考え方がより重要になってきています。 レジリエンスのための構築、スケールのための構築、クラウドやマイクロサービスアーキテクチャの一部である、これらの素晴らしい価値提案のための構築は素晴らしいことです。しかし、あなたの組織のフットプリントはどの程度でしょうか?実際の顧客数はどれくらいでしょうか?誰もがNetflixを構築しているわけではありません。レジリエンスのプロファイルに合わせて構築する必要があり、レジリエンスを妥協することは決してありません。しかし、何百万人ものユーザーのためのレジリエンスを構築することと、何百人のユーザーのためのレジリエンスを構築することは、あるいは組織のプロファイルが何であれ、それは異なるものです。

環境における複雑さの見返りについて考える必要があります。これらの事柄について深く掘り下げていくと、それぞれが得意とする強みの部分がはっきりと見えてきます。しかし同時に、組織にもたらす複雑さという側面も存在し、その複雑さも計算に入れなければなりません。このような領域では、複雑さに関するROIの計算を行い、Microservicesのフットプリントが全体的な価値提案とどう整合しているかを把握する必要があります。本当に価値を得られているのでしょうか?それとも単に、そうあるべきだからという理由で完全に分解されたシステムを構築し、価値が生まれることを期待しているだけなのでしょうか?

Thumbnail 1330

この価値の概念について、いくつかの基準を選んで考えてみましょう。実際の顧客数はどれくらいか?実際の負荷プロファイルはどうか?顧客はシステムをどのように利用しているか?スループットの要求はどの程度か?通常、スループットはアプリケーションの特定の領域に集中しており、そこでは本当に優れたパフォーマンスを発揮する必要があります。アーキテクチャが適切に分解されておらず、問題が分割されていない場合、そこで効率的にスケールする必要があります。その問題に適したサービスを持つ必要があるのです。

デプロイの頻度はどうでしょうか?これは見落とされがちな要素です。システムの一部を構築してサービスとして配置すると、そこにずっとあり続けます。新機能や新しい機能が追加されても、市場の変化に応じて常に変更が必要な高変動領域のものとは異なり、その一部は片隅に置かれたまま1年間変更されないかもしれません。これもパラメータとして考慮する必要があります。そして、障害の影響はどうでしょうか?障害の影響について話すのは少し奇妙に感じます。まるで障害が許容されるかのように聞こえるかもしれませんが、決してそうではありません。

障害には様々な可能性があります。何百万人もの顧客を抱える大規模な企業で障害が発生し、翌朝の新聞に大きく取り上げられるケースと、昨日1時間ダウンしていたことで数人の顧客が不満を感じるケースとでは異なります。どちらも悪いことですが、その「悪さ」にも程度があるのです。では、最も耐障害性の高いシステムが必要だと考えて、どこまでResilience重視にシフトすべきでしょうか?

Thumbnail 1440

このグラフを作成しました - Y軸は、私が説明している方程式へのこれらの入力値、つまりプロファイルを示しています。X軸は、それらが複雑さに対する見返りとどのように相関しているかを示しています。Scaleやresilienceなど、小規模なMicroservicesの真骨頂となる重要な要素が出てくると、それらのサービスにおける複雑さに対する見返りは非常に高くなります。一方で、システムの特定の部分において環境やワークロードがそれほど複雑でない場合、あるいは利用形態がそれほど複雑でない場合でも分解を行うと、複雑さに対する見返りはそれほど魅力的ではなくなります。

Thumbnail 1500

これは何らかの形でモデル化する必要があります。この件について素晴らしい方法論をお持ちできればよかったのですが、残念ながらそうではありません。それでも、ここで何かしらのモデル化は必要だと考えています。私にとって、これは価値のホットスポットを見つけることが重要なポイントです。 Microservicesに移行しようとしている組織に入った時、まず最初に探るのは、システム内のそういったホットスポットの場所です。

Thumbnail 1530

これらのホットスポットを考える際には、効率的にスケールできていない箇所や、潜在的な問題を懸念して過剰にプロビジョニングされている箇所を特定する必要があります。また、システムの特定の部分間の依存関係によってパフォーマンスやスループットに影響を与える課題を抱えているチームの状況も確認すべきです。 これらの問題は関連している可能性もありますが、別個の懸念事項である可能性もあります。

Thumbnail 1550

Thumbnail 1570

ビジネスクリティカルな業務を特定する必要があります。ソリューションの機能や性能の範囲を見たとき、どの特定の領域が重要性を持つのでしょうか?これらの機能の中には、お客様とその事業継続性にとって不可欠なものがあります。 また、サービスをチームにどう配置するかも考慮しなければなりません。チームにとって適切なMicroservicesのプロファイルとは何でしょうか?これらのサービスを日々維持管理する現実はどうなのでしょうか?これらのサービス専任のチームを持つことはできるのでしょうか?どのようにMicroservicesを異なるチーム間で分散させるべきでしょうか?

サービスの分解がどのように差別化に役立つかを探る必要があります。サービスの分解を通じて、新しいスループットを達成したり、顧客に新しい価値提案をしたりすることができるでしょうか?これは時としてリリース頻度として現れます - システムの特定の領域で一貫して機能を素早くデリバリーしているかもしれません。効果的な分解によって機能を迅速にプッシュアウトし、顧客からのフィードバックを得て、新機能のリリースを加速できているなら、それは素晴らしい価値提案となります。これは顧客ロイヤルティを高め、システムからより多くの価値を得ているという実感を与え、Product-led growthにつながる可能性があります。

Thumbnail 1630

運用の複雑さ(Operational complexity)が時として見過ごされがちだということを強調したいと思います。ここでいう「運用」は広い意味を持ちます。DevOpsの観点から、デプロイメントやその他のシステム面に関して、Microservicesはチームが独立してコードを書いてデプロイできる低摩擦なプロセスを提供することで運用面でのメリットをもたらす可能性があります。しかし、多くの組織が複数のリポジトリの管理や、それらのバージョン管理に苦心しています。Microservicesが増えていくにつれ、DevOpsの領域でさえ、チームは動く部分が増えることによる複雑さの増大に気付きます。

運用の複雑さのもう一つの側面は、サービスが本番環境で稼働している際に現れます。運用担当者が顧客から報告された問題を調査する必要がある場合、システムの分散的な性質によってトラブルシューティングが困難になることがあります。5つの異なるMicroservicesにまたがる呼び出しを追跡している時に、そのチェーンのどこかで問題が発生した場合、ログファイルだけでは作業が大変です。様々な運用ツールベンダーから優れたツールが提供されていますが、この複雑さの増加は認識しておく必要があります。Microservicesの数とその環境のサイジングを決定する際には、組織がそのようなモデルをサポートできる運用上の準備が整っているかを考慮する必要があります。

Thumbnail 1750

これらの基本原則は、私たちがサイジングにどのようにアプローチすべきか、そしてなぜ従来とは異なる考え方が必要なのかを示しています。ここで、実践的な戦略をいくつかご紹介したいと思います。これは現在進行形の取り組みであり、より正確な用語や分類法を確立するために、これらの戦略を継続的に改善していく必要があることを認識しています。しかし、ここで議論できることは十分にあります。

Value mapを用いたMicroservicesの評価と配置

Thumbnail 1780

Thumbnail 1800

最も説得力のあるアプローチは、Value mapを作成することです。Domain-driven designやEvent stormingなどを完了すると、環境に必要な候補サービスが特定されます。この時点でValue mapを作成することができます。

Thumbnail 1820

先ほど述べたように、私は4象限フォーマットを選択しました。これらの要素を整理する上で効果的な視覚的表現を提供してくれるからです。4象限による整理の仕方が気に入っていて、物事がどこに位置づけられるかの視覚的な表現を得ることができます。このために2つの軸を作成しました。これらが決定的な軸というわけではありません - 異なる要素を軸に設定することもできますが、いくつかの極端なケースを捉えたいと考えました。 Y軸の上部には、最も重要なビジネスオペレーションが位置します。ここには高いスループットがあり、効率的で迅速なスケーリングが必要です。これは本当に小規模なMicroservicesの理想的な領域です。効率的なスケール、局所的なResilience、そしてMicroservicesアーキテクチャで求められる他の優れた特性を最大限に活用したいからです。

Thumbnail 1850

Thumbnail 1870

その軸の反対側には、それほど頻繁に利用されないものが位置します。これらは控えめなScaling profileを持ち、突然スケールアウトして大量のワークロードを追加する必要がないものです。これらのサービスの全体的なスループットと利用は大きな問題ではなく、SLAもそれほど重要な懸念事項ではありません。 X軸には、変更の速さと展開の頻度に関する要素を配置しました。これも重要な要素だと考えているからです。小規模なサービスと迅速なデプロイメントがある場合、それはサイジングの理想的なスイートスポットとなります。サービスが小さく、デプロイがシステムの他の部分に大きな影響を与えないことがわかっている場合、Microservicesから大きな恩恵を得ることができます。

小規模なテストで済み、頻繁な変更とデプロイが必要な場合は、そこから価値を引き出すことができます。一方、スペクトルの反対側には、進化の遅い、デプロイ頻度の低いケースがあります。自律性の価値に関して、明確なビジネス課題の解決に焦点を当てた小規模なものの場合、チームがそのサービスの健全性、適切な構築、十分なテストを確保する上でより大きな自律性を持つことが望ましいと考えています。左側のものについては、頻繁に触れる機会が少ないため所有することのメリットが小さく、チーム間で共有してもよいかもしれません。

Thumbnail 1950

次に、候補となるサービスを象限に配置する必要があります。ここでは例として仮のサービスをいくつか配置してみましたが、右上の象限、特に右端上部に位置するサービスは非常に良い候補となるでしょう。これらがここに位置する場合、右側にあることから粗粒度のサイズでさらに分解できる可能性があります。頻繁にリリースされ、環境のワークロードの中心的な部分となるため、大きな価値を得られることがわかっています。

Thumbnail 1990

Thumbnail 2020

一方、左下の象限にあるものは、デプロイ頻度が低く、使用頻度や消費も少ないものです。明らかに、この左下に位置するものを何十何百ものサービスに分割することで大きな価値が得られるかは疑問です。ここには主観的な議論の余地があるでしょう。また、高いボリュームがありながらリリースが稀なものや、 システムの重要な部分でありながらほとんど変更されないもの、あるいは急速な進化を遂げているにもかかわらず頻繁にリリースされないサービスなど、例外的なケースもあります。

このフレームワークは完璧ではありませんが、私のアプローチをより良く理解していただけると思います。ドメインやコンテキスト、境界に関するものがすべてだというMicroservicesの考え方に反すると言う人もいるかもしれません。しかし、Microservicesをどこにどのように配置するかを決定する上で、これらの基準は非常に重要だと考えています。サービスの消費量だけに基づいてMicroservicesに関する判断を下すこともあります。これはドメインの役割とは関係なく、運用上の役割やスループットの役割、スケールの役割に関することかもしれません。

Thumbnail 2060

皆さんもおそらく考えるであろう基本的な考慮事項がいくつかあります。小規模なMicroservicesの候補を検討する際の重要な領域の1つは、確かにスケール効率です。ここで私が言いたいのは、消費量の多いサービスを見たとき、水平方向に効果的にスケールする必要があることを知っていますが、同時に良好な消費効率を得るためにスケールダウンも効果的に行う必要があるということです。サービスの分解を検討する際には、何がこのものをスケールさせる要因となるのかを考える必要があります。ここで左側を見ると、サービスにはさまざまな操作が含まれていますが、その中の1つの操作が非常に負荷の高いものになっているケースがあります。

このサービスからさらにスケールを得る唯一の方法は、スケールの単位を追加することです。たとえサービスの一部がほとんど使用されていなくても、そうせざるを得ません。サービスのある一つの側面をスケールさせるために、広く展開する必要がありますが、それは必ずしも効率的なスケーリングとは限りません。新しい機能を追加するためだけにサービスを追加しなければならない状況になるかもしれません。

そこで疑問が生じます:このサービスを分割すべきでしょうか?大量に消費される部分だけを独立してスケールさせることはできないでしょうか?データは常に重要な要素であり、Microservicesの中で最も難しい部分です。システムを単純に任意に分離することはできません。なぜなら、Microserviceによってデータがカプセル化されているからです。そのため、これらすべてのバランスを取る必要があります。右側には、負荷が非常にスパイク的なものがあります - 1日の大半はほとんど使用されませんが、アクセスが集中すると急速なスケーリングが必要になります。過剰なプロビジョニングは避けたいところです。サービスの粒度もこれに関係してきます。ContainerやServerlessなど、他にも多くの変数がありますが、一般的に、これらの重要な領域に対して分解が効率的にスケールするかどうかが問題です。重要なのは、これをすべてのサービスに適用するのではなく、どのサービスがこれらのプロファイルを持っているか、そしてそれらの位置づけとサイズにどのように影響するかを理解することです。

Thumbnail 2200

ストレージのスケーリングも重要な考慮事項です。このOrderマイクロサービスがあり、RDSなどで動作する大きめのサービスで、ストレージとコンピュートを使用している場合、環境とコンピュートの規模を決定するためにインスタンスのサイズを設定しています。この粗粒度モデルでは、この1つのOrderサービスの下に、さまざまなタイプのデータが存在します。このデータの一部に対して、Noisy Neighborの状態が発生していないかを確認する必要があります。Microserviceの適切なサイジングを決定する際の一部は、依存する基盤となるサービスが効果的にスケールする方法も含まれます。

例えば、緩やかに結合されているFulfillmentを切り離すことはできるでしょうか?Fulfillmentは、ストレージの観点で見ると非常にスケーラブルな部分となり、RDSインスタンスのサイジングで良好なアライメントを得ることができません。これを分離し、Fulfillmentを独自のMicroserviceとして切り出し、そのサービスのストレージコンピュートに適したサイジングを見つけることができます。Microservicesを考えるとき、私たちは通常、アプリケーションサービスのコンピュートだけを考え、ストレージを付随的なものとして扱いがちです。しかし、多くの場合、これを推進するのはボトムアップからです - ストレージのプロファイル、ストレージのコンピュートのプロファイル、そしてそれらの影響を考慮する必要があります。

Microservicesの進化的アプローチと実践的戦略

Thumbnail 2310

このBulkheadモデルは、船が一連の隔壁を持っているという考え方です。船が何かに衝突して隔壁に穴が開いた場合、その隔壁だけが水で満たされ、船全体が沈むことはありません。Microservicesについて考えるとき、私たちはこの同じモデルをすべてに適用したいと考えています。1つのサービスがダウンした場合でも、フォールバックを実装し、他の技術を使用してシステム全体がダウンするのを防ぐことができる、そのような粒度とサイズを選択したいのです。

これらの選択はすべてのサービスに当てはまりますが、一部のサービスではより慎重な取り扱いが必要です。システム内の何百もの相互作用の中心にあるサービスは、明らかに障害の集中点となります。そのため、適切な障害耐性を実現するために、システムのその部分をどのようにサイジングすればよいのでしょうか?システムの他の部分では、より単純な障害耐性の対応で済みます。これらのコンテキストを使用していて、障害が発生しても代替手段があり、エンドユーザーには障害が見えないようになっています。すべてのサービスで障害耐性が同じだと言うのは正しくありません。明らかに、障害耐性の目標を達成するために、特定のプロファイルとサイズを必要とするサービスが存在するのです。

Thumbnail 2400

そして、パフォーマンスのボトルネックという明白な考慮事項があります。大規模なサービスがあって、そのサービスのSLAが十分なパフォーマンスを発揮できていない場合、これを異なるMicroservicesに分解する機会となるでしょうか?

Thumbnail 2410

Thumbnail 2430

はい、これはまさにMicroservicesアーキテクチャの典型的な進化です。 一部のサイジングは途中で調整する必要があることを認識しなければなりません。これらの環境のパフォーマンスを見ると、ProductとSearchがSLAとスケールに重大な問題を引き起こしていることがわかります。Searchを分離しても問題を引き起こさないことがわかります。 ただし、分割によって生じる通信の頻度を検討する必要があります。もしそれが問題になるなら、自分たちでNoisy Neighborの問題を作り出してしまうことになるからです。これは確実にサイジング戦略に影響を与えます。

Thumbnail 2460

Thumbnail 2480

結局のところ、これは価値の境界線を引くことです。もしこれらの質問をすべて検討してデータを分析する余裕がないなら、どこかで線引きをする必要があります。 この方程式の一方には、Coarse-grainedなサービスがあります。Coarse-grainedとは何かとよく聞かれますが、絶対的な定義はありません。私が言いたいのは、可能な限り小さなサービスにする必要はないということです。Coarse-grainedは、いくつかの機能を集約したものかもしれません。 そして線の右側には、デプロイメントの目標とアジリティを達成するために、完璧なサイズに設計することで最大の価値を引き出せるサービスがあります。

Thumbnail 2500

例えば、Product CatalogとRatingサービスの概念は一方に置くことができます。これらは別々のサービスにすることもできますが、価値の象限の特定の場所に位置するため、それほど大きな価値は得られません。UsersとRolesについても同様で、システム内で頻繁に変更されるような形では消費されていません。ConfigurationとMetadataは、システムのセットアップと設定に使用されますが、一度設定されると滅多に変更されないため、グループ化することが理にかなっています。

Thumbnail 2530

右側に戻ると、先ほど議論したE-commerceシステムにおけるカートや決済などのトピックが出てきます。カートが機能していないために取引が完了できない場合、Resilienceとスケーリングを最大限に高める必要があります。他の例として、高スループットで急速なスケーリングが必要な検索機能は、高スループットのプロファイルを持つかもしれません。また、税務関連は税制が常に変更されるため頻繁にリリースが必要となり、その点で価値が生まれます。

Thumbnail 2590

ラインの片側か他方に配置することを出発点として、時間の経過とともにこれらの決定が正しいのか、どのように進化させる必要があるのかを評価することができます。 ここでもDesign Smellsの考え方が当てはまると思います。最初の決定を行った後、様々な質問を自分たちに投げかけることができます。効率的に消費されているか?サイズは開発者の生産性にどのような影響を与えているか?サービスを大きいままにしておくことが本当に有益なのか、それとも単に問題を引き起こしていないから大きいままにしているのか、を判断するために様々な質問を投げかけることができます。

Thumbnail 2630

また、多くの人が気づいていない逆方向のアプローチも可能です。このサービスを本当に小さくした価値が十分に得られているのか、それとも単に最初に小さくすると決めたから小さいままなのか、という視点です。2つか3つのサービスを取り上げて、使用パターンやデータを見てみましょう。もしこれらが別々になっていることからあまり価値を得られておらず、開発者が個別に作業するのに苦労しているのであれば、それらを統合してより粗粒度のサービスにしましょう。

Thumbnail 2670

結局のところ、全てのMicroservicesに関する文献は、必ずしも全ての人が従っているわけではありませんが、Microservicesをどのように実現するにしても、これを進化モデルとして見るべきだと述べています。最悪のシナリオは、「Microservicesに移行します。Domain-driven DesignとEvent Stormingを行い、200のMicroservicesを特定し、システムの最初のバージョンとしてその200全てのMicroservicesを構築します」と言うことです。ほとんどの人はそうすべきでないことを知っていますが、念のため言っておくと、どのようにそこに到達するにしても、たとえ異なるアプローチを選択し、最終的に200のMicroservicesを持つことが目標だとしても、そこからスタートしてはいけません。

Thumbnail 2740

学ぶべきことが多すぎます。稼働中の生きたシステムから抽出すべき運用知識、開発者の知識、スケールに関する知識が多すぎて、ただ暗闇の中に消えて戻ってきてサービスを書き始めるだけでは、それらの知識を得ることはできません。私にとって、Right-sizingへの完璧な道筋はありません。はい、Domain-driven Designを行ってください。しかし、 これを行う際は、こういったコンテキストの要素を議論に加えてください。もし私が提案しているコンテキストの要素が適切でないなら、自分たちに合ったコンテキストの要素を見つけてください。ただし、質問を投げかけ、これらが本当にサービスにとって適切な境界なのかを自問する必要があります。

Thumbnail 2760

実際に稼働しているサービスから学ぶことが大切です。環境がどのように構築され、運用され、機能しているかについてのリアルタイムの洞察ほど、設計を形作るのに適したものはありません。私にとって、サービスの分解について話し合う際に、呼び出し頻度やチームのデプロイ状況、依存関係を示す生データを目の前にして議論することに勝るものはありません。システムからの実際のフィードバックがあれば、何を分割すべきか、あるいは何をより大きなものに再構成すべきかについて、より確かな判断を下すことができます。

Thumbnail 2840

Thumbnail 2850

Thumbnail 2860

私たちは単に数百のMicroservicesを持つ魅力的なシステムを目指しているわけではありません。私たちが目指すのは、ビジネスの特性に基づいて適切に分解され、最大の価値を生み出すバージョンです。これは、単にサービスの数や、名詞に基づいた分割方法で決めるものではないと強く感じています。 まずは粒度の粗いサービスから始めることをお勧めします。小規模なサービスをいくつか用意し、アクティビティを把握し、 いくつかのMicroservice候補を特定し、一部の要素を分割し始めます。 さらに反復を重ね、新しいMicroservicesのセットに到達します。これを生きて進化する存在として捉えてください。Microservicesへの分解は決して完了することのないプロセスなのです。

モダナイゼーションとMicroservicesの将来

Thumbnail 2890

Thumbnail 2920

多くの組織は、既存のレガシーソリューションを持ち、Microservicesベースのアーキテクチャへの移行を試みているモダナイゼーションの段階にあります。このような状況で、この進化的なモデルは特に効果を発揮します。モダナイゼーションにおいて、第1リリースで完全に分解されたMicroservicesをいきなり導入することは避けるべきです。 私たちはStranglerパターンを使用します - 最初のサービスセットを抽出する方法について、多くの人々が議論しています。システムの一部がこれらの小規模なサービスで動作し、残りの部分はMonolithで動作している状態です。

Thumbnail 2940

そして、反復を続けていきます。ここでの重要な問題は、完全にモダナイズされた状態とは何かということです。 それは、レガシーMonolithにあった全てのボックスを小さなMicroservicesに分解することではありません。2、3回の反復を行い、10個か15個のMicroservicesを作成し、その他の多くの部分は、ビジネスにとって理にかなっているため、より大きな粒度の粗いサービスのままにしておくかもしれません。これは、ビジネスにとってより良いモダナイゼーションのストーリーとなります。通常、ビジネスにとってのTime to MarketやTime to Valueが短縮され、チャンスを掴むための良い機会が得られます。

Thumbnail 2980

Thumbnail 3000

ここでデータが重要になります - 多くのデータが利用可能ですが、 Microservicesのパフォーマンスプロファイルを意識的に構築することをお勧めします。多くのツールで既にデータは利用可能ですが、Microservicesがどのように消費されているかについて、どのような洞察が必要かを意識的に選択してください。これにより、そのMicroserviceが目標を達成しているか、そしてサイジングが本当に 適切かどうかを評価することができます。

Thumbnail 3010

Thumbnail 3020

Thumbnail 3030

Thumbnail 3070

この例では、カスタムスタック、つまりサービスアプリケーションスタックについて説明します。 ゲートウェイレベルでデータを取得できます。 個々のMicroservicesがどのように利用されているかについて、RESTマイクロサービスのエントリーポイントでデータを取得できます。 さらに、それらのMicroservices内部の基盤となるサービスがどのように利用されているかを調べ、Amazon CloudWatchからのデータを使用して、興味深い質問を投げかけることができます。 これは、適切なサイジングについて意味のある洞察を得るために、どのようなデータが必要かという観点から考えることが重要です。

時として私たちは、CPU使用率やメモリ消費量、インスタンスサイズが適切かどうかといった、すでに持っているメトリクスから考え始めがちです。これらはインフラ情報として非常に重要ですが、分割が適切かどうか、サイジングが適切かどうかを問うこととは異なります。これらのツールで、サービスが小さすぎて十分な価値を得られていないことを示す指標はほとんどありません。「小さすぎる」という問題と「大きすぎる」という問題の両方について、そのデータをどこでどのように取得するかを見つける必要があります。

これは運用経験の中に組み込まれるべきものです。これは単にアーキテクトがデータを見てサイジングの評価をする、といった片手間の作業ではありません。運用チームもサイジングに強い関心を持つべきです。問題が発生しているか、課題に直面しているか、スケールの問題が起きているかについて気にかける必要があります。Microservicesはそういった問題の中心にあることが多く、その分割方法がボトルネックやスケーリングの問題を引き起こしている可能性があります。運用チームがこれらの問題について考えるようになってほしいと思います。運用チームが分割の方針を主導することはないかもしれませんが、課題を示すデータを持っているはずです。

Thumbnail 3120

Thumbnail 3130

Thumbnail 3150

ここで、いくつかの重要なポイントをお伝えします。 目新しいものを追いかけないでください。200個や500個のMicroservicesを持つ企業になろうとしたり、Microservicesの数の多さを誇りにしたりしないでください。 価値を追求し、サイジングには絶対的な基準がないことを理解してください。小さいか大きいか、どれくらい小さくすべきか、どれくらい大きくすべきかについて、私から明確な公式をお伝えすることはできません。これらはすべてコンテキストによって決まります。 私は常に粗粒度から始めることを好みます。そして、システムの活動によって本当に必要だと示されたときに、Microserviceを分割するという考え方が気に入っています。つまり、データが示すところに従って、1つのMicroserviceを3つに分割する、といった具合です。

Thumbnail 3170

小さければ良いというわけではありません。この話の中で複雑さについても考慮してほしいと思います。これは単に呼び出しの頻度やScaling Profile、アーキテクチャの次元の話だけではありません。組織全体にとっての複雑さの問題なのです。Microservicesの分割は、製品としてもアーキテクチャとしても望んでいる成果を達成できているでしょうか?ビジネスの各領域に複雑さを加えていないか、運用チームのトラブルシューティングを困難にしていないか、DevOpsの取り組みが予想以上に難しくなっていないか、期待した価値が得られているかを考える必要があります。

Thumbnail 3210

Thumbnail 3220

必要なインサイトとデータを入手してください。そして、これは常に進化し続けるものだと考えてください。これは生き物のように変化し続けるものなのです。 Microservicesのサイジングに関する、より広範な包括的なテーマをお話ししました。Microservicesの基本となる中核的な原則を守り続け、そこにご自身の環境やチーム、ドメインのコンテキストを加えることで、適切な答えにたどり着くことができます。この講演が、サイジングに関する新しい考え方のモデルを皆さんに提供できたことを願っています。もしかしたら、すでにそのような考え方をされている方もいらっしゃるかもしれません。また、Right-sizingについて語る人は多くいますが、私がこの概念を発明したわけではありません。これは単に、Microservicesベースのアーキテクチャを構築する際の考え方の自然な発展段階だと考えています。残りのre:Inventもお楽しみください。ご清聴ありがとうございました。よい一日をお過ごしください。


※ こちらの記事は Amazon Bedrock を利用することで全て自動で作成しています。
※ 生成AI記事によるインターネット汚染の懸念を踏まえ、本記事ではセッション動画を情報量をほぼ変化させずに文字と画像に変換することで、できるだけオリジナルコンテンツそのものの価値を維持しつつ、多言語でのAccessibilityやGooglabilityを高められればと考えています。

Discussion