Java 上級: 負荷分散のための 5 つのアルゴリズムの詳細な理解

Java 上級: 負荷分散のための 5 つのアルゴリズムの詳細な理解

この記事はWeChatの公開アカウント「Android Development and Programming」から転載したもので、著者はAndroid Development and Programmingです。この記事を転載する場合は、Android 開発プログラミング パブリック アカウントにお問い合わせください。

序文

負荷分散とは何ですか?

複数のサーバーを対称的に構成したサーバーセットを指します。各サーバーは同等の地位を持ち、他のサーバーの支援なしに独立して外部にサービスを提供できます。何らかの負荷分散技術により、外部から送信されたリクエストは対称構造のサーバーに均等に分散され、リクエストを受信したサーバーはクライアントのリクエストに独立して応答します。負荷分散により、クライアント要求をサーバー アレイに均等に分散できるため、重要なデータへの高速アクセスが可能になり、多数の同時アクセス サービスの問題が解決されます。このクラスター テクノロジにより、最小限の投資で大規模なメインフレームに近いパフォーマンスを実現できます。

今日は以下のことについてお話します。

1. 負荷分散アルゴリズムの概要

1. 投票方法

実際の接続数やサーバーの現在のシステム負荷に関係なく、各バックエンド サーバーを平等に扱い、リクエストをバックエンド サーバーに順番に分散します。

2. ランダム法

システムのランダム アルゴリズムにより、バックエンド サーバーのリスト サイズ値に基づいて、アクセスするサーバーの 1 つがランダムに選択されます。確率統計理論によれば、クライアントがサーバーを呼び出す回数が増えるにつれて、実際の効果は各バックエンドサーバーへの呼び出し量を均等に分散することにますます近づき、つまりポーリングの結果になります。

3. 送信元アドレスのハッシュ

ソース アドレス ハッシュの考え方は、クライアントの IP アドレスを取得し、ハッシュ関数を通じて値を計算することです。この値は、サーバー リストのサイズに対してモジュロ演算を実行するために使用されます。結果は、クライアントがアクセスするサーバーのシリアル番号です。負荷分散には送信元アドレス ハッシュを使用します。同じ IP アドレスを持つクライアントの場合、バックエンド サーバー リストが変更されていない場合は、アクセスするたびに同じバックエンド サーバーにマップされます。

4. 加重ラウンドロビン

バックエンド サーバーによってマシン構成や現在のシステム負荷が異なる場合があり、そのためストレス耐性も異なります。構成が高く負荷が低いマシンに高い重みを割り当てて、より多くのリクエストを処理できるようにします。構成が低く負荷が高いマシンに低い重みを割り当てて、システム負荷を軽減します。重み付けポーリングはこの問題を適切に処理し、重みに従って順番にバックエンドにリクエストを分散します。

5. 加重ランダム法

加重ラウンドロビン方式と同様に、加重ランダム方式でも、バックエンド マシンの構成とシステムの負荷に基づいて異なる重みが割り当てられます。違いは、順序ではなく重みに応じてバックエンド サーバーをランダムに要求することです。

2. 5つの負荷分散アルゴリズムを実装するコード

1. 投票方法

  1. java.util.* をインポートします。
  2. java.util.concurrent.ConcurrentHashMap をインポートします。
  3. パブリッククラスTestRoundRobin{
  4. // 1. マップ、キー-ip、値-weightを定義する
  5. 静的Map<String, Integer > ipMap = new HashMap<>();
  6. 静的{
  7. ipMap.put( "192.168.13.1" ,1);
  8. ipMap.put( "192.168.13.2" ,1);
  9. ipMap.put( "192.168.13.3" ,1);
  10. }
  11. //整数 合計= 0;
  12. 整数pos = 0;
  13. パブリック文字列ラウンドロビン(){
  14. Map<String, Integer > ipServerMap = 新しい ConcurrentHashMap<>();
  15. ipServerMap.putAll(ipMap);
  16. // 2.キーを取り出してセット入れる
  17. <文字列> ipset = ipServerMap.keySet()を設定します
  18. // 3.セットリストに入れ、リストをループして取り出す
  19. ArrayList<文字列> iplist=新しいArrayList<文字列>();
  20. iplist.addAll(ipset);
  21. 文字列 serverName = null ;
  22. // 4. ループ値を定義し、それが設定された値より大きい場合は0 から開始します。
  23. 同期(pos){
  24. (pos>= ipset.size ())の場合{
  25. 位置=0;
  26. }
  27. serverName=iplist.get(pos);
  28. // 投票 +1
  29. 位置++;
  30. }
  31. serverNameを返します
  32. }
  33. 公共 静的void main(String[] args) {
  34. テストラウンドロビン testRoundRobin=新しいテストラウンドロビン();
  35. ( int i=0;i<10;i++)の場合{
  36. 文字列 serverIp=testRoundRobin.RoundRobin();
  37. System.out.println(サーバーIP ) ;
  38. }
  39. }
  40. }

2. 加重ラウンドロビン

  1. java.util.* をインポートします。
  2. java.util.concurrent.ConcurrentHashMap をインポートします。
  3. パブリッククラスTestWeightRobin {
  4. // 1.map、キー-ip、値-重み
  5. 静的Map<String, Integer > ipMap = new HashMap<>();
  6. 静的{
  7. ipMap.put( "192.168.13.1" ,1);
  8. ipMap.put( "192.168.13.2" ,2);
  9. ipMap.put( "192.168.13.3" ,4);
  10. }
  11. 整数pos=0;
  12. パブリック文字列WeightRobin(){
  13. Map<String, Integer > ipServerMap = 新しい ConcurrentHashMap<>();
  14. ipServerMap.putAll(ipMap);
  15. <文字列> ipSet = ipServerMap.keySet() を設定します
  16. イテレータ<文字列> ipIterator=ipSet.iterator();
  17. //すべてのサーバーを配置するリストを定義する
  18. ArrayList<文字列> ipArrayList=新しいArrayList<文字列>();
  19. //セットをループしマップの値を使用してセットの値を見つけ、対応する数のサーバーをリストに追加します。
  20. (ipIterator.hasNext()) の間{
  21. 文字列 serverName = ipIterator.next ();
  22. 整数の重み=ipServerMap.get(serverName);
  23. ( int i = 0; i < 重み; i++) {
  24. ipArrayList.add (サーバー名);
  25. }
  26. }
  27. 文字列 serverName = null ;
  28. if (pos>= ipArrayList.size ()){
  29. 位置=0;
  30. }
  31. serverName=ipArrayList.get(pos);
  32. // 投票 +1
  33. 位置++;
  34. serverNameを返します
  35. }
  36. 公共 静的void main(String[] args) {
  37. テストウェイトロビン testWeightRobin=新しいテストウェイトロビン();
  38. ( int i =0;i<10;i++)の場合{
  39. 文字列 server=testWeightRobin.WeightRobin();
  40. System.out.println (サーバー) ;
  41. }
  42. }
  43. }

3. ランダム法

  1. java.util.* をインポートします。
  2. java.util.concurrent.ConcurrentHashMap をインポートします。
  3. パブリッククラスTestRandom{
  4. // 1. マップ、キー-ip、値-weightを定義する
  5. 静的Map<String, Integer > ipMap = new HashMap<>();
  6. 静的{
  7. ipMap.put( "192.168.13.1" ,1);
  8. ipMap.put( "192.168.13.2" ,2);
  9. ipMap.put( "192.168.13.3" ,4);
  10. }
  11. パブリック文字列ランダム() {
  12. Map<String, Integer > ipServerMap = 新しい ConcurrentHashMap<>();
  13. ipServerMap.putAll(ipMap);
  14. <文字列> ipSet = ipServerMap.keySet() を設定します
  15. //すべてのサーバーを配置するリストを定義する
  16. ArrayList<文字列> ipArrayList=新しいArrayList<文字列>();
  17. ipArrayList.addAll(ipSet);
  18. // 乱数をループする
  19. ランダム random=new Random();
  20. //リストから乱数を取得します (1- list.size )
  21. int pos=random.nextInt(ipArrayList.size ( ));
  22. 文字列 serverNameReturn = ipArrayList.get(pos);
  23. serverNameReturnを返します
  24. }
  25. 公共 静的void main(String[] args) {
  26. TestRandom testRandom=新しい TestRandom();
  27. ( int i =0;i<10;i++)の場合{
  28. 文字列 server=testRandom.Random();
  29. System.out.println (サーバー) ;
  30. }
  31. }
  32. }

4. 加重ランダム

  1. java.util.* をインポートします。
  2. java.util.concurrent.ConcurrentHashMap をインポートします。
  3. パブリッククラスTestRobinRandom{
  4. // 1. マップ、キー-ip、値-weightを定義する
  5. 静的Map<String, Integer > ipMap = new HashMap<>();
  6. 静的{
  7. ipMap.put( "192.168.13.1" ,1);
  8. ipMap.put( "192.168.13.2" ,2);
  9. ipMap.put( "192.168.13.3" ,4);
  10. }
  11. パブリック文字列RobinRandom(){
  12. Map<String, Integer > ipServerMap = 新しい ConcurrentHashMap<>();
  13. ipServerMap.putAll(ipMap);
  14. <文字列> ipSet = ipServerMap.keySet() を設定します
  15. イテレータ<文字列> ipIterator=ipSet.iterator();
  16. //すべてのサーバーを配置するリストを定義する
  17. ArrayList<文字列> ipArrayList=新しいArrayList<文字列>();
  18. //セットをループしマップの値を使用してセットの値を見つけ、対応する数のサーバーをリストに追加します。
  19. (ipIterator.hasNext()) の間{
  20. 文字列 serverName = ipIterator.next ();
  21. 整数の重み=ipServerMap.get(serverName);
  22. ( int i=0;i<weight;i++)の場合{
  23. ipArrayList.add (サーバー名);
  24. }
  25. }
  26. // 乱数をループする
  27. ランダム random=new Random();
  28. //リストから乱数を取得します (1- list.size )
  29. int pos=random.nextInt(ipArrayList.size ( ));
  30. 文字列 serverNameReturn = ipArrayList.get(pos);
  31. serverNameReturnを返します
  32. }
  33. 公共 静的void main(String[] args) {
  34. TestRobinRandom testRobinRandom=新しい TestRobinRandom();
  35. ( int i =0;i<10;i++)の場合{
  36. 文字列 server=testRobinRandom.RobinRandom();
  37. System.out.println (サーバー) ;
  38. }
  39. }
  40. }

5. 送信元アドレスのハッシュ

  1. java.util.ArrayList をインポートします。
  2. java.util.HashMap をインポートします。
  3. java.util.Map をインポートします。
  4. java.util.Setをインポートします
  5. java.util.concurrent.ConcurrentHashMap をインポートします。
  6. パブリッククラスipHash{
  7. // 1. マップ、キー-ip、値-weightを定義する
  8. 静的Map<String, Integer > ipMap = new HashMap<>();
  9. 静的{
  10. ipMap.put( "192.168.13.1" ,1);
  11. ipMap.put( "192.168.13.2" ,2);
  12. ipMap.put( "192.168.13.3" ,4);
  13. }
  14. パブリック文字列ipHash(文字列クライアントIP){
  15. Map<String, Integer > ipServerMap = 新しい ConcurrentHashMap<>();
  16. ipServerMap.putAll(ipMap);
  17. // 2.キーを取り出してセット入れる
  18. <文字列> ipset = ipServerMap.keySet()を設定します
  19. // 3.セットリストに入れ、リストをループして取り出す
  20. ArrayList<文字列> iplist=新しいArrayList<文字列>();
  21. iplist.addAll(ipset);
  22. // IPのハッシュコード値の残りを取得します。これは毎回同じです
  23. intハッシュコード = クライアントIP.ハッシュコード();
  24. int serverListsize = iplist.size ( );
  25. int pos=ハッシュコード%サーバーリストサイズ;
  26. iplist.get(pos);を返します
  27. }
  28. 公共 静的void main(String[] args) {
  29. ipHash iphash = 新しい ipHash();
  30. 文字列サーバー名 = iphash.ipHash( "192.168.21.2" );
  31. System.out.println (サーバー名) ;
  32. }
  33. }

要約する

前進しなければ遅れを取ってしまいます。一緒に頑張りましょう!

<<:  顔認識技術は「束縛」されているのか?テクノロジーはまだシステムを待つ必要がある

>>:  この3つのロボットを知っていますか?

ブログ    
ブログ    

推薦する

自己教師学習の効率限界を突破! Ma Yi と LeCun が共同で EMP-SSL をリリース: 特別なトリックは不要、30 エポックで SOTA を達成可能

過去数年間、教師なし学習と自己教師あり学習 (SSL) は大きな進歩を遂げてきました。SSL を通じ...

MITの研究者はAIを使って自動運転車が赤信号でアイドリングを回避できるように支援する

ドライバーが毎回信号を直進できるように旅行を計画できたらどうなるでしょうか?これは、特に幸運な状況下...

BaiduのNLP自然言語処理技術の最も包括的な分析

[[209979]] AI時代には、コンピューターが視覚、聴覚、行動、言語の知能を持つようになること...

AIで意思決定を自動化するのは超簡単ですか?

人工知能とは何を意味するのでしょうか?人工知能はコンピュータサイエンスの範囲を指し、AI とは、設計...

CMU、NUS、Fudanが共同でDataLabを立ち上げ:テキストフィールドでのデータ分析と処理のためのMatlabを作成

データ中心の人工知能の構築は、今後のトレンドになりつつあります。 1年以上前、アンドリュー・ン氏は「...

再帰アルゴリズムにおけるリンクリスト操作

今日は、問題をさらに一歩進めて、再帰プロセスに対応する操作を追加する予定です。 (免責事項: 以下の...

AIの諸刃の剣:質問を検索するために写真を撮ることと不正行為を支援すること

子どもを指導しているとき、圧倒されたり、怒りすぎて気が狂いそうになったりすることがありますか? [[...

...

人工知能が生き残るために頼りにしているビッグデータは、独占企業の手に渡ると本当に恐ろしいものになる

わずか5年で、人工知能は急速に発展しました。最近、GPT-3が再び白熱した議論を巻き起こしています。...

...

マルチユーザーデータ取得: LangChain 技術ガイドとケーススタディ

著者 | 崔昊レビュー | Chonglouまとめこの記事では、さまざまなユーザー データの分離を確...

Baiduの新しいAIインフラがCIFTISでデビューし、CTOの王海峰が業界インテリジェンスの推進におけるBaiduの成果を紹介

AIはあらゆる分野に新たな活力を吹き込み、AIの新しいインフラはサービス貿易部門を含む社会経済の発展...

...

スーパー暗号解読:自動運転はこうして実現される

多くの新製品と同様に、自動運転に対する人々の態度は、過度の信頼から過少な信頼まで二極化しています。自...