すべてのプロダクト
Search
ドキュメントセンター

Alibaba Cloud Service Mesh:EWMA を使用したワークロードレイテンシに基づく負荷分散

最終更新日:Jan 13, 2025

Service Mesh (ASM) バージョン 1.21 では、新しい負荷分散アルゴリズムであるピーク指数加重移動平均 (ピーク EWMA) が提供されています。このアルゴリズムは、静的重み、レイテンシ、エラー率、その他の要因の移動平均を計算してノードのスコアを取得し、負荷分散に適したノードを選択します。バックエンドサービスがバーストトラフィックを処理する必要がある場合、ASM はピーク EWMA 負荷分散アルゴリズムを使用して、バックエンドサービスポッドの最大負荷とリアルタイムの応答時間を考慮し、適切なポッドにトラフィックを柔軟に分散することで、バーストトラフィックをより適切に処理できます。このトピックでは、EWMA を構成および使用して、ワークロードレイテンシに基づく負荷分散を実装する方法について説明します。

背景情報

ASM は、ラウンドロビン、最小リクエスト、ランダムなど、さまざまな一般的な負荷分散アルゴリズムを提供しています。これらのアルゴリズムは、ほとんどのビジネスシナリオの要件を満たし、特定のパフォーマンスを保証できます。ただし、これらのアルゴリズムは、バックエンドサービスポッドのリアルタイムのステータスとパフォーマンスを考慮せずに、静的ルールに基づいてバックエンドサービスポッドを選択することしかできません。

たとえば、バックエンドサービスポッドのホスト上のリソースが他のアプリケーションによって占有されている場合でも、デフォルトの負荷分散アルゴリズムを使用する ASM インスタンスは、他のアイドル状態のポッドではなく、このポッドを選択します。その結果、バックエンドサービスは、より高いレイテンシでリクエストに応答するか、リクエストがタイムアウトすることさえあります。この場合、負荷分散アルゴリズムがパフォーマンスの低下したこのポッドをインテリジェントに無視し、トラフィックを他のアイドル状態のポッドにルーティングできれば、アプリケーションの全体的なエラー率と応答レイテンシを大幅に削減できます。

前提条件

ピーク EWMA の使用

  1. ASM コンソール にログインします。左側のナビゲーションペインで、[service Mesh] > [メッシュ管理] を選択します。

  2. [メッシュ管理] ページで、ASM インスタンスの名前をクリックします。左側のナビゲーションペインで、[トラフィック管理センター] > [destinationrule] を選択します。表示されるページで、[YAML から作成] をクリックします。

  3. 次のサンプルコードを入力し、[作成] をクリックします。次のサンプル YAML コードは、default ネームスペースの simple-server サービスに PEAK_EWMA 負荷分散アルゴリズムを指定しています。

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: simple-server
      namespace: default
    spec:
      host: simple-server.default.svc.cluster.local
      trafficPolicy:
        loadBalancer:
          simple: PEAK_EWMA # ASM の PEAK_EWMA 負荷分散アルゴリズムを使用します。
    

説明

この例では、simple-server アプリケーションがサーバーです。 sleep アプリケーションはテストトラフィックを送信するクライアントとして機能し、simple-server アプリケーションに基づく simple-server.default.svc.cluster.local サービスはサーバーとして機能します。このサービスには、構成の異なる 2 つのデプロイメントがあります。

  • simple-server-normal: このデプロイメントの応答レイテンシは 50 ms から 100 ms の範囲です。

  • simple-server-hight-latency: このデプロイメントの応答レイテンシは 500 ms から 2000 ms の範囲です。このデプロイメントは、サービスの一部のワークロードのレイテンシの増加をシミュレートするために使用されます。

ステップ 1:ASM インスタンスのメトリック監視を有効にする

ピーク EWMA 負荷分散アルゴリズムの利点を視覚的に示すために、この例では ASM インスタンスのメトリック監視を有効にして、ピーク EWMA 負荷分散アルゴリズムが有効になる前後のサービスの全体的な応答レイテンシの変化を観察します。メトリック監視を有効にし、Application Real-Time Monitoring Service (ARMS) にメトリックを収集する方法の詳細については、「Managed Service for Prometheus にメトリックを収集する」をご参照ください。

ステップ 2:必要な環境をデプロイする

  1. kubeconfig ファイルの情報に基づいて kubectl を使用して ACK クラスタに接続し、次の内容を含む sleep.yaml ファイルを作成します。

    YAML ファイルを表示

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sleep
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sleep
      labels:
        app: sleep
        service: sleep
    spec:
      ports:
      - port: 80
        name: http
      selector:
        app: sleep
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sleep
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sleep
      template:
        metadata:
          labels:
            app: sleep
        spec:
          terminationGracePeriodSeconds: 0
          serviceAccountName: sleep
          containers:
          - name: sleep
            image: curlimages/curl
            command: ["/bin/sleep", "infinity"]
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /etc/sleep/tls
              name: secret-volume
          volumes:
          - name: secret-volume
            secret:
              secretName: sleep-secret
              optional: true
    ---
    

    次のコマンドを実行して、sleep アプリケーションをデプロイします。

    kubectl apply -f sleep.yaml
    
  2. 次の内容を含む simple.yaml ファイルを作成します。

    YAML ファイルを表示

    apiVersion: v1
    kind: Service
    metadata:
      name: simple-server
      labels:
        app: simple-server
        service: simple-server
    spec:
      ports:
      - port: 8080
        name: http
      selector:
        app: simple-server
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: simple-server
      name: simple-server-normal
      namespace: default
    spec:
      progressDeadlineSeconds: 600
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: simple-server
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: simple-server
        spec:
          containers:
          - args:
            - --delayMin
            - "50"
            - --delayMax
            - "100"
            image: registry-cn-hangzhou.ack.aliyuncs.com/test-public/simple-server:v1.0.0.0-g88293ca-aliyun
            imagePullPolicy: IfNotPresent
            name: simple-server
            ports:
            - containerPort: 80
              protocol: TCP
            resources:
              limits:
                cpu: 500m
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          terminationGracePeriodSeconds: 30
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: simple-server
      name: simple-server-high-latency
      namespace: default
    spec:
      progressDeadlineSeconds: 600
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: simple-server
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: simple-server
        spec:
          containers:
          - args:
            - --delayMin
            - "500"
            - --delayMax
            - "2000"
            image: registry-cn-hangzhou.ack.aliyuncs.com/test-public/simple-server:v1.0.0.0-g88293ca-aliyun
            imagePullPolicy: IfNotPresent
            name: simple-server
            ports:
            - containerPort: 80
              protocol: TCP
            resources:
              limits:
                cpu: 500m
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          terminationGracePeriodSeconds: 30
    ---
    
    

    次のコマンドを実行して、simple-server-normal アプリケーションと simple-server-high-latency アプリケーションをデプロイします。

    kubectl apply -f simple.yaml
    

ステップ 3:デフォルトの負荷分散アルゴリズムでテストを開始する

デフォルトの負荷分散アルゴリズム LEAST_REQUEST を使用してテストを行い、ベースラインデータを生成します。

  1. 次のコマンドを実行してテストを開始します。 simple-server サービスの /hello パスにアクセスするために 100 件のリクエストが送信されます。

    kubectl exec -it deploy/sleep -c sleep --  sh -c 'for i in $(seq 1 100); do time curl simple-server:8080/hello; echo "request $i done"; done'
    

    予期される出力:

    hello
     this is port: 8080real 0m 0.06s
    user    0m 0.00s
    sys     0m 0.00s
    request 1 done
    hello
     this is port: 8080real 0m 0.09s
    user    0m 0.00s
    sys     0m 0.00s
    request 2 done
    
    ......
    
    hello
     this is port: 8080real 0m 1.72s
    user    0m 0.00s
    sys     0m 0.00s
    request 100 done
    
  2. コマンドを実行した後、[メッシュ管理] ページで目的の ASM インスタンスの名前をクリックします。左側のナビゲーションペインで、[可観測性管理センター] > [監視メトリック] を選択します。 [cloud ASM Istio Service] タブをクリックし、次のフィルター条件を構成します。

    • ネームスペース:default

    • サービス:simple-server.default.svc.cluster.local

    • レポーター:destination

    • クライアントワークロードネームスペース:default

    • クライアントワークロード:sleep

    • サービスワークロードネームスペース:default

    • サービスワークロード:simple-server-normal + simple-server-high-latency

  3. [クライアントワークロード] をクリックして、[送信元別受信リクエスト期間] セクションを表示します。

    image

    sleep アプリケーションから simple-server サービスへのリクエストの P50 応答レイテンシは 87.5 ms であり、P95 応答レイテンシは 2.05 秒に大幅に上昇していることがわかります。これは、simple-server-high-latency アプリケーションの応答レイテンシが高いため、simple-server サービスの全体的な応答時間が長くなっているためです。

    重要

    上記のテスト結果は、制御された実験環境で得られた理論値です。実際の結果は、ビジネス環境によって異なる場合があります。

ステップ 4:ピーク EWMA 負荷分散アルゴリズムを構成し、テストを再実行する

simple-server サービスのピーク EWMA 負荷分散アルゴリズムを構成する宛先ルールを作成します。

  1. ピーク EWMA の使用 の手順を参照して、次の YAML コンテンツを使用して宛先ルールを作成します。

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: simple-server
      namespace: default
    spec:
      host: simple-server.default.svc.cluster.local
      trafficPolicy:
        loadBalancer:
          simple: PEAK_EWMA
    
  2. kubeconfig ファイルの情報に基づいて kubectl を使用して ACK クラスタに接続し、次のコマンドを実行してテストを再実行します。

    kubectl exec -it deploy/sleep -c sleep --  sh -c 'for i in $(seq 1 100); do time curl simple-server:8080/hello; echo "request $i done"; done'
    
  3. ステップ 3 を参照してテスト結果を観察します。結果は、P90、P95、および P99 のレイテンシが大幅に減少していることを示しています。これは、ピーク EWMA 負荷分散アルゴリズムが simple-server-high-latency ワークロードのレイテンシが高いことを検出し、負荷分散の重みを減らすためです。その結果、より多くのリクエストがレイテンシの低い simple-server-normal にルーティングされます。 simple-server サービスの観点からは、リクエストの全体的なレイテンシが大幅に削減されます。

    image