いくつかの負荷分散アルゴリズムの原理とコード実装

いくつかの負荷分散アルゴリズムの原理とコード実装

ポーリング アルゴリズム: 受信したリクエストをバックエンド サーバーに順番に転送します。現在のサーバーへの実際の接続数や現在のシステム負荷を考慮せずに、すべてのサーバーを平等に扱います。 以下に簡単な投票システムを示します。

  1. パブリッククラスラウンドロビン{
  2. 静的 整数位置 = 0;
  3. 公共 静的リスト<String> initServerList() {
  4. List<String> サーバー = 新しい ArrayList<>();
  5. サーバーを追加します( "192.168.10.00" );
  6. サーバーを追加します( "192.168.10.01" );
  7. サーバーを追加します( "192.168.10.02" );
  8. サーバーを追加します( "192.168.10.03" );
  9. サーバーを追加します( "192.168.10.04" );
  10. サーバーを追加します( "192.168.10.05" );
  11. サーバーを追加します( "192.168.10.06" );
  12. サーバーを返す
  13. }
  14. 公共 静的文字列 getServerUrl() {
  15. //サーバーのオンラインとオフラインによって発生する同時実行の問題を回避するために、新しいリスト割り当てを作成します
  16. リスト<String> serverList = 新しい ArrayList<>();
  17. サーバーリストにAllを追加します(initServerList());
  18. 文字列サーバー = null ;
  19. 同期(位置){
  20. if(位置 >= serverList.size ()) {
  21. 位置 = 0;
  22. }
  23. サーバー = serverList.get(位置);
  24. 位置++;
  25. }
  26. サーバーを返す
  27. }
  28. 公共 静的void main(String[] args) {
  29. )の間{
  30. System.out.println (getServerUrl()) ;
  31. }
  32. }
  33. }

実際の生産環境では、次のような多くの要素を考慮する必要があります。

[[238078]]

新しく追加されたサーバー IP をどのように処理しますか? これは比較的簡単で、initServerList() に追加するだけです。

サービス停止が発生した場合はどうすればよいですか? たとえば、192.168.10.01 が配置されているサーバーがダウンしていて、そのサーバーにリクエストが転送された場合、エラーが報告されます。このとき、サービスを必要とする消費者はフォールト トレランスを考慮します。この場合、たとえば、再度リクエストを送信すると、192.168.10.02 マシンに転送されますが、これは正常です。 この方法の最大の欠点は、悲観的ロック同期を使用するため、システムの同時パフォーマンスに影響が出ることです。

各マシンの構成は異なり、シングルコアCPU、2Gメモリのものもあれば、8コアCPU、32Gメモリのものもある。この場合、上記のポーリング方法を使用すると不公平になり、構成が弱いマシンに大きな負担がかかります。 これを導入することができます

重み付けラウンドロビン: 各サーバーに重み値が与えられます。重みが高いサーバーにはより多くのリクエストが割り当てられ、重みが低いサーバーにはより少ないリクエストが割り当てられます。 実装のアイデアも非常にシンプルです。重みに応じてサービス リストを再構築し、ポーリングします。前の画像:

コードの実装は次のとおりです。

  1. パブリッククラスWeightRoundRobin {
  2. 静的 整数位置 = 0;
  3. 公共 静的マップ<文字列、整数> initServicesMap() {
  4. Map<String, Integer > servicesMap = new HashMap<>();
  5. servicesMap.put( "192.168.10.00" , 1);
  6. servicesMap.put( "192.168.10.02" , 3);
  7. servicesMap.put( "192.168.10.03" , 3);
  8. servicesMap.put( "192.168.10.04" , 5);
  9. servicesMap.put( "192.168.10.05" , 5);
  10. servicesMap.put( "192.168.10.06" , 5);
  11. servicesMapを返します
  12. }
  13. 公共 静的文字列 getServerUrl() {
  14. //サーバーのオンラインとオフラインによって発生する同時実行の問題を回避するために、新しいリスト割り当てを作成します
  15. Map<String, Integer > initMap = new HashMap<>();
  16. initMap = initServicesMap();
  17. <String>を設定します。servicesSet = new HashSet<>();
  18. servicesSet.addAll(initMap.keySet());
  19. イテレータ<String> servicesIterator = servicesSet.iterator();
  20. リスト<String> servicesList = 新しい ArrayList<>();
  21. (servicesIterator.hasNext()) の間 {
  22. 文字列 server = servicesIterator.next ();
  23. 整数の重み = initMap.get(server);
  24. if(重み > 0) {
  25. ( int i=0; i<weight; i++)の場合{
  26. servicesList.add (サーバー);
  27. }
  28. }
  29. }
  30. 文字列サーバー = null ;
  31. 同期(位置){
  32. if(位置 >= servicesList.size ()) {
  33. 位置 = 0;
  34. }
  35. サーバー = servicesList.get(位置);
  36. 位置++;
  37. }
  38. サーバーを返す
  39. }
  40. 公共 静的void main(String[] args) {
  41. )の間{
  42. System.out.println (getServerUrl()) ;
  43. }
  44. }
  45. }

ランダム化アルゴリズム:

名前が示すように、N 個のサーバー IP アドレスがあります。リクエストが届くと、ランダムにサーバーに転送されます。確率の観点から見ると、リクエストの数が増えると、各サーバーに割り当てられるリクエストは最終的にほぼ等しくなります。これにより、ポーリング アルゴリズムよりも悲観的なロックが 1 つ少なくなり、同時実行パフォーマンスが大幅に向上します。

実装も非常に簡単です。

次のように:

  1. パブリッククラスRandomDemo {
  2. 公共 静的リスト<String> initServerList() {
  3. List<String> サーバー = 新しい ArrayList<>();
  4. サーバーを追加します( "192.168.10.00" );
  5. サーバーを追加します( "192.168.10.01" );
  6. サーバーを追加します( "192.168.10.02" );
  7. サーバーを追加します( "192.168.10.03" );
  8. サーバーを追加します( "192.168.10.04" );
  9. サーバーを追加します( "192.168.10.05" );
  10. サーバーを追加します( "192.168.10.06" );
  11. サーバーを返す
  12. }
  13. 公共 静的文字列 getServerUrl() {
  14. //サーバーのオンラインとオフラインによって発生する同時実行の問題を回避するために、新しいリスト割り当てを作成します
  15. リスト<String> serverList = 新しい ArrayList<>();
  16. serverList に All を追加します。
  17. int位置 = 新しい Random().nextInt(serverList.size ( ));
  18. serverList.get(position)を返します
  19. }
  20. 公共 静的void main(String[] args) {
  21. )の間{
  22. System.out.println (getServerUrl()) ;
  23. }
  24. }
  25. }

しかし、単純なポーリング アルゴリズムと同じ問題があります。

パフォーマンスが異なるサーバーを平等に扱うのは実際には不公平です。構成が低いため、要求も少なくなるはずです。

それでおしまい

重み付けランダム アルゴリズムの実装の考え方は、重み付けポーリング アルゴリズムの実装の考え方と同じで、構成の異なるサーバーに異なる重み値を設定します。コードの実装は重み付けポーリングのアイデアと同じです。重み値を満たすサービス セットを構築した後、ランダム選択が実行されます。ここでは記述せず、各自で記述してください。

送信元アドレスハッシュ (hashCode) 方式: クライアントの要求 IP に基づいてハッシュ計算を実行して値を取得し、その値をサーバーリストの数で剰余計算して、要求によってアクセスされたサーバーリストのシリアル番号を取得します。この方法の利点の 1 つは、サーバー リストが変更されていない場合、クライアントは常に固定サーバーにアクセスするため、クライアントとサーバーの間でステートフル セッションを構築できることです。

コード実装:

  1. パブリッククラスHashDemo {
  2. 公共 静的リスト<String> initServerList() {
  3. List<String> サーバー = 新しい ArrayList<>();
  4. サーバーを追加します( "192.168.10.00" );
  5. サーバーを追加します( "192.168.10.01" );
  6. サーバーを追加します( "192.168.10.02" );
  7. サーバーを追加します( "192.168.10.03" );
  8. サーバーを追加します( "192.168.10.04" );
  9. サーバーを追加します( "192.168.10.05" );
  10. サーバーを追加します( "192.168.10.06" );
  11. サーバーを返す
  12. }
  13. 公共 静的文字列 getServerUrl() {
  14. //サーバーのオンラインとオフラインによって発生する同時実行の問題を回避するために、新しいリスト割り当てを作成します
  15. リスト<String> serverList = 新しい ArrayList<>();
  16. serverList に All を追加します。
  17. int requestIpHashCode = "192.168.10.06.109" .hashCode();
  18. int位置 = requestIpHashCode % serverList.size ( ) ;
  19. serverList.get(position)を返します
  20. }
  21. 公共 静的void main(String[] args) {
  22. )の間{
  23. System.out.println (getServerUrl()) ;
  24. }
  25. }
  26. }

【編集者のおすすめ】

  1. ソフトウェア定義データセンター (SDDC) を完全に実現するにはどうすればよいでしょうか?
  2. 【おすすめ】負荷分散って難しい?これを読んで全て理解できました
  3. Linux のヒント: パスワード不要のログインを実装し、サーバーの運用とメンテナンスの時間を節約する方法
  4. ゲートウェイなしでLoRaネットワークを実現するにはどうすればいいですか?
  5. 負荷分散を試してみたいのですが、これらをご存知ですか?

<<:  Pythonを使用して独自のTwitterボットを構築する方法を学びます

>>:  人工知能と伝統的な中国医学が出会うと、青い「箱」は「見て、嗅いで、聞いて、感じることができる」

ブログ    
ブログ    

推薦する

人工知能はマーケティング業界に破壊的な影響を及ぼすだろう

ビッグデータと人工知能の市場は現在、活況を呈しています。調査会社の最近の予測によると、これら2つの技...

インダストリー4.0における人工知能

人工知能は、強化された接続性とインテリジェントな自動化を通じて、インダストリー 4.0 に破壊的な変...

PaxosアルゴリズムがRaftプロトコルとZabプロトコルの祖先である理由とその原理分析

Paxos アルゴリズムは分散分野で非常に重要な役割を果たします。ただし、Paxos アルゴリズムに...

技術者でなくても、クラウド コンピューティング、ビッグ データ、人工知能を理解することができます。

今日は、クラウド コンピューティング、ビッグ データ、人工知能の 3 つのトピックについてお話しした...

研究のアイデアがない場合は、信頼できる機械学習のための革新的なアイデア1,000個をご紹介します。

I. はじめに1. まず話をしましょう約4〜5年前、私はカーネギーメロン大学(CMU)の博士課程の...

...

肖像情報セキュリティには「内部と外部の共同管理」が必要

防疫期間中、マスクの着用は人々の日常の外出に必須の装備となった。マスク着用者の顔認識技術が実際に活用...

...

データサイエンティストが最もよく使用するアルゴリズム10選

最新の KDnuggets 調査では、データ サイエンティストの実際の業務で最もよく使用されるアルゴ...

...

Google、ファイルサイズを35%削減できる新しいJPEGアルゴリズムをオープンソース化

海外メディアの報道によると、Googleはファイルサイズを約35%削減、あるいはファイルサイズを変え...

機械学習を使用してデータセンターの電力を管理するにはどうすればよいでしょうか?

[[249391]] [51CTO.com クイック翻訳] データセンターがますます複雑になってい...

給料の心配はやめましょう。これは今後 10 年間で最も収益性の高い業界であり、横になっているときでもお金を稼ぐことができます。

小米創始者の雷軍はかつて「風の吹き口に立てば豚でも飛べる」と言った。事実は往々にしてこの通りだ。人の...

マイクロソフト、AIツール「コパイロット」があなたの仕事を奪うことはないと改めて主張

Responsible AI チームを発表した際、Microsoft の幹部は、Copilot は仕...