2014-10-30 34 views
0

我創造出的地圖存儲數據的CherryPy的網絡服務中獲取數據,從客戶端接收鍵和返回相應的數據:使多個請求從CherryPy的網絡服務

import sys 
import imp 
import cherrypy 

data_source = get_data() # get data from the database and store it in the map 

class Provider: 
    exposed = True 

    def POST(self, key): 
     global data_source 
     data = data_source[key] # get stored data based on given key 
     return data 

if __name__ == '__main__': 
    cherrypy.tree.mount(Provider(), '/Provider',{'/': 
      {'request.dispatch': cherrypy.dispatch.MethodDispatcher()} 
     }) 
    cherrypy.config.update({'server.socket_host': '0.0.0.0', 
      'server.socket_port': 8080, 
     }) 
    cherrypy.server.max_request_body_size = 1048576000 
    cherrypy.engine.start() 
    cherrypy.engine.block() 

然後,另一臺機器上,我創建了一個腳本來向提供者請求數據。使用腳本,就可以scpecify,我想多少併發請求作出:

import requests 
import time 
from threading import Thread 

def make_request(id, key): 
    start = time.time() 
    r = requests.post("http://provider-host/Provider", {'key':key}) 
    end = time.time() 
    print 'Thread {0} takes {1} seconds to finish with status code {2}'.format(id, end - start, r.status_code) 

def start(num, key): 
    ts = [] 
    for i in range(num): 
     t = Thread(target=make_request, args=(i, key)) 
     ts.append(t) 
    for t in ts: t.start() 
    for t in ts: t.join() 

最後,我做一個測試,要求相同的鍵10次,有2種不同的方法:順序和併發。

序貫方法:

time for i in range(10): start(1, 'big_data_key') 

結果是:

Thread 0 takes 2.51558494568 seconds to finish with status code 200 
Thread 0 takes 2.47761011124 seconds to finish with status code 200 
Thread 0 takes 2.66229009628 seconds to finish with status code 200 
Thread 0 takes 2.47381901741 seconds to finish with status code 200 
Thread 0 takes 2.4907720089 seconds to finish with status code 200 
Thread 0 takes 2.93357181549 seconds to finish with status code 200 
Thread 0 takes 2.47671484947 seconds to finish with status code 200 
Thread 0 takes 2.40888786316 seconds to finish with status code 200 
Thread 0 takes 2.6319899559 seconds to finish with status code 200 
Thread 0 takes 2.77075099945 seconds to finish with status code 200 
CPU times: user 1.79 s, sys: 1.06 s, total: 2.85 s 
Wall time: 25.9 s 

併發方法:

time start('138.251.195.251', 10, 'big_data_key') 

結果是:

Thread 5 takes 15.5736939907 seconds to finish with status code 200 
Thread 1 takes 19.4057281017 seconds to finish with status code 200 
Thread 7 takes 21.4743158817 seconds to finish with status code 200 
Thread 8 takes 22.4408829212 seconds to finish with status code 200 
Thread 0 takes 24.1915988922 seconds to finish with status code 200 
Thread 2 takes 24.3175201416 seconds to finish with status code 200 
Thread 6 takes 24.3368370533 seconds to finish with status code 200 
Thread 4 takes 24.3618791103 seconds to finish with status code 200 
Thread 9 takes 24.3891952038 seconds to finish with status code 200 
Thread 3 takes 24.5536601543 seconds to finish with status code 200 
CPU times: user 2.34 s, sys: 1.67 s, total: 4.01 s 
Wall time: 24.6 s 

很明顯,使用併發方法,完成一個請求所需的時間比順序方法中的要高。

所以,我的問題是:是由兩臺機器之間的帶寬造成的下載時間的差異,還是由其他原因造成的,例如, cherrypy有關?如果是由其他原因引起的,我將不勝感激任何處理它的建議。

+0

告訴我們關於「big_data_key」和「huge_text.txt」的大小。關於機器之間網絡連接的平均帶寬(例如''wget''某個大文件)。然後,您可以對串行和並行情況進行預計時間的數學計算。 – saaj 2014-10-30 15:34:29

+0

嗨,我已經解決了我的問題,以便只使用一個密鑰。數據大小爲22mb,帶寬爲10.8 mb/sec。 – 2014-10-30 15:47:24

回答

1

那麼很明顯你的瓶頸就是網絡。以10.8MiB/s傳輸220MiB應該至少需要20秒。您的實驗需要約25秒,即8.8MiB/s,即在100MBit/s的最大理論容量中有效〜74Mbit/s。考慮到所有可能的測量誤差,這是一個好結果。

串行和並行情況(〜5%)之間的差異表明多路複用無助於解決,因爲瓶頸是網絡帶寬,而不是單個連接限制。

爲了測量CherryPy的影響,你可以設置一個用本地代碼編寫的網頁服務器,我建議nginx,把文件放在那裏,然後嘗試下載10次。對於平行測試,您可以嘗試Apache ab,如ab -n 10 -c 10 http://provider-host/some-big-file

兼論CherryPy的幾個注意事項:

  • CherryPy的是線程服務器,默認的線程池,server.thread_pool,有職工10人,
  • 嘗試激活gzip壓縮,'/' : {'tools.gzip.on': True},在你的配置,這將顯着提升純文本數據。

你也可以看看this question,關於用CherryPy處理大文件下載。