さまざまなWebサービスと通信するDjangoプロジェクトでPythonを実行すると、時々リクエストが通常の< 100ミリ秒ではなく約5秒かかることがあるという問題があります。Python `socket.getaddrinfo`要求の約0.1%を受け取ります
これは、socket.getaddrinfo
の機能で取られた時間に絞りました。これは、外部サービスに接続するときにrequests
によって呼び出されますが、デフォルトのDjango接続をクラスタのPostgresデータベースボックスに反映するようにも見えます。デプロイ後にuwsgi
を再起動すると、最初に送信される要求には応答を送信するのに5秒かかります。セロリのタスクは定期的に5秒かかりますが、私はまだstatsdタイマーの追跡を追加していません。
私は問題を再現するためにいくつかのコードを書いている:
import socket
import timeit
def single_dns_lookup():
start = timeit.default_timer()
socket.getaddrinfo('stackoverflow.com', 443)
end = timeit.default_timer()
return int(end - start)
timings = {}
for _ in range(0, 10000):
time = single_dns_lookup()
try:
timings[time] += 1
except KeyError:
timings[time] = 1
print timings
典型的な結果は{0: 9921, 5: 79}
私の同僚は、すでにIPv6のルックアップ時間の周りの潜在的な問題を指摘しているされていると/etc/gai.conf
にこれを追加しました:
precedence ::ffff:0:0/96 100
これは、curl
などの非Pythonプログラムからのルックアップを確実に改善しました。使用していますが、Python自体からは使用できません。サーバーボックスはUbuntu 16.04.3 LTSを実行しており、これをPython 2のバニラVMで再現することができます。
すべてのPythonルックアップのパフォーマンスを向上させるために、どのような手順を取ることができますか。< 1 ?
結果をキャッシングしてセロリなどで更新するのはどうですか? –
あなたのDNSリゾルバが遅いのが聞こえますが、ncsdに試してみてください。 – georgexsh
@ YaroslavSurzhikovあなたはキャッシュのために何を提案しますか?そして、あなたは、キャッシュを更新して高温にして、Pythonサーバーコード*がキャッシュを更新するとき以外は遅い要求を実行しないようにする方法を提案しますか? – jamesc