李伟山:金融撮合架构
李偉山
《架構寶典》聯合作者
讀完需要
10
分鐘速讀僅需 4 分鐘
李偉山,某司 CTO,曾負責電商平臺、活動營銷平臺的架構設計研發工作,開發設計了一款云同步社交平臺——號簿管家。曾參與設計開發億萬級流量的阿里虛擬業務平臺——話費充值、網游聯運平臺。在分布式系統架構設計、高并發系統設計、 系統穩定性保障等領域積累了豐富的實踐經驗,對基于 HTTP 協議的 SOA 架構有深入研究,在排查解決線上問題和故障方面有豐富的實踐經驗,擅于利用數據分析解決實際問題。對新技術有濃厚的興趣,并樂于分享。中生代技術、技術瑣話坐館老司機;
1
? ?
概述
隨著信息技術的日新月異和金融業務的快速發展,金融交易領域對于核心技術的需求也在不斷增強,國內外金融交易模式已經從傳統人工叫價的方式變成了由高度電子化交易系統撮合訂單的方式。傳統的金融交易主要發生在有型金融市場中,金融交易的買賣雙方通過叫價進行價格協商等方式最終達成一致,從而形成一筆交易,同時按照交易訂單到指定的交割地點進行實物交割。傳統的金融交易的整個過程主要依靠人來執行,其缺點主要有效率低、速度慢、交易時間限制大、交易空間限制大、交易成本非常髙、容易有內幕交易、交易擴展性差、交易容易出錯、資金安全性差等一系列缺點。
通過了解熟悉電子交易市場中訂單的下單流程、交易所的訂單處理機制及從訂單下達到交易所形成交易價格的過程,深入了解交易所撮合訂單的方式與機制,從而總結出交易撮合系統的需求,對系統進行分析建模并設計系統架構,根據真實市場機制采用多層分布式體系和內存撮合的數據存儲模式,構建出一個較為完善的交易撮合系統。
2
? ?
系統總體設計
2.1
? ?
系統核心模塊
交易撮合系統中包括以下幾個核心模塊。
交易層: 用戶最終可以通過終端進行撮合委托、委托查詢、出入金等操作。
接口層: 將用戶的商品查詢、下單等請求派發給業務層,并把交易詳情反饋給交易層。
業務層: 交易系統中的核心部分,用于接收訂單,根據業務邏輯實現訂單撮合,同時生成交易記錄,隨后給予用戶交易結果反饋。
數據層: 用來存儲商品信息、交易信息、資金信息、用戶信息,并實現數據持久化,
同時對交易詳情按行進行緩存,以減輕數據庫的壓力。此外,根據不同類型的金融交易產品將撮合模塊劃分為若干業務分區,每個分區獨立進行撮合,彼此不受影響。對于單個業務分區而言,撮合系統的整體架構設計如圖 15.1 所示。本章的總體設計圍繞業務層(撮合引擎層),以及撮合引擎與接口層(網關層)、數據層(數據庫)的交互方式進行。
2.2
? ?
撮合算法設計
如圖 15.2 所示,撮合引擎的核心業務模塊就是交易撮合算法,其可以對客戶訂單進行公平合理的排列和撮合,但是我們需要保證撮合算法的公平性、高效性及高擴展性等。由于不同金融交易系統的撮合業務各有不同,因此本節僅對通用的交易撮合算法進行概括性描述。
訂單隊列
交易撮合的重要組成部分就是買賣訂單,通過對買賣訂單進行撮合,最后形成交易記錄,所以對無法立刻完成撮合的訂單需要有買入隊列和賣出隊列來保存訂單。隊列按照“價格優先,同價格下時間優先”的原則排序。買入隊列按照委托價格由高到低的順序排列, 賣出隊列則按照委托價格由低到高的順序排列,如圖 15.3 所示。
交易委托有如下四種情況。
一. 新進的訂單是買入市價委托: 如果賣出隊列中有市價委托,則對它們進行撮合;如果將賣出隊列中的市價委托全部進行撮合后,該買入市價委托還有可交易數量,則將買入市價委托和賣出隊列中的限價委托進行撮合。如果賣出隊列中沒有市價委托,則直接將買入市價委托和賣出隊列中的限價委托進行撮合。如果賣出隊列為空, 則只將該買入市價委托插入買入隊列。
二. 新進的訂單是買入限價委托: 如果賣出隊列中有市價委托,則先對它們進行撮合; 如果市價委托全部撮合完畢后,該買入限價委托還存在可交易數量且價格大于等于賣出隊列中限價委托的最低價格,則繼續跟限價委托撮合。如果賣出隊列中只有限價委托且該買入委托的價格大于等于賣出隊列中的最低價格,則對它們進行撮合, 否則只能將該買入委托按照撮合原則插入買入隊列。如果賣出隊列為空,則直接將該買入限價委托按照撮合原則插入買入隊列。
三. 新進的訂單是賣出市價委托: 如果買入隊列中有市價委托,則先對它們進行撮合; 如果撮合后該賣出隊列還有未成交量,則和買入隊列中限價委托撮合。如果買入隊列中僅有限價委托,則和限價委托撮合。如果買入隊列為空,則將該賣出市價委托插入賣出隊列中。
四. 新進的訂單是賣出限價委托: 如果買入隊列中有市價委托,則先對它們進行撮合; 如果將市價委托全部撮合完畢后,該賣出限價委托還存在可交易數量且價格小于等于買入隊列中的最高價格,則繼續跟限價委托撮合。如果買入隊列中只有限價委托 且該賣出限價委托的價格小于等于買入隊列中的最高價格,則將其進行撮合,否則只能將該賣出限價委托按照撮合原則插入賣出隊列。如果買入隊列為空,則直接將該賣出限價委托按照撮合原則插入賣出隊列。
撮合順序
撮合引擎接收到新的買入訂單,則會到賣出隊列的頭部查找是否存在符合價格規則的賣出訂單,如果存在賣出價格小于或等于買入價格的訂單,則從隊列中取出此訂單并撮合成一筆交易;如果賣出隊列為空或隊列頭部不滿足價格關系,則將買入訂單插入買入隊列中,由于買入隊列是按照價格與時間進行排序的,所以新插入的訂單會經過一次排序再插入買入隊列。
相同地,當撮合引擎接收到新的賣出訂單時,會到買入隊列的頭部查找是否存在符合價格規則的買入訂單,如果存在買入價格大于或等于賣出價格的訂單,則從訂單隊列中取出此訂單并撮合成一筆交易; 如果買入隊列為空或隊列頭部不滿足價格關系,則將賣出訂單插入賣出隊列中,由于賣出隊列也是按照價格與時間進行排序的,所以新插入的訂單會經過一次排序再插入賣出隊列。結合買賣訂單情況,撮合算法的流程如圖 15.4 所示。從圖 15.4 所示的撮合順序可知,買賣隊列的有序性是保證撮合順序的基礎,并且撮合過程中的每筆訂單都可以撮合出當前最優交易。
2.3
? ?
基于內存撮合
當前的數據庫撮合技術性能低下的原因在于與數據庫交互過多,使得 I/O 操作很多,系統整體處理速度受數據庫事務邏輯約束。
這里釆用內存撮合技術,通過最大限度地去除與數據庫的交互(如圖 15.5 所示),將整個撮合邏輯放在內存中進行,因此比數據庫撮合技術少了許多 I/O 操作,在性能上可以大幅提升撮合速度; 內存撮合的弊端就是在由于內存的易失性而使服務器出現故障停機時,所有的交易數據將會丟失,系統的可靠性及一致性都會相應降低。因此,本章在提高內存撮合技術可靠性方面采用了多機熱備份及分布式一致性技術作為補充,從而獲得內存撮合技術的高性能及數據庫撮合技術的數據持久性。
2.4
? ?
災備的多機設計
由于內存撮合技術在撮合引擎出現異常時的可靠性和一致性非常差,而金融交易系統因為其業務特性對服務中斷及數據丟失的容忍度非常低,所以為了提高容錯性,一般多采用多機熱備份技術。采用多機熱備份技術將一組撮合引擎部署成互為備份的撮合引擎集群, 并在同一時間內只讓一臺撮合引擎提供服務,當這臺撮合引擎出現故障無法繼續正常工作時,撮合引擎集群便會迅速檢測到這個故障,并選舉出一個備份撮合引擎接管故障撮合引擎的任務,從而保證整個撮合系統正常運行。多機熱備份技術的本質就是針對服務器臨時故障所做的一種備份技術,本章采用多機熱備份技術來避免長時間的撮合服務中斷,保證撮合系統長期、可靠的服務。如圖 15.6 所示,通過用多臺撮合引擎做熱備份來保證在撮合引擎出現故障時,在可以接受的時間內完成主機和備份機之間的切換,由備份機提供無縫連續服務。
通過釆用多機熱備份技術,盡可能地避免了單一內存撮合引擎發生故障時導致的系統不可用問題,但仍舊無法提供 100%的可用性,因為當大規模服務器集群發生故障時仍舊存在服務不可用的可能性,但在實際生產環境中,3 臺互為備份的服務器可以提供較高的、用于生產環境的可靠性。
2.5
? ?
狀態機復制
由于內存撮合技術在撮合引擎出現異常時的可靠性和一致性非常差,而金融交易系統因為其業務特性對服務中斷及數據丟失的容忍度非常低,所以為了提高容錯性,一般多采用多機熱備份技術。采用多機熱備份技術將一組撮合引擎部署成互為備份的撮合引擎集群, 并在同一時間內只讓一臺撮合引擎提供服務,當這臺撮合引擎出現故障無法繼續正常工作時,撮合引擎集群便會迅速檢測到這個故障,并選舉出一個備份撮合引擎接管故障撮合引擎的任務,從而保證整個撮合系統正常運行。多機熱備份技術的本質就是針對服務器臨時故障所做的一種備份技術,本章采用多機熱備份技術來避免長時間的撮合服務中斷,保證撮合系統長期、可靠的服務。如圖 15.6 所示,通過用多臺撮合引擎做熱備份來保證在撮合引擎出現故障時,在可以接受的時間內完成主機和備份機之間的切換,由備份機提供無縫連續服務。
通過釆用多機熱備份技術,盡可能地避免了單一內存撮合引擎發生故障時導致的系統不可用問題,但仍舊無法提供 100%的可用性,因為當大規模服務器集群發生故障時仍舊存在服務不可用的可能性,但在實際生產環境中,3 臺互為備份的服務器可以提供較高的、 用于生產環境的可靠性。
2.6
? ?
狀態機復制
由于多機熱備份技術引入了多臺互為熱備份的撮合引擎,因此根據撮合系統設計及撮合邏輯要求,需要保證服務器之間的數據一致,這就需要保證多服務器之間的一致性,這也是該系統的難點之一。
在設計中使用一種內存狀態機復制方案,即將撮合算法視作一個確定性狀態機,將其復制多份并部署到撮合系統的多臺撮合引擎中。每個撮合引擎副本從相同的初始狀態開始運行,當撮合系統收到網關發來的訂單時,系統中的每個撮合引擎都會撮合這個訂單,并依次產生交易記錄,同時更新確定性撮合算法狀態機的獨立狀態。通過這樣的方式,可以使每個撮合引擎副本在撮合系統正常運轉時具有相同的結果狀態,而在撮合系統出現故障或異常時,撮合引擎就會出現狀態不一致的情況,換句話說,一旦撮合系統的結果或狀態出現了不一致的情況就可以斷定系統出現了異常。
一. 關鍵技術點系統為了實現基于內存狀態機復制的撮合系統,總結出撮合系統中的幾個關鍵技術點:
將確定性撮合算法狀態機服務部署到多臺獨立撮合引擎中。
接收網關訂單,并將其作為確定性撮合算法狀態機的輸入。
根據撮合算法的需求,選擇一種訂單排序方式。
每臺撮合引擎對按照排序方式排序過的訂單進行撮合。
將確定性撮合算法狀態機輸出的交易記錄作為給用戶或數據庫的響應。
監控撮合引擎副本的狀態或輸出的差別。
二. 具體實現為了實現基于內存狀態機復制的撮合系統,系統主要通過以下方案實現狀態機復制的關鍵技術點:
采用原子多播解決撮合引擎訂單的可靠多播與全局有序性。
采用基于無鎖訂單隊列的流水線撮合技術提供快速的訂單撮合。
采用異步一致性持久化技術實現與數據庫的交互。
采用失效備援技術對撮合引擎集群進行狀態監控并保證系統的容錯能力。
采用進度追趕技術解決撮合引擎的故障以及添加新的撮合引擎。
三. 數據庫優化撮合系統中對數據庫的查詢操作是很重要的一環,查詢的性能對是否能夠擁有高效的撮合效率有很大影響。為此,對數據庫進行查詢優化必不可少。每個查詢都會有許多可供選擇的執行策略和操作算法,查詢優化就是選擇一個高效執行的查詢處理策略。查詢的執行開銷主要包括 I/O 開銷(磁盤存取塊數)、CPU 開銷(處理機時間)、內存開銷,其中 I/O 開銷是最主要的。為此,可以充分利用索引的方法來減少表掃描的 I/O 開銷,盡量避免表搜索的發生,例如可以在訂單表中對 orderID 或 itemID 建立索引以提高查詢效率。利用好索引可以極大地提高數據庫的檢索性能,但是不能基于經常修改的列建立索引,因為這樣只會增加系統搜索的開銷。而且由于撮合系統每秒鐘都需要處理大量的數據,因此為了提高系統效率,可以盡量建立單索引提高查詢效率。(未完待續)
本文節選自中生代技術社區叢書之《架構寶典》
往期推薦
美團技術:百億規模API網關服務Shepherd的設計與實現
阿里巴巴為什么能抗住90秒100億?看完這篇你就明白了!
八戒科技服務技術負責人鴻鵠真人:做好技術負責人的4個關鍵特質
彭榮新:喜馬拉雅自研網關架構演進過程
Google和Facebook為什么不用Docker?
追根溯源 - 數據中臺概念的起源
總結
以上是生活随笔為你收集整理的李伟山:金融撮合架构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: poj-3641 Pseudoprime
- 下一篇: poj-1845 Sumdiv nyo