梁鑫:重构 - 在美股行情系统的实践
梁鑫
讀完需要
4
分鐘速讀僅需 2 分鐘
作者:梁鑫(資深架構師,多年云原生,微服務架構經驗,開源 SIA 系列產品 owner)
1
? ?
引子
今年開始,由于工作內容調整。開始負責美股港股產品的研發。第一個面對的問題,就是當前產品股票行情信息嚴重延遲。股票行情信息延遲,客戶會看到的是錯誤的股價,這直接導致了產品的不可用,失去了客戶的信任。
股票行情是一種證券市場用語,指股票交易所內各只股票的漲幅變化及交易流通情況。
2
? ?
舊版美股行情系統架構圖
從現狀的架構圖中可以看出,美股行情產品有以下若干問題
2.1
? ?
問題一,消息服務器選擇
相信很多朋友都對 rabbitmq 有所了解,很多公司都采用了 rabbitmq。它以傳輸速度快,可靠性高而被廣為使用。在主流的開源消息服務器中,它是唯一可以傳輸速度達到微秒級的消息消息服務器。在實際傳輸中,即使使用集群,它也并不是真正的分布式隊列服務器。所以在消息順序上,它是保證的最好的。但 rabbitmq 也有自身的不足,最大的不足就是吞吐量太低。無法滿足海量股票行情信息的傳輸需求。
2.2
? ?
問題二,緩存服務器 Redis 的使用
Redis 緩存服務的性能,相信可以滿足大多數項目的需求。但如果降美股行情的數據量進行全量的寫入操作,即使是 redis,也 cover 不住。雖然 Redis 號稱能支持每秒 14 萬的讀操作,11 萬的寫操作。但這估計是理想的情況。在實際的生產環境中,我們的實際測試結果是達不到這個量級的。對于每秒超過十萬的股票行情信息,每條數據都進行 redis 寫操作,必然出現大量的寫入失敗,甚至頻繁出現 redis 鏈接異常。
2.3
? ?
問題三,線程池的使用
在現存的架構中,多線程設計有著明顯的問題。因為 rabbitmq 的吞吐量不足,因此技術上把數百條消息合并成一條進行傳輸處理,這樣雖降低了消息吞吐量,不會導致消息大量堆積,但卻對實時的股票行情數據造成了人為的延遲。即便進行了消息合并,但吞吐量還是過大,因此根據股票的名稱把若干股票的信息分組用不同的隊列進行傳輸。
每組股票都用一個線程池來處理。強行增大處理性能。當接到封裝的信息后,為了保證能夠處理大量消息,還需要采用多線程方式,因為股票行情需要有一定順序行,無序的線程處理導致了大量時序錯誤信息, 最終發現展示結果很難使人滿意。并且維護大量的線程池極度消耗資源,我們常規意義的線程配置,是計算有限 CPU 核數+1,IO 有限 CPU 核數*2。維護數百個線程池,其實是讓線程切換的工作占據了大量的 CPU 時間,浪費了寶貴的 CPU 的資源。
2.4
? ?
問題四,系統無法進行水平擴展
如果判斷系統是一個好的集群架構。往往需要滿足三點要求。
一是可以避免單點故障;
二是可以水平擴展;
三是能實現負載均衡。
現狀股票行情架構是完全不能滿足這三點需求。需要進行重構。
3
? ?
新版美股行情系統架構圖
3.1
? ?
改進一,使用 kafka 替代 rabbitmq
美股行情信息吞吞量非常大,在開盤和收盤的高峰期甚至超過了每秒十萬條交易信息。如此之大的吞吐量,很明顯 rabbitmq 根本無法滿足需求,只有采用吞吐更大的 kafka 才能滿足需求。我們經常用下表來比對幾種主流消息服務器的差異。
3.2
? ?
改進二,降低 redis 的寫入次數
如何降低 redis 的寫入次數,只能是把原先寫入 redis 的操作變更成為寫入內存。當股票行情信息通過 kafka 隊列服務器將消息流轉到股票計算節點時,計算節點把數據計算后寫入內存,同時定期將內存數據同步到 redis 中,這樣可以大大節省 redis 的寫操作,讓 redis 的性能能夠 cover 我們現在的需求。同時我們將性能較差的 redisTemplate 換成直接使用 jedis,通過我們的測試,兩者之間的性能差異接近三倍,并優化 redis 鏈接數,避免出現大量鏈接異常情況。
3.3
? ?
改進三,改進線程池的使用
現狀系統的線程池創建太多,讓寶貴的 CPU 資源浪費在了線程切換中。新的架構為了解決這個問題,獲取每只股票的 hashcode,然后用固定線程數取余,每個余數給一個固定的線程池,每個線程池保活一個線程,這樣就能保證每只股票在同一節點進入一個線程處理,最大限度保證了處理股票行情信息的順序性。
3.4
? ?
改進四,支持水平擴展
通過對 kafka 同一個 topic 訂閱,然后不同 worker 接收不同的信息,這樣可以輕松讓計算節點進行水平擴展。當信息再往下一個節點流轉時,查詢節點通過不同 groupid 訂閱完整 topic,不需要再通過 redis,這樣查詢節點可以輕松進行水平擴展。支持了整體架構的水平擴展。
4
? ?
總結
美股行情的吞吐量,遠超過我之前所負責過的項目。如此高的并發,且不能延遲,還要最大限度的保證處理信息的順序性。對自己而言也是個不小的挑戰,在這個項目中我學到了很多東西。
往期推薦歐創新:深度解析DDD中臺和微服務設計領域驅動專家張逸文字脫口秀:簡單工廠不簡單DDD專家張逸:《解構領域驅動設計》前言Hacker News熱文:請停止學習框架,學習領域驅動設計(DDD)(獲500個點贊)京東平臺研發朱志國:領域驅動設計(DDD)理論啟示DDD專家張逸:構建領域驅動設計知識體系領域驅動設計(DDD)在美團點評業務系統的實踐當DDD遇上微服務DDD戰略篇:架構設計的響應力可視化與領域驅動設計領域驅動設計(DDD)前夜:面向對象思想領域驅動設計(DDD):領域和子域DDD專家張逸:復雜與架構演進的關系滕云:DDD實現之路百度十億級流量的搜索前端,是怎么做架構升級的?Francisco: 構建前瞻性應用架構的優秀實踐這 3 種 DDD 分層架構的模式,你掌握了么?END ? ?? #技術人必備#點個在看,讓更多人看見總結
以上是生活随笔為你收集整理的梁鑫:重构 - 在美股行情系统的实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NYOJ 106 背包问题
- 下一篇: NYOJ 289 苹果