3

2台のサーバーがあります(AとBという名前を付けます)。

事実:

  • それらは同じCPU、メモリ、マザーボード、ハードドライブ、アップリンク速度を持っています。
  • これらは両方とも、Python2.7.3とDjangoの最新リビジョンを備えたUbuntu12.04上にあります。
  • また、同じ名前のサーバーが設定された同じデータセンターにあります。
  • ネームサーバーと同様のpingとtracerouteの結果が得られます。

サーバーAは正常に動作します。私の問題は、Pythonを使用してインターネットに接続するときにサーバーBが非常に遅いことです。

以下は、両方のサーバーで行ったテストです(domain_list_1とdomain_list_2は、各リストに100個の一意のドメインを含む2つのリストです)。

テスト1:

starttime = time.time()
for domain in domain_list_1:
    ip = socket.gethostbyname(domain)
print '%.1f items per second' % (100/(time.time()-starttime))
>> Server A Results: 3.3 items per second
>> Server B Results: 0.7 items per second

テスト2:

starttime = time.time()
for domain in domain_list_2:
    os.system('nslookup %s > /dev/null' % domain)
print '%.1f items per second' % (100/(time.time()-starttime))
>> Server A Results: 3.3 items per second
>> Server B Results: 3.3 items per second

テスト2からわかるように、サーバーBのネットワークには問題はありません。

urllib2で同様のテストを行いましたが、結果は同じです(サーバーAは問題ありませんが、サーバーBはwgetまたはcurlを使用して同じジョブを実行するよりもurllib2を使用すると低速です)。だから私はそれがPythonの問題だと信じています。サーバーBのPythonセットアップで何がうまくいかなかったのかわかりません。

内部プロセスをプロファイリングして、コードのどの部分がプロセス全体の速度を低下させているかを確認する方法はありますか?

前もって感謝します!

4

1 に答える 1

2

Greg からの提案に基づいて、strace の出力を調べたところ、次のことがわかりました。

サーバー A:

12879 21:29:24.182590 connect(5, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("206.251.73.9")}, 16) = 0 <0.000035>
12879 21:29:24.182694 poll([{fd=5, events=POLLOUT}], 1, 0) = 1 ([{fd=5, revents=POLLOUT}]) <0.000018>
12879 21:29:24.182778 sendto(5, "'!\1\0\0\1\0\0\0\0\0\0\njanadrakka\3com\0\0\1\0\1", 32, MSG_NOSIGNAL, NULL, 0) = 32 <0.000040>
12879 21:29:24.182881 poll([{fd=5, events=POLLIN}], 1, 5000) = 1 ([{fd=5, revents=POLLIN}]) <0.067000>
12879 21:29:24.249987 ioctl(5, FIONREAD, [130]) = 0 <0.000022>
12879 21:29:24.250100 recvfrom(5, "'!\201\200\0\1\0\1\0\2\0\2\njanadrakka\3com\0\0\1\0\1"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("206.251.73.9")}, [16]) = 130 <0.000032>
12879 21:29:24.250287 close(5)          = 0 <0.000053>

サーバー B:

4850  21:28:55.501276 connect(5, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("206.251.73.9")}, 16) = 0 <0.000019>
4850  21:28:55.501348 poll([{fd=5, events=POLLOUT}], 1, 0) = 1 ([{fd=5, revents=POLLOUT}]) <0.000014>
4850  21:28:55.501419 sendto(5, "\346\10\1\0\0\1\0\0\0\0\0\0\fdeghatgostar\3com\0\0\1"..., 34, MSG_NOSIGNAL, NULL, 0) = 34 <0.000036>
4850  21:28:55.501506 poll([{fd=5, events=POLLIN}], 1, 5000) = 1 ([{fd=5, revents=POLLIN}]) <0.615731>
4850  21:28:56.117335 ioctl(5, FIONREAD, [129]) = 0 <0.000033>
4850  21:28:56.117429 recvfrom(5, "\346\10\201\200\0\1\0\1\0\2\0\2\fdeghatgostar\3com\0\0\1"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("206.251.73.9")}, [16]) = 129 <0.000011>
4850  21:28:56.117499 close(5)          = 0 <0.000009>

このシステム コールで遅延が発生しました。

A: 12879 21:29:24.182881 poll([{fd=5, events=POLLIN}], 1, 5000) = 1 ([{fd=5, revents=POLLIN}]) < 0.067000 >

B: 4850 21:28:55.501506 poll([{fd=5, events=POLLIN}], 1, 5000) = 1 ([{fd=5, revents=POLLIN}]) < 0.615731 >

ソリューション:

サーバー B での IPv6 dns ルックアップが原因で遅延が発生したようです。ただし、サーバー A でこのような問題が発生しない理由はまだわかりませんが、サーバー B で次の変更を行うと解決します。

次の行を /etc/sysctl.conf に追加し、サーバーを再起動します。

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

最後に、アドバイスをくれた Greg に感謝します。

于 2012-11-09T05:49:01.213 に答える