高頻交易系統怎樣在多線程和連接埠通訊之間取捨?

來源:互聯網
上載者:User
如題,比如在tick data處理和後續交易訊號分析之間交換資料,採用多線程系統的延遲小,但不利於代碼功能區分;多個程式之間連接埠通訊的方法則代碼比較清晰,但顯然會增加延遲。如何取捨?

回複內容:

如果通訊方式一樣,比如都用共用記憶體,那麼多線程和多進程間的主要區別就只有程式崩潰時的隔離特性,多線程一崩潰就全完蛋,多進程只會影響一部分。

如果還考慮軟體工程意義,不同進程通常意味著不同的程式,甚至不同的項目,操作風險會降低,這是很多交易系統做兩個進程而不是一個進程的重要原因,風控進程和策略進程軟體工程意義上隔離,改策略不會增加亂報單的可能性。

這兩點考慮到了之後,進程數越少越好。不同邏輯流(線程)間的同步越少越好。低計算量下,最低延遲通常是單線程邏輯得到的。

做低延遲都需要考慮I/O blocking到被喚醒執行所耗費的時間,用Socket等需要syscall和context switch的當然更應該能避免則避免了。

當然這一切都是基於高頻交易,更準確的說是低延遲交易領域。不是所有電子交易系統都處於這一領域,其他領域的架構根據不同的需求可能完全不同。首先我同意軟體解藕的方法很多,按進程拆分不過是其中一種,但不必然是最好的一種。事實上要提高開發效率和降低維護難度,是一項需要根據團隊成員的技術特點不斷摸索的藝術,不必預先把自己的思維模式限制死了,嘗試一下其他方法(比如 OO ,Functional )也許有更好的效果。

根據我(多年打雜)的經驗來看,交易系統也是特別符合《人月神話》中推薦的外科手術團隊的開發模式。開發這種高精密系統人多了其實有負面作用,最好的辦法是以一兩個高水平程式員為主力設計和開發,再加幾個雜兵跑堂就可以了。所以解決這個問題有一個四海一家的終極大法:讓老闆漲工資高薪聘請一流的技術專家。當你有一個一流高手坐鎮主攻的時候,解藕就從多人協作變成一項個人品味的問題了,只要根據主攻手的口味選擇方案就好。

當然我明白人在江湖,身不由己。以上建議對於已經有很多曆史遺留或者起了一半的項目來說顯然是遠水解不了近渴。所以下面嘗試給點實際的建議。

首先處理序間通訊(IPC )有很多種方法,連接埠通訊(Socket)絕對不是最快的那種。Named pipe 和共用記憶體都可以做的更好,事實上最快的辦法是共用記憶體+獨佔 CPU core,可以參考 Java-Chronicle 的實現。這種方法做到幾十鈉秒的通訊延遲是沒問題的,見:fastest (low latency) method for Inter Process Communication between Java and C/C++

關於連接埠通訊為什麼慢,只要看這篇文章就可以理解:Know your TCP system call sequences ,見:
即便你用的是本地介面(localhost),一樣要經過系統調用(system call)切換進 kernel space,中間經過無數記憶體拷貝,協議檢查之類浪費時間的事情。這些問題在共用記憶體方案下都不存在。所以一個簡單的做法是重寫你們的通訊模組,採用這些更快的通訊方法。即便你用的是本地介面(localhost),一樣要經過系統調用(system call)切換進 kernel space,中間經過無數記憶體拷貝,協議檢查之類浪費時間的事情。這些問題在共用記憶體方案下都不存在。所以一個簡單的做法是重寫你們的通訊模組,採用這些更快的通訊方法。

如果你的攤子實在太爛以至於修改通訊代碼也是不能承受之重,那麼還有一手秘籍叫做替換系統調用。簡言之就是用修改函數指標的方式把系統調用入口換成自己的程式,比如用共用記憶體來實現連接埠通訊的 API。這樣你可以在不改動現有程式的基礎上改變通訊方式來提高通訊速度。具體怎麼做可以參考流行的開源實現 OpenOnload ,雖然它主要是替換 TCP/IP 協議棧,但思路是一樣的。

其實這個時候是最能體現 Java 等基於虛擬機器位元組碼的語言的優勢的。如果你用 Java,那麼替換系統調用就很容易,對 JVM 上 instrumentation 即可,嫌麻煩可以直接用 JMockit 之類的庫,用法很簡單(請允許我對於深陷 C++ 囹圄中苦苦掙紮的同學們表示一下同情)。回頭看了下自己的答案,過於關注在模組化這個編程視角了,沒有跟行業需求結合,覺得有些簡單粗暴了,修改一下。
@董可人@盧旺彬回答都很詳細,分別提到了遺留系統的處理方法和分析多線程和通訊層面的優劣比較,非常有借鑒意義。

補充一下,由於題主對高頻系統的具體資訊甚少,也不清楚是否只需要接一個證券交易所,因此大多數人只能按低延遲系統來回答,我這邊稍微發散一下,引出幾個相關的資訊,供大家深入討論。

首先, 系統各業務功能的模組化與主程式採用什麼樣的部署運行狀態(多線程或多進程)是不矛盾的,在各部分系統用同一種程式設計語言的前提下,兩者可以輕鬆地同時得到。這也是大家在答案中都提到過的解耦,但如果是多語言開發的系統,彼此之間還是需要資料通訊,或者是多個策略需要共用一個前端資料來源,比如證券交易所只允許接一個串連,多個策略系統要用,可能沒辦法部署在一台機器上,這樣的情況下網路通訊都不可避免,可以升級通過內部網路和機器硬體來處理,換句話說,得具體問題具體分析和最佳化。

其次,要分析下程式造成延遲的主要原因,或者從需求來講需要低延遲的主要因素在哪兒,需要具體分析下,任何需求的滿足都是要付出代價的,尤其是一些非功能性的需求,有時會導致整個系統成本急劇地上升。在高頻交易中,具體高頻到什麼程度,是否網路間的資料轉送延遲是最大的瓶頸?是在內網還是外網,如果是外網,託管機器就可消除網路傳輸的延遲,如果是內網,改善網路裝置和機器也是可行方案,這些相關的環節都是需要分析的問題,曾經我們的一個客戶,在這個方面糾結了很久,但後來發現,如果演算法上做出些改進,系統一下子減少了上百個ms的延遲,所以抓住主要矛盾才是解決問題的關鍵。

再次,迴歸到題主的具體問題,假定只集中在這個問題上, tick data已經有了,分析tick data的模組和tick data採集之間如何交換資料,實際上高頻交易資料部分的傳輸是單向的,tick data的資料擷取是生產者,分析部分是消費者,很簡單的計算模型,用共用記憶體的方式即可解決,因為證券交易所資料是不斷推過來的,資料分析部分必須在下一條資料到來之前完成處理,否則看緩衝區的處理方式可能會有堆積或資料丟失,建議採用類似於作業系統對硬體中斷的兩步處理模式,把分析任務細分解一下,什麼時候資料足夠了啟動分析,和讀取資料之間做個平衡處理,在資料分析方面儘可能地改進演算法,減少它的延遲才是關鍵,如果它的計算時間少於tick data資料的間隔,很多複雜的最佳化工作就可以省了。

最後,一點建議,跟我們最近的一個R語言的策略開發SDK執行個體相關,R語言層面寫的策略只能是單線程的,而後端需要支援多個證券交易所的行情資料擷取源、交易通道介面,必須是多線程,前後之間通過用C++開發R語言擴充包來銜接,中間就是採用的共用記憶體資料來通訊的,供借鑒參考。

-------以下是原回答 ------------

作為程式員,很不明白樓主的問題,多線程怎麼就不能做到代碼功能的區分了呢? 模組化跟是否用多線程,還是部署成多個程式,用網路通訊沒有關係的,主要在於程式員對業務的理解程度,以及能否把這個需求用編程技術優雅地實現出來的功力。
只有一個程式,哪怕原始碼只有一個檔案,也可以做到很好的模組化。 一點經驗分享:
1. 交易系統或是高頻交易系統必然是多線程的,原因略去,有時間我再修改加上去。
2. 直接分享我寫高頻程式的經驗(在不影響我策略的基礎上盡量分享),僅供參考。

以下所有層都是單獨運作,互相之間沒有Dependencies,資料區共用。


A : 單向資料取得層,(深度,成交量等..來源:網路,延時時間:不確定),基本是每個資料項目開一個“無限” 迴圈去取資料放入公用資料區(記憶體資料,如果資料量巨大,可以考慮基於記憶體的資料庫。)

B: 資料加工層: 資料來源,記憶體(A),延時,基本無延時,資料輸出-->>依然是公用資料區,記憶體。

C: 主邏輯層:資料來源,記憶體(B 加工後的資料,avg..spread..top value..之類的),根據你的策略作出買賣之類的動作(開啟線程D,), 主邏輯層依然做自己的事。

D1: 訂單跟蹤層: 資料來源,網路,跟蹤訂單狀態及其後續要採取的動作。。
D2:............
D3...........
D4...........
P.S..如果樓主指的是本地到網路的連接埠,而不是線程之間的連接埠。那一個普通PC就有好幾萬。如果還是不夠。我們再討論。1.怎麼感覺在【高頻交易】這個話題下的問題的技術水平如此低下?錯覺嗎?

2.既然主要需求是極端高的效能,以及極端低的延遲,那麼整個系統的設計原則肯定是:怎麼高效能怎麼來,怎麼簡單怎麼來。所以:

3.代碼功能區分(其實是模組化,低耦合,低寫入程式碼)、多個程式之間連接埠通訊的方法(難道是連接埠複用?或者是基於TCP/UDP的處理序間通訊?)等這些顯然會增加延遲的技術,那就肯定不用。

甚至...甚至...甚至....嗯嗯......

4444444.有條件的最好用FPGA、DSP來代替低效能的普通PC機、工作站或伺服器,有研發技術實力的研究所或公司甚至可以用HyperIFR51(基於光信量子技術的51單片機)來進行超速計算。有條件的單位可以使用微波通訊來代替普通光纖網路,有海量資金的高端企業甚至可以通過核心人脈去租用電信最新最保密的軍用級P3OEMod25k(基於核子共振技術的25k極速撥號電話網路)來進行超速通訊。噗....

題主應該是The Art of Unix Programming這類書看到溝裡去了吧,言必稱進程,視線程和物件導向為毒物。

1. 不要過度追求“distribution architecture”
2. 堅定不要過度追求
3. 打散你的code,分不同的module
3.1 可以學習C是怎麼做的,哪怕是non-OO語言,也是可以打散的
4. 乾貨時間, martin fowler的microservices: Microservices
4.1 理解透了,你也知道哪些應該“單獨”進程,哪些放在一個進程裡multi thread處理即可

PS: 我很不喜歡下面的一些答案,不管咋就噴,從我的經驗來看我覺得這個問題挺好的:
market data 和 策略order之間的協調是永遠的痛點之一。> 多線程系統的延遲小,但不利於代碼功能區分
為嘛不利於代碼功能區分?

> 多個程式之間連接埠通訊的方法則代碼比較清晰,但顯然會增加延遲
增加多大的延遲?是不可接受的嗎?莫非你的系統需要到微妙以內?

你的目的是解決問題,而不是提出一些不存在的問題。我們自己開發的系統基本上還是用socket為主,確實考慮到開發成本的問題。如果資料量大的時候,偶發有線程互斥等其他問題。這也是沒辦法的事情,一來覺得證券交易所的資料給的就慢。你本地提高几十毫秒未見得對整體系統有多大提升,換其他的方式還需要各種測試。綜合來看,socket易用,也便宜。有些問題可以靠演算法來最佳化,只要穩定,國內基本都ok,國內的資料慢,也不用想太多。All process should be single thread.
You should use cup isolation to pin a process to a core.
They communicate thru shared memory if they are execution related processes, otherwise should be multicast, like risk related processes.
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.