10

boto 経由で dynamodb をテストしていますが、ハッシュキー、レンジキー条件クエリに基づくデータ セットの取得が驚くほど遅いことがわかりました。SSL (is_secure) が非 SSL よりも約 6 倍速く実行されるという奇妙な点についての議論をいくつか見てきましたが、その発見を確認することができます。しかし、ssl を使用しても、かなり小さなデータ セット (1K レコード未満) でハッシュキー/範囲キー条件を使用して 300 レコードを取得するのに 1 ~ 2 秒かかります。

profilehooks プロファイラーを実行すると、300 レコードを取得するために、ssl.py で 20617 ncalls の順序で多くの余分な時間が費やされていることがわかります。レコードあたり 10 回の呼び出しでも、予想の 6 倍以上になるようです。これはミディアム インスタンスですが、マイクロ インスタンスでも同じ結果が得られます。500 回の読み取り/秒 1000 回の書き込み/秒 スロットルが記録されていないプロビジョニング。

バッチ リクエストの実行を検討しましたが、範囲キー条件を使用できないため、そのオプションが排除されました。

私が時間を失っている場所についてのアイデアは大歓迎です!!

  144244 function calls in 2.083 CPU seconds

並べ替え: 累積時間、内部時間、呼び出し回数

  ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    1    0.001    0.001    2.083    2.083 eventstream.py:427(session_range)
  107    0.006    0.000    2.081    0.019 dynamoDB.py:36(rangeQ)
  408    0.003    0.000    2.073    0.005 layer2.py:493(query)
  107    0.001    0.000    2.046    0.019 layer1.py:435(query)
  107    0.002    0.000    2.040    0.019 layer1.py:119(make_request)
  107    0.006    0.000    1.988    0.019 connection.py:699(_mexe)
  107    0.001    0.000    1.916    0.018 httplib.py:956(getresponse)
  107    0.002    0.000    1.913    0.018 httplib.py:384(begin)
  662    0.049    0.000    1.888    0.003 socket.py:403(readline)
20617    0.040    0.000    1.824    0.000 ssl.py:209(recv)
20617    0.036    0.000    1.785    0.000 ssl.py:130(read)
20617    1.748    0.000    1.748    0.000 {built-in method read}
  107    0.002    0.000    1.738    0.016 httplib.py:347(_read_status)
  107    0.001    0.000    0.170    0.002 mimetools.py:24(__init__)
  107    0.000    0.000    0.165    0.002 rfc822.py:88(__init__)
  107    0.007    0.000    0.165    0.002 httplib.py:230(readheaders)
  107    0.001    0.000    0.031    0.000 __init__.py:332(loads)
  107    0.001    0.000    0.028    0.000 decoder.py:397(decode)
  107    0.008    0.000    0.026    0.000 decoder.py:408(raw_decode)
  107    0.001    0.000    0.026    0.000 httplib.py:910(request)
  107    0.003    0.000    0.026    0.000 httplib.py:922(_send_request)
  107    0.001    0.000    0.025    0.000 connection.py:350(authorize)
  107    0.004    0.000    0.024    0.000 auth.py:239(add_auth)
 3719    0.011    0.000    0.019    0.000 layer2.py:31(item_object_hook)
  301    0.010    0.000    0.018    0.000 item.py:38(__init__)
22330    0.015    0.000    0.015    0.000 {method 'append' of 'list' objects}
  107    0.001    0.000    0.012    0.000 httplib.py:513(read)
  214    0.001    0.000    0.011    0.000 httplib.py:735(send)
  856    0.002    0.000    0.010    0.000 __init__.py:1034(debug)
  214    0.001    0.000    0.009    0.000 ssl.py:194(sendall)
  107    0.000    0.000    0.008    0.000 httplib.py:900(endheaders)
  107    0.001    0.000    0.008    0.000 httplib.py:772(_send_output)
  107    0.001    0.000    0.008    0.000 auth.py:223(string_to_sign)
  856    0.002    0.000    0.008    0.000 __init__.py:1244(isEnabledFor)
  137    0.001    0.000    0.008    0.000 httplib.py:603(_safe_read)
  214    0.001    0.000    0.007    0.000 ssl.py:166(send)
  214    0.007    0.000    0.007    0.000 {built-in method write}
 3311    0.006    0.000    0.006    0.000 item.py:186(__setitem__)
  107    0.001    0.000    0.006    0.000 auth.py:95(sign_string)
  137    0.001    0.000    0.006    0.000 socket.py:333(read)
4

1 に答える 1

13

これは完全な答えではありませんが、現時点で投稿する価値があると思いました。

ここ数週間、何人かの人々からこのような報告を聞いています。HTTPS が HTTP よりもかなり高速であるという異常を再現することはできましたが、追跡することはできませんでした。その問題は Python/boto に固有のもののように見えましたが、同じ問題が C#/.Net で見つかったことが判明し、根本的な問題がPython および .Net ライブラリでのNagle のアルゴリズムの使用であることが判明したことを調査しました。.Net では、これをオフにするのは簡単ですが、残念ながら Python ではそれほど簡単ではありません。

これをテストするために、ループで 1000 件の GetItem リクエストを実行する簡単なスクリプトを作成しました。フェッチされていたアイテムは非常に小さく、1K をはるかに下回っていました。us-east-1 リージョンの m1.medium インスタンスの Python 2.6.7 でこれを実行すると、次の結果が得られました。

>>> http_data = speed_test(False, 1000)
dynamoDB_speed_test - RUNTIME = 53.120193
Throttling exceptions: 0
>>> https_data = speed_test(True, 1000)
dynamoDB_speed_test - RUNTIME = 8.167652
Throttling exceptions: 0

サービスからのスロットリングを回避するのに十分なプロビジョニング容量がテーブルにあり、HTTP と HTTPS の間の予期しないギャップが明らかであることに注意してください。

次に、Python 2.7.2 で同じテストを実行しました。

>>> http_data = speed_test(False, 1000)
dynamoDB_speed_test - RUNTIME = 5.668544
Throttling exceptions: 0
>>> https_data = speed_test(True, 1000)
dynamoDB_speed_test - RUNTIME = 7.425210
Throttling exceptions: 0

したがって、2.7 ではこの問題が修正されたようです。次に、2.6.7 の httplib.py に簡単なパッチを適用しました。このパッチは、次のように、HTTPConnection オブジェクトに関連付けられたソケットの TCP_NO_DELAY プロパティを設定するだけです。

self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

次に、2.6.7 でテストを再実行しました。

>>> http_data = speed_test(False, 1000)
dynamoDB_speed_test - RUNTIME = 5.914109
Throttling exceptions: 0
>>> https_data = speed_test(True, 1000)
dynamoDB_speed_test - RUNTIME = 5.137570
Throttling exceptions: 0

HTTP よりも HTTPS を使用した方が予想されるよりも高速ですが、さらに優れています。その違いが重要かどうかを判断するのは困難です。

そのため、HTTPConnection オブジェクトのソケットをプログラムで構成して、TCP_NO_DELAY を正しく構成する方法を探しています。httplib.py でそれを実現するのは簡単ではありません。現時点での最善のアドバイスは、可能であれば Python 2.7 を使用することです。

于 2012-04-13T13:10:07.500 に答える