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

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

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

  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ボットを構築する方法を学びます

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

ブログ    

推薦する

地下鉄乗車時の「顔認識」:AI専門家にとって新たな金鉱

[[276754]]業界のすべての実務者が合意に達することはまれですが、AI業界は例外です。ほぼすべ...

強力なJavaScriptによりスノーフレークアルゴリズムが実現

[[353520]]この記事はWeChat公式アカウント「妹の味」から転載したもので、著者は妹が飼っ...

...

2秒で2枚の画像を3D再構築!このAIツールはGitHubで人気です、ネットユーザー:Soraを忘れてください

必要なのは2枚の写真だけで、追加のデータを測定する必要はありません——ディンディン、完全な 3D ク...

中国は人工知能において3つの大きな優位性を持ち、5年後には日本と米国を追い抜くでしょう!

現在、私たちは「インターネット+」から「人工知能」への移行を経験しています。人工知能の発展は、技術レ...

...

Google は、MLM 損失で直接事前トレーニングされた 24 個の小さな BERT モデルをリリースしました。

[[318598]] Google は最近、24 個の合理化された BERT モデルをダウンロード...

人工知能がデータアナリストに与える影響

セミナーで講演したイエローフィンのCEO、グレン・ラビー氏は、多くのアナリストが自動化や人工知能によ...

エッジAIの台頭

「今日のテクノロジーの世界では、クラウドにおける AI とエッジにおける AI の統合が重要です」と...

AIが人々の職場復帰を支援:重慶の音声ロボット、北京の無人配達、広州の顔認識体温測定

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

...

寒い冬の「火」、快手は流行に逆らって1,000人以上を募集

春が来たが、インターネットの寒い冬の影はまだ消えていない。年初から人員削減、外部採用の中止、採用削減...

世界中のロボットが1つの脳を共有する、Google DeepMindが第一歩を踏み出した

過去 1 年間、生成型人工知能の開発におけるキーワードは「ビッグ」でした。強化学習の先駆者であるリッ...