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

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

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

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

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

ブログ    
ブログ    
ブログ    
ブログ    
ブログ    

推薦する

Baidu UNITが小能科技を支援し、ハイアールグループと提携してインテリジェントクラウド顧客サービスをアップグレード

インテリジェントな顧客サービスの分野は、2018 年に急速な発展を遂げました。企業の人件費を抑制する...

ジェネレーティブ AI がサイバーセキュリティのスキルギャップに与える影響

サイバーセキュリティ分野の仕事は需要が高く、有能な従業員が求められています。アメリカ国立標準技術研究...

テクノロジーは農作物の栽培プロセスを変えています。何か食べたいときはロボットに頼まなければなりません

Science News for Students によると、食物の栽培は通常、種から始まります。そ...

AI の力: Docker による機械学習アプリケーションの導入とスケーラビリティの簡素化

翻訳者 |李睿レビュー | Chonglou近年、機械学習の応用が爆発的に増加しており、堅牢でスケー...

Red Hat は Ansible の自動化に IBM Watsonx コード生成を採用

Red Hat Inc. は本日、情報技術自動化のための生成 AI サービスである IBM Wats...

Pythonがリードを拡大、PyTorchはわずか6.4%

最近、有名なデータサイエンスのウェブサイト KDnuggets が、2018 年のデータサイエンスお...

人工知能の罪と罰についても話しましょう

1. ある人にとっての好物は、別の人にとっては毒物かもしれない人工知能 (AI) が独自の言語を作成...

人工知能と機械学習の時代に新たなサイバー脅威にどう対抗するか

侵入テスト サービスの必要性は、システムへの攻撃が頻繁に行われるようになった 1 世紀以上にわたって...

Transformer ではまだ注意が必要ですか?

ここ数週間、AI コミュニティでは、注意を必要としないアーキテクチャを使用して言語モデルを実装すると...

...

太陽光発電や風力発電に AI はメリットをもたらすのでしょうか?

太陽光発電と風力発電は急成長しているが、世界の再生可能電力への移行は、気候目標を迅速に達成するにはま...

弱電産業におけるAIの応用動向

近年、セキュリティ業界では、デジタル化された人工知能の学習および認識技術の概念がかなり普及しています...

...

自動機械学習ガイド: 4 つの成熟モデル

[51CTO.com クイック翻訳] 人工知能と機械学習の概念は、データサイエンスコミュニティで人気...

自動運転車向けエッジAIコンピューティングの可能性

自動運転はエッジコンピューティングの重要な応用分野です。自動運転には100~1000TOPSのエッジ...