2012-04-12 8 views
10

Boto aracılığıyla dynamodb test ediyorum ve şaşırtıcı bir şekilde, hashkey, rangekey koşul sorgularına dayanan veri kümelerinin alınmasında yavaş olduğunu buldum. Ssl (is_secure) 'ın 6s daha hızlı, daha sonra non-ssl yapmasına neden olan gariplik hakkında bazı tartışmalar gördüm ve bu bulguyu doğrulayabiliyorum. Ama ssl kullanarak bile, oldukça küçük bir veri kümesinde bir hashkey/range anahtar koşulu kullanarak 300 kayıt almak için 1-2 saniye görüyorum (daha az 1K kayıtları).Python Boto Dynamodb, aralık anahtarları üzerindeki küçük kayıt kümesi alma işlemi için çok yavaş performans

Profilehooksların çalıştırılması ssl.py'de 300 kayıt elde etmek için 20617 ncalls sırasına kadar çok fazla zaman harcadım. Kayıt başına 10 aramada bile 6x daha fazla bekler gibi görünüyor. Bu bir orta örnekte-- aynı sonuçlar bir mikro örnekte ortaya çıkıyor. 500 Okur/sn 1000 yazıyor/sn önyükleme yapılmıyor.

Bir toplu iş isteğine baktım ama aralık anahtar koşullarını kullanamaması benim için bu seçeneği ortadan kaldırıyor.

Zaman kaybediyorum nerede herhangi bir fikir büyük takdir! göre sıralanır

144244 function calls in 2.083 CPU seconds 

: kümülatif zaman, iç zaman, bu tam bir cevap değil ama şu anda göndermeden değer diye düşündüm

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) 
+2

Veriler için teşekkürler. Son zamanlarda aradığım bir şey bu. HTTP ve HTTPS arasındaki delta en azını söylemek için şaşırtıcıdır. Bu bir EC2 örneğinden mi? Tablo için temel verim nedir? – garnaat

+1

Birzon EC2-ortamı örneğinde 500 okuma/sn ve 1000 yazma/s olarak sağlanmıştır. Sonuçlarda önemli bir değişiklik olmaksızın artan ve azalan iş hacmini ve farklı büyüklükteki örnekleri denedim. Azaltılmış iade özniteliklerinin (10'dan 2'ye kadar) küçük bir etkisi vardır. – jaredmsaul

+1

Bu bilginin orijinal yazılarınızda olduğunu görüyorum. Afedersiniz. Herhangi bir kısıtlama olayı görmüyorsanız (ve bu provizyon seviyesinde olmamalısınız), o zaman sorun müşteri tarafındadır. Daha fazla istekte bulunmayı denediniz mi (ör., 10 bin veya daha fazla). Bu, önbellekleri ısıtacak ve potansiyel iş hacminin daha iyi temsil edilmesini sağlayacaktır. Ancak, httplib'de tuhaf bir şeyin devam ettiği açıktır. Onu takip edip edemeyeceğimi araştırıyorum. – garnaat

cevap

12

saymak diyoruz.

Son birkaç hafta içinde birkaç kişinin bu gibi raporlarını duydum. HTTPS'nin anormalliğini HTTP'den çok daha hızlı bir şekilde yeniden üretmeyi başardım, ancak bunu takip edemedim. Bu problem Python/boto'ya özgüymiş gibi görünüyordu, fakat aynı sorun C#/.Net'de bulundu ve altta yatan sorunun Python ve .Net kitaplıklarında Nagle's algorithm'un kullanılması olduğu araştırılıyordu. .Net'de bunu kapatmak kolay ama maalesef Python'da bu kadar kolay değil.

Bunu test etmek için, döngü içinde 1000 GetItem isteği gerçekleştiren basit bir komut dosyası yazdım. Getirilen öğe, 1K'nın altında çok küçüktü. bu sonuçlar bize doğu-1 bölgede bir m1.medium örneğinde Python 2.6.7 bu üretilen Running: hizmetinden herhangi azaltmayı önlemek için tablodaki yeterli hazırlığı kapasitesi olmadığını

>>> 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 

Not ve HTTP ve HTTPS arasındaki beklenmedik boşluk açıktır.

sonraki Python 2.7.2 aynı testi yaptı:

>>> 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 

Yani, 2.7 bu sorunu sabit gibi görünüyor. Daha sonra 2.6.7'deki httplib.py dosyasına basit bir yama uyguladı. Sonra testi yeniden ran

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

2.6.7 üzerinde: yama basitçe böyle httpconnection nesneyle ilgili soketin TCP_NO_DELAY özelliğini, ayarlar da iyisi

>>> 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 

hala rağmen HTTPS ile beklenenden daha hızlı bir şekilde HTTP'den daha hızlı. Bu farkın anlamlı olup olmadığını bilmek zor.

Yani, TCP_NO_DELAY doğru yapılandırılmış olması için HTTPConnection nesnelerinin soketini program aracılığıyla yapılandırmanın yollarını arıyorum. Buna httplib.py'de ulaşmak kolay değil.Şu an için en iyi tavsiyem, mümkünse Python 2.7'yi kullanmaktır.

+0

+1 ayrıntılı analiz için ve zaten gönderme, gerçekten şaşırtıcı bir bulmaca - teşekkürler! –