同期コマンドを実行して EC2 インスタンスと S3 バケット間でデータを転送しているのですが、転送が遅いです。この問題を解決するにはどうしたらいいですか?

所要時間5分
0

同期コマンドを実行して Amazon Elastic Compute Cloud (Amazon EC2) インスタンスと Amazon Simple Storage Service (Amazon S3) バケット間でデータを転送しているのですが、転送が遅いです。この問題を解決するにはどうしたらいいですか?

簡単な説明

AWS コマンドラインインターフェイス (AWS CLI) の sync コマンドは、ListObjectSv2、HeadObject、GetObject、および PutObject API 呼び出しを含む高レベルのコマンドです。 転送が遅い原因を特定するには次を実行します。

  • ユースケースのアーキテクチャを確認します。
  • ネットワーク接続を確認します。
  • Amazon S3 へのアップロードとAmazon S3 からのダウンロードの速度をテストします。
  • 同期をバックグラウンドプロセスとして実行しながら、ネットワークとリソースの負荷を確認します。

解決策

ユースケースのアーキテクチャを確認する

ネットワーク接続、転送速度、およびリソース負荷をテストする前に、転送速度に影響する可能性のある次のアーキテクチャ要因を検討してください。

  • どの Amazon EC2 インスタンスタイプ を使用していますか? この転送ユースケースでは、スループットが 10 Gbps 以上のインスタンスを使用するのがベストプラクティスです。
  • EC2 インスタンスと S3 バケットは同じ AWS リージョンにありますか? インスタンスとバケットを同じリージョンにデプロイするのがベストプラクティスです。Amazon S3 の VPC エンドポイント を、インスタンスがデプロイされている VPC にアタッチするのもベストプラクティスです。
  • 同じリージョンにあるインスタンスとバケットの場合、AWS CLI は Amazon S3 Transfer Acceleration のエンドポイントを使用するように設定されていますか? リソースが同じリージョンにある場合は、Transfer Acceleration エンドポイントを使用しないことがベストプラクティスです。
  • 転送するソースデータセットの性質はどのようなものですか? たとえば、Amazon S3 に大量の小さなファイルを転送するのか、それともいくつかの大きなファイルを転送するのかということです。 AWS CLI を使用してさまざまなソースデータセットを Amazon S3 に転送する方法の詳細については、「 Amazon S3 CLI を最大限に活用する」を参照してください。
  • どのバージョンの AWS CLI を使用していますか? AWS CLI の最新バージョンを使用していることを確認してください。
  • AWS CLI の設定はどのようなものですか?

ベストプラクティスを実行しても転送が遅い場合は、ネットワーク接続、転送速度、およびリソースの負荷を確認してください。

ネットワーク接続を確認

S3 バケットで dig コマンドを実行し、クエリ時間 フィールドで返されたクエリ応答時間を確認します。次の例では、クエリ時間 は ** 0 ミリ秒**です。

Bash

$ dig +nocomments +stats +nocmd awsexamplebucket.s3.amazonaws.com

;awsexamplebucket.s3.amazonaws.com. IN	A
awsexamplebucket.s3.amazonaws.com. 2400 IN CNAME	s3-3-w.amazonaws.com.
s3-3-w.amazonaws.com.	2	IN	A	52.218.24.66
;; Query time: 0 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Fri Dec 06 09:30:47 UTC 2019
;; MSG SIZE  rcvd: 87

IP アドレスを返すドメインネームシステム (DNS) 解決クエリの応答時間が長くなると、パフォーマンスに影響する可能性があります。クエリの応答時間が長い場合は、インスタンスの DNS サーバーを変更してみてください。 別のネットワーク接続テストとして、仮想スタイルのホスト名と、バケットの S3 リージョナルエンドポイントに TCP を使用して traceroute または mtr を実行します。次の mtr 例のリクエストは、インスタンスの VPC にアタッチされている Amazon S3 の VPC エンドポイントを経由してルーティングされます。

Bash

$ mtr -r --tcp --aslookup  --port 443 -c50  awsexamplebucket.s3.eu-west-1.amazonaws.com
Start: 2019-12-06T10:03:30+0000
HOST: ip-172-31-4-38.eu-west-1.co Loss%   Snt   Last   Avg  Best  Wrst StDev
  1. AS???    ???                 100.0    50    0.0   0.0   0.0   0.0   0.0
  2. AS???    ???                 100.0    50    0.0   0.0   0.0   0.0   0.0
  3. AS???    ???                 100.0    50    0.0   0.0   0.0   0.0   0.0
  4. AS???    ???                 100.0    50    0.0   0.0   0.0   0.0   0.0
  5. AS???    ???                 100.0    50    0.0   0.0   0.0   0.0   0.0
  6. AS???    ???                 100.0    50    0.0   0.0   0.0   0.0   0.0
  7. AS16509  s3-eu-west-1-r-w.am 62.0%    50    0.3   0.2   0.2   0.4   0.0

Amazon S3 へのアップロードとAmazon S3 からのダウンロードの速度をテストする

1.    2 GB のコンテンツを含む 5 つのテストファイルを作成します。

Bash

$ seq -w 1 5 | xargs -n1 -P 5 -I % dd if=/dev/urandom of=bigfile.% bs=1024k count=2048

$ ls -l
total 10244
-rw-rw-r-- 1 ec2-user ec2-user 2097152 Nov 8 08:14 bigfile.1
-rw-rw-r-- 1 ec2-user ec2-user 2097152 Nov 8 08:14 bigfile.2
-rw-rw-r-- 1 ec2-user ec2-user 2097152 Nov 8 08:14 bigfile.3
-rw-rw-r-- 1 ec2-user ec2-user 2097152 Nov 8 08:14 bigfile.4
-rw-rw-r-- 1 ec2-user ec2-user 2097152 Nov 8 08:14 bigfile.5

2.    AWS CLI を使用して sync コマンドを実行し、5 つのテストファイルをアップロードします。転送時間を調べるには、sync コマンドの先頭に time コマンド (Linux のマニュアルを参照) を挿入します。

**注:**sync コマンドの実行中は、スループット速度も必ず記録してください。

Bash

$ time aws s3 sync . s3://awsexamplebucket/test_bigfiles/ --region eu-west-1

Completed 8.0 GiB/10.2 GiB (87.8MiB/s) with 3 file(s) remaining

real 2m14.402s
user 2m6.254s
sys 2m22.314s

これらのテスト結果をベースラインとして使用して、ユースケースの実際の同期時間と比較できます。

同期をバックグラウンドプロセスとして実行しながら、ネットワークとリソースの負荷を確認する

1.    sync コマンドの末尾に & を追加して、コマンドをバックグラウンドで実行します。

注:ストリーム演算子 (>) を追加してテキストファイルに出力を書き込み、後で確認することもできます。

Bash

$ time aws s3 sync . s3://awsexamplebucket/test_bigfiles/ --region eu-west-1 \
> ~/upload.log &
[1] 4262
$

2.    sync コマンドがバックグラウンドで実行されている間に、mpstat コマンド (Linux のマニュアルを参照) を実行して CPU 使用率を確認します。次の例は、4 つの CPU が使用されており、その使用率が約 20% であることを示しています。

Bash

$ mpstat -P ALL 10
Average:     CPU    %usr   %nice    %sys   %iowait   %irq   %soft  %steal  %guest  %gnice  %idle
Average:     all   21.21    0.00   23.12    0.00    0.00    2.91    0.00    0.00    0.00   52.77
Average:       0   21.82    0.00   21.71    0.00    0.00    3.52    0.00    0.00    0.00   52.95
Average:       1   21.32    0.00   23.76    0.00    0.00    2.66    0.00    0.00    0.00   52.26
Average:       2   20.73    0.00   22.76    0.00    0.00    2.64    0.00    0.00    0.00   53.88
Average:       3   21.03    0.00   24.07    0.00    0.00    2.87    0.00    0.00    0.00   52.03

この場合、CPU はボトルネックではありません。使用率が 90% 以上であれば、CPU を追加したインスタンスを起動してみてください。top コマンドを実行して、実行中の最高の CPU 使用率を確認することもできます。最初にこれらのプロセスを停止してから、同期コマンドを再実行してください。

3.    sync コマンドがバックグラウンドで実行されている間に、lsof コマンド (Linux のマニュアルを参照) を実行します。これにより、ポート 443 で Amazon S3 に対して開いている TCP 接続の数がチェックされます。

注:AWS CLI 設定ファイルのユーザープロファイルで max\ _concurrent\ _requests が 20 に設定されている場合、確立された TCP 接続は最大 20 件になると予想されます。

Bash

$ lsof -i tcp:443
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
aws     4311 ec2-user    3u  IPv4  44652      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:33156->52.218.36.91:https (CLOSE_WAIT)
aws     4311 ec2-user    4u  IPv4  44654      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39240->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user    5u  IPv4  44655      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39242->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user    6u  IPv4  47528      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39244->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user    7u  IPv4  44656      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39246->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user    8u  IPv4  45671      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39248->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   13u  IPv4  46367      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39254->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   14u  IPv4  44657      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39252->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   15u  IPv4  45673      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39250->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   32u  IPv4  47530      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39258->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   33u  IPv4  45676      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39256->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   34u  IPv4  44660      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39266->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   35u  IPv4  45678      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39260->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   36u  IPv4  45679      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39262->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   37u  IPv4  45680      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39268->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   38u  IPv4  45681      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39264->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   39u  IPv4  45683      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39272->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   40u  IPv4  47533      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39270->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   41u  IPv4  44662      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39276->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   42u  IPv4  44661      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39274->52.216.162.179:https (ESTABLISHED)
aws     4311 ec2-user   43u  IPv4  44663      0t0  TCP ip-172-31-4-38.eu-west-1.compute.internal:39278->52.216.162.179:https (ESTABLISHED)

ポート 443 に他の TCP 接続がある場合は、それらの接続を停止してから sync コマンドを再実行してみてください。

TCP 接続の数を取得するには、次のコマンドを実行します。

$ lsof -i tcp:443 | tail -n +2 | wc -l
21

4.    単一の同期プロセスを最適化したら、複数の同期プロセスを並行して実行できます。これにより、ネットワーク帯域幅は広くてもネットワーク帯域幅の半分しか使用されていない場合に、単一プロセスのアップロード速度が遅くなることを回避できます。同期プロセスを並行して実行する場合は、目的のスループットが得られるようにさまざまなプレフィックスをターゲットにします。

詳細については、「Amazon S3 に大量のデータをアップロードする場合に、パフォーマンスを最適化するにはどうすればよいですか?」を参照してください。


AWS公式
AWS公式更新しました 1年前
コメントはありません

関連するコンテンツ