背景
場景:
- 交易撮合系統
挑戰:
- 有時間優先限制, 單隻股票隻能串行操作, 容易導緻交易擁堵的瓶頸.
- 一筆交易涉及多份, 例如200股, 存在部分交易, 部分撤單的需求.
- 買賣雙方的數量可能不比對, 一筆撮合交易可能涉及多方.
- 隐蔽問題: 價格挂太高或太低, 無法撮合時, 會導緻資源浪費. 類似vacuum, 有長事務, 導緻垃圾不能回收, 但是依舊要觸發掃描.
- 業務層實作撮合的挑戰: 與資料庫需要進行很多輪互動, 并且需要在事務中完成, 事務RT和死鎖問題增加. 性能弱.
PG解決方案:
- 業務邏輯放在函數内完成, 大幅降低應用與資料庫互動, 降低RT.
- advisory lock, skip locked等技術手段避免死鎖.
DEMO:
限制:
- 時間優先
- 價格優先
-
- 買低不買高
- 賣高不賣低
- 限價交易, 指定價格
- 限時交易
-
- 過期未完成交易則撤單
結構設計:
1、時價表
stockid
price -- 時價
ts
2、買方pipeline
pk
uid
stockid
price
cnt
request_ts
deadline_ts
modify_ts
3、賣方pipeline
4、交易明細
buyer
provider
price
status
5、過期訂單曆史
ops -- 買or賣
請求需求:
- 建立交易訂單
- 修改訂單内容
- 撤單
撮合函數邏輯:
參數: 輸入stockid, batch次數(loop次數)
邏輯:
loop batch次數
删除過期訂單寫入過期訂單曆史表
按規則取出一條最早的待成交記錄, 買方和賣方, 時間優先, 并且取待交易數額(cnt)小的.
撮合
更新買、賣表cnt
寫交易明細
更新時價表
end loop;
參考
《如何用一個回形針換一棟别墅- openBarter (古人的物物交換市場) 類撮合交易系統》