Skip to content

Instantly share code, notes, and snippets.

@wreulicke
Last active September 17, 2020 15:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wreulicke/978028a27185022bb5fa7e8aacf9634b to your computer and use it in GitHub Desktop.
Save wreulicke/978028a27185022bb5fa7e8aacf9634b to your computer and use it in GitHub Desktop.
Microservices: Client Side Load Balancing の和訳

この和訳メモは以下のリンク先の記事の和訳です。

マイクロサービス: クライアントサイドロードバランシング

プロダクションでのフェイルセーフ性を確保するために、同じアプリケーションを複数のインスタンスにデプロイします。 同じアプリケーションをホストする論理的なサーバ(ノード)のグループは Application Clusterを構成します。

伝統的なアプローチ

それらのノードの一つに伝達させるための伝統的な方法はロードバランサーを通して行われます。 クライアントはアプリケーションクラスタの前にあるロードバランサを知っています。 リクエストを受け取った際に、ロードバランサはクラスタにあるどのノードに呼び出しをルーティングするかを選択します。 この選択をするためにたくさんあるアルゴリズムの一つが使えます(※)。 最も一般的に使われるアルゴリズムはラウンドロビンです。 より正確に表現するために、これはサーバサイドでアプリケーションの負荷の分散のための、サーバサイドバランシングです。 クライアントはこのノードの選択のために何も影響しません。

訳者注 ※ can use one of may algorithms の mayがmanyのタイポっぽい きしださんありがとう!

Client Side Load balancing

クライアントサイドロードバランシングはアプリケーション(もしくはクライアント)の呼び出し側がロードバランシングを取り扱います。 これがどのようなことを引き起こすのか抽象的に見ていきましょう。クライアントサイドでロードバランシングをするために。

  • クライアントはアプリケーションクラスタにある利用可能なノードの全てを知っているべきです。この時点ではクライアントはそれについて知っていることを仮定しましょう。 (記事の後半で知る方法について説明します。)

  • 次に、クライアントに標準的なロードバランシングのアルゴリズムを実装した、利用可能なライブラリがあることを仮定します。

  • クライアントはすべて、このライブラリにリクエストを移譲することで、アプリケーションのノードを呼び出します、選ばれたロードバランシングアルゴリズムに基づいて。

些細なように思えませんがそれほど訳に立たない・・・?ちょっと待って!

Why Use Client Side Load Balancing?

クライアントサイドロードバランシングの優位性についてさっと見てみましょう。

  1. No More Single Point Of Failure In A Cluster (クラスタにSPOF/単一障害点がなくなる)

単一のロードバランサーが前面にあるクラスタは、ロードバランサーがダウンした場合にクラスタノードは到達不可能になるリスクを常に負っています。 思い出してください。失敗は起きるもので、例外ではありません。クライアントサイドロードバランシングによって、サーバサイドバランシングと比べて、何も必要とせず、この制限は無くなります。

  1. Removal of Bandwidth Bottleneck(帯域のボトルネックの除去)

サーバーサイドロードバランサーは高スループットのシステムにとってのペインポイントに簡単になるでしょう。 ロードバランサはリクエストを処理するための固定のスレッド数や(VMやハードウェアのNICカードによって規定される)固定の帯域量を持つとするならば。 これは、サーバサイドロードバランシングでは常に水平スケール性に上限があることを意味しています。 クライアントサイドロードバランシングであれば、この懸念は、サービス間通信が 全てP2Pであるため、なくなります。

訳者注: 面倒で訳してない ロードバランサのスレッド数が400のときにアプリケーションノードのスレッド数が全体で400あった時に スケールアウトした際にロードバランサのスレッド数を増やさないといけない、みたいな話が書いてあるけど そもそもそのシナリオ、妥当じゃない気がする。

Example: a given cluster is backed by 4 application nodes, each of them having 100 threads configured in server (or servlet container like tomcat, jetty, etc. ) to serve requests. That makes a total of 400 threads. The load balancer fronting this cluster also has 400 threads. Makes sense. Just when things were predictable and stable, the company ran an advertising campaign on YouTube and now they are expecting double the traffic. Which means the application cluster should now have double the number of nodes. Easy. The devops team spins up 4 new nodes - which makes a total of 8 nodes in the cluster. So now they have 800 (8x100) threads to server the request, but the load balancer still has 400 threads. Simple. Let us increase the number of request processing threads on the load balancer. Looks trivial on the surface. However, each request processing thread requires a certain amount of memory and RAM. Does this require a larger VM? If not yet, it won't be long before the VM hits that ceiling.

  1. Auto-discovery (自動ディスカバリ)

サーバサイドロードバランサーでは、ロードバランサの設定ファイルによって新しいノードが設定されるでしょう。 これはchefなどのツールを使って自動化することが出来ますが、これらは変更を受け入れるために、しばしば、設定のためにロードバランサのリスタートやリロードが必要になります。 設定が自動化されていないケースでは、手作業を必要とします。 これを自動化するのは、習熟するための別のスキルセットが必要になります。それはすぐに使えるものではありません。 クライアントサイドロードバランシングでは、アプリケーションに組み込まれている、ロードバランシングのライブラリがこの側面を面倒見ます。 ディスカバリは全体的に透過的で、そして必要なのは、アプリケーションの設定ファイルでレジストリサーバへのIP/hostnameの設定をすることだけです。

訳者注: ALBみたいなの使ってると、この点に関してはあんまりメリットを感じない

  1. Reduced Cost(削減されたコスト)

サーバーサイドロードバランサが必要ないのであれば、これ以上、ロードバランサのVMを必要としないので、コストが下がります。 この点に関する議論は、同じVMで走る、ソフトウェアロードバランサの複数のインスタンスを複数のクラスタで提供することですが、このアプローチは単一のVMが複数のクラスタのSPOFになるリスクが増大します。 レジストリのためのVMが必要になりますが、複数ロードバランサのVMを取り除く事ができ、したがって、ドルを抑えられるでしょう。

  1. One Hop Less (less HTTP hops) (1ホップすくない(HTTPのホップを下げる))

これは明らかです。サーバサイドロードバランサを通してルーティングされる呼び出しは、追加のネットワークホップを意味し、そして追加のレイテンシを意味します。 クライアントサイドロードバランシングであれば、サービス間通信はP2Pで、ネットワークホップを抑えることができます。

Let's Dive Deeper

Service Registry

サービスノードがサービスレジストリに登録や使用を試みる際に、その裏で何が起きるのかを見てみましょう。 通常、全てのステップはクライアントサイドロードバランサーのライブラリによって、調整され、開発者に透過的です。

  1. マイクロサービスが起動する。起動の一部として、クライアントロードバランサのライブラリはアプリケーションをサービスレジストリに登録します。 この登録リクエストには、クライアントは一般的に次の情報をサービスレジストリに送信するでしょう。
  • application ID - これはアプリケーションのためのユニークIDである文字列です
  • Hostname / IP - サービス 1 を実行するVMのホスト名やIP
  • Port - サービス1がリクエストをリスンしているポート

サービスレジストリはアプリケーションIDに対して、このエントリを追加します。

  1. マイクロサービスハートビート: アプリケーションがサービスレジストリに登録されたら、サービスレジストリに正常なハートビートを送るべきです。 これは、動作しているノードのみがレジストリに残っていることを保証するために必要です。

  2. サービスの呼び出し: サービス1はサービスレジストリに登録されており、サービス1を呼び出したいなんらかのノードは、アプリケーションID サービス1の詳細のために サービスレジストリにリクエストする必要がある。 サービスレジストリはこのリクエストに、サービス1が動作しているノードに関する情報を返却します。 これらの情報から、ロードバランサーのライブラリはサービス1のノードのひとつに対して呼び出しを作成します。 呼び出されるサービス1のノードがどれになるかは、ロードバランシングのアルゴリズムの選択に依存しています。 これは p2p 通信です。

  3. アプリケーションのグレースフルシャットダウン: サービス1のノードがシャットダウンした場合どうなるでしょう。 このケースはサービス1がサービスレジストリに対して、現在のノードの解除リクエストを送ります。

  4. アプリケーションの非グレースフルシャットダウン: サービスがもし、突然終了(例えば、kill -9 {pid})した場合 サービスはサービスレジストリから解除の機会がありません。このケースではあるしきい値のハートビートが見過ごされたなら、 サービスレジストリが影響のあるノードをレジストリから削除します。

Client Side Load Balancer Library

ロードバランシングアルゴリズムの実装、低レベルの実装を抽象化します。 一般的な機能は以下の通りです。

  • レジストリへのハートビート
  • スナップショットの保持
  • 失敗したものの切り離し

例としては、Netflix Ribbonがあります。

What if Service Registry Crashed? (もしサービスレジストリがクラッシュしたらどうなるの?)

全てのサービスレジストリが同時にダウンした場合でも、アプリケーションのノードはそれでも動作可能です。 これは、クライアントサイドロードバランサーライブラリが一般的にはレジストリデータのスナップショットを保持しているためです。 アプリケーションノードはこのデータを使って他のサービスを呼び出します。サービスレジストリの障害の影響は次のようなものになるでしょう。

  • 新しいサービスノードが見つからない。
  • 終了したサービスモードが削除されない。しかしながら、クライアントサイドロードバランサーライブラリはノードへの呼び出しが失敗し、最終的に削除されることを、検知するのに十分にスマートです。

訳者注 Armeriaの実装とかを読んでみたい

これはビジネスにとって小さな影響にしかならないでしょう。

For The Curious Ones

いかがでしたか?ここにいくつかの単語をあなたがより深く探求もしくは更に調べるための単語をおいておきます。

  • Netflix Eureka
  • Consul
  • Zookeeper
  • Service Mesh
  • LinkerD

この記事は https://amitcodes.wordpress.com/2018/10/22/microservices-client-side-load-balancing/ で元々発行されたものです。

訳者注 この和訳メモは以下のリンク先の記事の和訳です。 https://www.linkedin.com/pulse/microservices-client-side-load-balancing-amit-kumar-sharma/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment