2012-04-12 26 views
10

Tôi đang thử nghiệm dynamodb thông qua boto và đã tìm thấy nó chậm đáng ngạc nhiên trong việc lấy các tập dữ liệu dựa trên các truy vấn điều kiện phạm vi. Tôi đã thấy một số cuộc thảo luận về sự kỳ quặc gây ra ssl (is_secure) để thực hiện khoảng 6x nhanh hơn sau đó không ssl và tôi có thể xác nhận rằng việc tìm kiếm. Nhưng ngay cả khi sử dụng ssl tôi thấy 1-2 giây để lấy 300 bản ghi bằng cách sử dụng điều kiện khóa băm/phạm vi trên một tập dữ liệu khá nhỏ (ít hơn 1K bản ghi).Python Boto Dynamodb hiệu suất rất chậm cho thu nhỏ thiết lập kỷ lục trên các phím phạm vi

Chạy hồ sơ sơ yếu lý lịch Tôi thấy rất nhiều thời gian không liên quan được sử dụng trong ssl.py với thứ tự 20617 ncalls để truy xuất 300 bản ghi. Có vẻ như ngay cả ở 10 cuộc gọi cho mỗi bản ghi nó vẫn còn 6x hơn sau đó tôi mong đợi. Đây là trên một ví dụ trung bình-- mặc dù kết quả tương tự xảy ra trên một trường hợp vi mô. 500 Reads/sec 1000 viết/giây cung cấp không có throttles đăng nhập.

Tôi đã xem xét thực hiện yêu cầu hàng loạt nhưng không thể sử dụng các điều kiện chính của phạm vi loại bỏ tùy chọn đó cho tôi.

Bất kỳ ý tưởng nào về nơi tôi mất thời gian sẽ được đánh giá cao !!

144244 function calls in 2.083 CPU seconds 

Ordered bởi: thời gian tích lũy, thời gian nội bộ, gọi đế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

Cảm ơn dữ liệu. Đây là điều tôi đã xem xét gần đây. Vùng đồng bằng giữa HTTP và HTTPS khó hiểu, ít nhất là nói. Đây có phải là từ phiên bản EC2 không? Thông lượng được cung cấp cho bảng là gì? – garnaat

+1

Được cấp phép với 500 lần đọc/s và 1000 ghi/s trên một phiên bản trung bình EC2 amazon. Tôi đã thử tăng và giảm thông lượng và cũng có các trường hợp có kích thước khác nhau mà không có thay đổi đáng kể trong kết quả. Việc giảm các thuộc tính trả về (từ 10 đến 2) có tác dụng nhỏ. – jaredmsaul

+1

Tôi thấy thông tin đó là tất cả trong bài đăng gốc của bạn. Lấy làm tiếc. Nếu bạn không nhìn thấy bất kỳ sự kiện điều chỉnh nào (và bạn không nên ở cấp độ cung cấp đó) thì vấn đề là tất cả ở phía khách hàng. Bạn đã thử thực hiện thêm nhiều yêu cầu chưa (ví dụ: 10k hoặc hơn). Điều này sẽ làm ấm bộ đệm và sẽ cung cấp cho một đại diện tốt hơn về thông lượng tiềm năng. Tuy nhiên, rõ ràng là có điều gì đó kỳ lạ đang diễn ra trong httplib. Tôi đang điều tra xem tôi có thể theo dõi nó không. – garnaat

Trả lời

12

Đây không phải là một câu trả lời hoàn chỉnh nhưng tôi nghĩ rằng nó là giá trị đăng nó vào lúc này.

Tôi đã nghe các báo cáo như thế này từ một vài người trong vài tuần qua. Tôi đã có thể tái tạo sự bất thường của HTTPS nhanh hơn đáng kể so với HTTP nhưng không thể theo dõi nó. Có vẻ như vấn đề đó là duy nhất đối với Python/boto nhưng nó chỉ ra cùng một vấn đề đã được tìm thấy trên C# /. Net và điều tra rằng nó đã được tìm thấy rằng vấn đề cơ bản là sử dụng Nagle's algorithm trong thư viện Python và .Net. Trong. Net, thật dễ dàng để tắt tính năng này nhưng thật không dễ dàng bằng Python.

Để kiểm tra điều này, tôi đã viết một kịch bản đơn giản đã thực hiện 1000 yêu cầu GetItem trong một vòng lặp. Vật phẩm đang được lấy rất nhỏ, dưới 1K. Chạy trên Python 2.6.7 trên một thể hiện m1.medium trong khu vực chúng tôi đông-1 được sản xuất các kết quả này:

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

Lưu ý rằng có khả năng được cung cấp đầy đủ trong bảng để tránh bất kỳ sự điều tiết từ các dịch vụ và khoảng cách bất ngờ giữa HTTP và HTTPS là rõ ràng.

tôi tới chạy thử nghiệm tương tự bằng 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 

Vì vậy, 2.7 dường như đã cố định vấn đề này. Sau đó tôi áp dụng một bản vá đơn giản cho httplib.py trong 2.6.7. Các miếng vá đơn giản là đặt thuộc tính TCP_NO_DELAY của ổ cắm gắn liền với đối tượng HttpConnection, như thế này:

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

Sau đó tôi lại chạy thử nghiệm trên 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 

Thậm chí tốt hơn mặc dù vẫn còn một thời gian dự kiến ​​nhanh hơn với HTTPS hơn HTTP. Thật khó để biết liệu sự khác biệt đó có đáng kể hay không.

Vì vậy, tôi đang tìm cách để lập trình cấu hình ổ cắm cho các đối tượng HTTPConnection để có cấu hình TCP_NO_DELAY đúng cách. Nó không phải dễ dàng để có được ở đó trong httplib.py.Lời khuyên tốt nhất của tôi cho thời điểm này là sử dụng Python 2.7, nếu có thể.

+0

+1 để phân tích chi tiết và đăng nó đã, một câu đố khó hiểu thực sự - cảm ơn nhiều! –

Các vấn đề liên quan