我已經編寫了一個程序,用作samba共享的簡單HTTP接口:用戶向http://proxy.example.com/?path=\\repository\foo\bar.txt
發送獲取請求,\\repository\foo\bar.txt
通過http.ServeFile(或多或少)。在服務中使用samba文件的悖論性能
然而,表現是糟糕的。我跑了一些基準,結果讓我難堪。對於上下文來說,圖中有三臺機器:samba服務器(文件所在的位置),代理服務器(go程序運行的地方)和最終用戶的機器(我最終希望文件得到的機器)。 Samba服務器和代理服務器位於同一地點,最終用戶相當遙遠。
從samba機器到使用windows拷貝的用戶機器的直接拷貝以〜1.5MB/s運行。這對我來說已經夠好了,而且我在代理服務中的目標是什麼。
不幸的是,來自用戶機器的curl 'http://proxy.example.com/?path=\\repository\foo\bar.txt' > bar.txt
時鐘約爲150KB/s。
因此,讓我們看看samba服務器和代理服務器之間是否存在連接問題。從samba服務器到代理服務器的副本看起來像是......約15MB/s。
嗯,也許這是一件事?我會寫一個去程序來衡量傳輸速度。
src, _ := os.Open("\\\\repository\\foo\\bar.txt")
start := time.Now()
written, _ := io.Copy(ioutil.Discard, src)
elapsed := time.Since(start)
bytesPerSecond := written/int64(elapsed/time.Second)
當,15MB/s。
好吧,好吧,也許有什麼其他在去代碼導致的問題。遠程啓動代理服務器,啓動IE,轉至http://proxy.example.com/?path=\\repository\foo\bar.txt
,15MB/s。
好的,所以我的代碼顯然工作得很好,它必須是代理服務器和最終用戶之間的連接。我會將bar.txt
複製到代理服務器,並在url中使用其本地路徑\mycoolfiles\bar.txt
。呵呵,1.5MB /秒。
爲了讓事情變得更加奇怪,我恰好有C:\mycoolfiles
設置爲網絡共享名爲\\alexscoolfiles
和http://proxy.example.com/?path=\\alexscoolfiles\bar.txt
時鐘,在敦敦頓,150KB/s。
只是爲了確認這種瘋狂,我改變了圍棋程序分兩步執行:
- 複製從共享文件到本地硬盤驅動器
- http.SendFile從那裏
瞧,在文件以15MB/s傳輸時暫停一小段時間後,下載以固定的1.5MB /秒開始。
因此,share-> proxy是15MB/s,proxy-> user是1.5MB/s,但share-> proxy-> user是... 150KB/s?比應該慢十倍?除非你和代理在同一臺機器上,那麼它的速度應該和它應該一樣快呢?而且還存在這個問題,即使它只是一個UNC路徑而另一個只是一個本地路徑而被訪問完全相同的文件?
什麼?
請幫忙,我只是不知道。
編輯:所以我的直覺是(正如評論),它與TCP有關。有問題的代碼已被隔離到幾乎只是io.Copy。
- 我知道,當讀者是samba文件,作者是ioutil.Discard時,我可以獲得最大的吞吐量。
- 我知道,當閱讀器是本地文件並且writer是http.Response時,無論使用響應的客戶端的帶寬和RRT如何,我都可以獲得最大吞吐量。
- 我知道,當閱讀器是一個samba文件,作家是一個http.Response,並且連接是本地的,我獲得了最大的吞吐量。
- 我知道,當讀者是samba文件時,作者是一個http.Response,並且連接不是本地的,我得到了可怕的(〜1/10)吞吐量。
翻看io.Copy,似乎唯一可能導致問題的是讀取samba文件和寫入響應的時間之間的相互作用;一個足夠快的編寫器使得讀取一個samba文件達到最大吞吐量,一個足夠快的讀取器使得http.Response.Write達到最大吞吐量,但是將它們結合使得一切都很糟糕。
什麼是非常有用的是......實際發生了什麼,更重要的是,我怎樣才能讓這個問題消失。
延遲*帶寬產品 – 2015-03-31 00:22:33
該文件的聲音太小,因此您正在測量開銷而不是實際的傳輸速度。 – 2015-03-31 00:46:29
@Harry我一直在測試的文件是50MB,所以我不認爲這是問題所在。 – 2015-03-31 04:15:11