1. 程式人生 > 其它 >TDengine在同花順組合管理業務中的優化實踐

TDengine在同花順組合管理業務中的優化實踐

前言

同花順每天需要接收海量交易所行情資料,確保行情資料的資料準確。但由於該部分資料過於龐大,而且使用場景頗多,每天會產生很多的加工資料,而組合管理(PMS)還會使用到歷史行情資料。之前雖然採用了Postgres+LevelDB作為資料的儲存方案,但仍然有不少痛點,所以必須對儲存方案進行改造。

通過對ClickHouse、InfluxDB、TDengine等時序資料儲存方案的調研,最終我們選擇了TDengine。大資料監控平臺採用TDengine後,在穩定性、查詢效能等方面都有較大的提升。

專案背景與問題

同花順私募之家組合管理是一個集多資產管理、實時監控、績效分析、風險分析、輿情分控、報表輸出等功能於一體的智慧投資組合管理平臺。為券商、基金、私募等機構客戶提供實時準確的投研服務。

資料層面主要依賴實時資料及歷史日級別資料,為所支援的股票、基金、債券、美股、港股、期權、期貨資產類別的監控和分析提供支援。

其中,實時資料主要用於資產監控,由於使用場景會對數百個不同的標的進行資產監控,資料重新整理頻率在1秒左右。因此,整個系統對實時資料的讀寫效能及延時有著比較高的要求。

此外,歷史日級別資料主要用於投資組合的各種分析。歷史分析所涉及的標的數量,相較實時資產監控更多,在時間上的跨度會長至10數年。此外在輸出分析報告時,還會疊加多種分析指標和分析模型。在整個分析過程中,涉及巨量的資料集。這對歷史資料庫的讀寫效能又提出了更高的要求。

由上述架構圖可以看到,該服務內需要大量的基礎資料支撐,像實時行情、歷史行情。

針對歷史行情資料支撐,涉及多個證券品種的資料,包括股票、債券、基金、港股、美股、期貨、期權。資料跨度週期從數天到數年不等。頁面返回的資料是計算結果,而計算依賴的資料是業務層資料和大量歷史行情資料。這個計算過程包含了歷史行情資料請求。尤其是在展示結果包含多證券標的和長週期的情況下,產生一個分析報告可能達到 5s,而行情獲取耗時佔比達到80%以上。而且,輸出報告服務面臨併發情況,這種情況帶來的擁堵會進一步惡化使用者的使用體驗。

通過對改造前的資料流進行分析,當前行情獲取模組的分析, 當前存在以下2個需要解決的問題:

  • 依賴多,穩定性較差:PMS作為多品種的投後分析服務, 需要使用到各種日線資料、當天實時行情資料、當天分鐘資料等,在資料獲取方面需要依賴Http以及Postgres、LevelDB等資料庫。過於多的資料獲取鏈路會導致平臺可靠性降低,同時依賴於其他各個服務,導致查詢問題過於複雜。
  • 效能不能滿足需求: PMS作為多品種投後分析,在演算法分析層面需要大量的行情獲取,而且對行情獲取的效能也有較大的要求,當前所有行情會佔據大量分析的效能。

技術選型

為解決上述問題,我們有必要對現有行情模組進行升級改造。在資料庫選型方面,我們對如下資料庫做了預研和分析:

  • ClickHouse:運維成本太高,擴充套件過於複雜,使用的資源較多。
  • InfluxDB: 可以高效能地查詢與儲存時序型資料,被廣泛應用於儲存系統的監控資料、IoT行業的實時資料等場景;但是叢集功能沒有開源。
  • TDengine:效能、成本、運維難度都滿足,支援橫向擴充套件,且支援高可用。

通過綜合對比,我們初步選定TDengine作為行情模組的資料庫。

主要由於行情資料是繫結時間戳的形式,所以時序資料庫更適用於這個業務場景。而且在同等資料集和硬體環境下,濤思官方的測試結果顯示,TDengine的寫入速度遠高於InfluxDB。同時TDengine支援多種資料介面,包含C/C++、Java、Python、Go和RESTful等。

資料接入過程需要進行如下操作:

  • 資料清洗,剔除格式不對的資料;
  • 由於歷史資料過於雜亂,採取指令碼生成csv形式並直接匯入,後續增量資料由Python實現指令碼匯入資料。

資料庫建模以及應用場景

TDengine在接入資料前需要根據資料的特性設計schema,以達到最好的效能表現。

同花順行情根據時間頻度的不同,資料特性分別如下。

通用特性:

  • 資料格式固定,自帶時間戳;
  • 資料極少需要更新或刪除;
  • 資料標籤列不多,而且比較固定;
  • 單條資料資料量較小,欄位較少。

tick快照資料特性如下:

  • 每天資料量大,超過2000W;
  • 需保留近幾年資料。

daily資料特性如下:

  • 子表很多,約20W張表;
  • 每天資料20W;
  • 需保留近30年資料。

根據上述特點,我們構建瞭如下的資料模型。

按照TDengine建議的資料模型,將每個特性的資料單獨建立資料庫,根據不同特性資料設定不同的引數,在各個資料庫內根據品種去建立超級表,例如股票、指數、債券、基金等,結合我們的資料特點和使用場景,建立資料模型如下:

  • 以品種型別作為超級表,方便對同一型別的資料進行聚合分析計算;
  • 標的本身包括標的資訊,直接將標籤資訊作為超級表的標籤列,每個品種作為子表。

庫結構如下:

超級表結構:

落地實施

組合管理主要是需要可以穩定高效地獲取到資料,所以在實施的過程中需要考慮查詢的效能、線上資料的更新以及運維情況。

實施難點如下。

  • 資料寫入:由於歷史行情資料會存在大量的歷史資料,不是隻接收當前新增的資料,這對歷史資料的遷移有很大的挑戰。當前TDengine資料庫對於現有資料的匯入,通過insert語句達到批量更新,會導致歷史資料遷移耗時很大。為了解決該問題,我們在本地建立快取,將現有csv檔案修改為可執行匯入的形式,直接通過csv匯入,大大提升了寫入速度。在這個過程中,我們還發現了一個問題:通過csv匯入的時候,如果採用自動建立表的方式,會在幾個版本內出現崩潰。通過詢問官方,他們不建議在匯入csv的時候建立表,後來我們就拆解為先建立表結構再進行csv匯入,問題得到了解決。
  • 查詢問題:查詢單點問題。TDengine原生HTTP查詢是直接查詢特定服務端完成的。這個在生產環境是存在風險的。首先,所有的查詢都集中在一臺服務端,容易導致單臺機器過載;另外,無法保證查詢服務的高可用。基於以上兩點,我們在TDengine叢集使用過程中,在應用使用建立連結的時候會配置多臺Http的介面來解決單點問題。
  • 容量規劃:資料型別、資料規模對TDengine的效能影響比較大,每個場景最好根據自己的特性進行容量規劃,影響因素包括表數量、資料長度、副本數和表活躍度等。根據這些因素調整配置引數,確保最佳效能,例如blocks、caches和ratioOfQueryCores等。根據與濤思資料工程師的溝通,我們確定了TDengine的容量規劃計算模型。TDengine容量規劃的難點在於記憶體的規劃。

改造效果

完成改造後,線上的行情獲取效能可以達到預期,目前執行穩定。

  • 改造後效能對比情況,可以看到效能提升明顯。
  • 改造後穩定性對比情況:改造前呼叫資料情況共40W次,共出現異常0.01%的異常,改造後出現異常降低至0.001%。

TDengine問題解決

在使用TDengine的過程中,我們遇到了一些小問題。比如在通過Restful介面使用TDengine的時候,獲取資料超過10240行會有限制。經過溝通,我們瞭解到在啟動服務端時,引數restfulRowLimit 可以控制返回結果集的最大條數。

其他一些在使用過程中不清楚的地方,在濤思資料的物聯網大資料微信交流群都能很快得到反饋和解答。一些小bug也可以通過版本升級解決。

總結

目前從大資料監控這個場景看,TDengine在成本、效能和使用便利性方面都有非常大的優勢,尤其是在節省成本方面給我們帶來了很大驚喜。

在預研和專案落地過程中,濤思資料的工程師提供了專業、及時的幫助,在此表示感謝。

希望TDengine能夠不斷提升效能和穩定性,開發新特性,我們也會根據自身需求進行二次開發,向社群貢獻程式碼。祝TDengine越來越好。對於TDengine,我們也有一些期待改進的功能點:

  • 支援更加豐富的SQL語句;
  • 灰度平滑升級;
  • 可實現自定義聚合方法;
  • 更快的資料遷移。

後續我們也將在同花順的更多場景中嘗試應用TDengine,包括:

  • tick、minute行情資料的遷移以及線上應用;
  • 採取自定義聚合方法實現分鐘行情、日線行情的聚合計算;
  • 當天實時行情的資料的管理。

想了解更多 TDengine Database的具體細節,歡迎大家在GitHub上檢視相關原始碼。