《基于Lambda架構(gòu)的股票市場(chǎng)事件處理引擎實(shí)踐》要點(diǎn):
本文介紹了基于Lambda架構(gòu)的股票市場(chǎng)事件處理引擎實(shí)踐,希望對(duì)您有用。如果有疑問(wèn),可以聯(lián)系我們。
CEP(Complex Event Processing)是證券行業(yè)很多業(yè)務(wù)應(yīng)用的重要支撐技術(shù).CEP的概念本身并不新鮮,相關(guān)技術(shù)已經(jīng)被運(yùn)用超過(guò)15年以上,但是證券界肯定是運(yùn)用CEP技術(shù)最為充分、最為前沿的行業(yè)之一,從算法交易(algorithmic trading)、風(fēng)險(xiǎn)管理(risk management)、關(guān)鍵時(shí)刻管理(Moment of Truth – MOT)、委托與流動(dòng)性分析(order and liquidity analysis)到量化交易(quantitative trading)乃至向投資者推送投資信號(hào)(signal generation)等等,不一而足.
CEP技術(shù)通常與Time-series Database(時(shí)序數(shù)據(jù)庫(kù))結(jié)合,最理想的解決方案是CEP技術(shù)平臺(tái)向應(yīng)用提供一個(gè)歷史序列(historical time-series)與實(shí)時(shí)序列(real-time series)無(wú)差異融合的數(shù)據(jù)流連續(xù)體(continuum)- 對(duì)于證券類應(yīng)用而言,昨天、上周、上個(gè)月的數(shù)據(jù)不過(guò)是當(dāng)下此刻數(shù)據(jù)的延續(xù),而處理算法卻是無(wú)邊際的 – 只要開(kāi)發(fā)者能構(gòu)想出場(chǎng)景與模型.
廣發(fā)證券的IT研發(fā)團(tuán)隊(duì),一直關(guān)注Storm、Spark、Flink等流式計(jì)算的開(kāi)源技術(shù),也經(jīng)歷了傳統(tǒng)Lambda架構(gòu)的技術(shù)演進(jìn),在Kappa架構(gòu)的技術(shù)尚未成熟之際,團(tuán)隊(duì)針對(duì)證券行業(yè)的技術(shù)現(xiàn)狀與特點(diǎn),采用改良的Lambda架構(gòu)實(shí)現(xiàn)了一個(gè)CEP引擎,本文介紹了此引擎的架構(gòu)并分享了一些股票業(yè)務(wù)較為有趣的應(yīng)用場(chǎng)景,以饗同好.
隨著移動(dòng)互聯(lián)和物聯(lián)網(wǎng)的到來(lái),大數(shù)據(jù)迎來(lái)了高速和蓬勃發(fā)展時(shí)期.一方面,移動(dòng)互聯(lián)和物聯(lián)網(wǎng)產(chǎn)生的大量數(shù)據(jù)為孕育大數(shù)據(jù)技術(shù)提供了肥沃的土壤;一方面,各個(gè)公司為了應(yīng)對(duì)大數(shù)據(jù)量的挑戰(zhàn),也急切的需要大數(shù)據(jù)技術(shù)解決生產(chǎn)實(shí)踐中的問(wèn)題.短時(shí)間內(nèi)各種技術(shù)層出不窮,在這個(gè)過(guò)程中Hadoop脫穎而出,并營(yíng)造了一個(gè)豐富的生態(tài)圈.雖然大數(shù)據(jù)一提起Hadoop,好像有點(diǎn)老生常談,甚至覺(jué)得這個(gè)技術(shù)已經(jīng)過(guò)時(shí)了,但是不能否認(rèn)的是Hadoop的出現(xiàn)確實(shí)有非凡的意義.不管是它分布式處理數(shù)據(jù)的理念,還是高可用、容錯(cuò)的處理都值得好好借鑒和學(xué)習(xí).
剛開(kāi)始,大家可能都被各種分布式技術(shù)、思想所吸引,一頭栽進(jìn)去,掉進(jìn)了技術(shù)的漩渦,不能自拔.一方面大數(shù)據(jù)處理技術(shù)和系統(tǒng)確實(shí)復(fù)雜、繁瑣;另一方面大數(shù)據(jù)生態(tài)不斷的推陳出新,新技術(shù)和新理念層出不窮,確實(shí)讓人目不暇接.如果想要把生態(tài)圈中各個(gè)組件玩精通確實(shí)不是件容易的事情.本人一開(kāi)始也是深陷其中,皓首窮經(jīng)不能自拔.但騰出時(shí)間,整理心緒,回頭反顧,突然有種釋然之感.大數(shù)據(jù)并沒(méi)有大家想象的那么神秘莫測(cè)與復(fù)雜,從技術(shù)角度看無(wú)非是解決大數(shù)據(jù)量的采集、計(jì)算、展示的問(wèn)題.
因此本文參考Lambda/Kappa架構(gòu)理念,提出了一種有行業(yè)針對(duì)性的實(shí)現(xiàn)方法.盡量讓系統(tǒng)層面更簡(jiǎn)單,技術(shù)更同構(gòu),初衷在讓大家聚焦在大數(shù)據(jù)業(yè)務(wù)應(yīng)用上來(lái),從而真正讓大數(shù)據(jù)發(fā)揮它應(yīng)有的價(jià)值.
Lambda架構(gòu)是由Storm的作者Nathan Marz 在BackType和Twitter多年進(jìn)行分布式大數(shù)據(jù)系統(tǒng)的經(jīng)驗(yàn)總結(jié)提煉而成,用數(shù)學(xué)表達(dá)式可以表示如下:
batch view = function(all data)
realtime view = function(realtime view,new data)
query = function(batch view .realtime view)
邏輯架構(gòu)圖如下:
從圖上可以看出,Lambda架構(gòu)主要分為三層:批處理層,加速層和服務(wù)層.它整合了離線計(jì)算和實(shí)時(shí)計(jì)算,融合了不可變性(immutable),讀寫(xiě)分離和復(fù)雜性隔離等一系列架構(gòu)原則設(shè)計(jì)而成,是一個(gè)滿足大數(shù)據(jù)系統(tǒng)關(guān)鍵特性的架構(gòu).Nathan Marz認(rèn)為大數(shù)據(jù)系統(tǒng)應(yīng)該具有以下八個(gè)特性,Lambda都具備它們分別是:
由于Lambda架構(gòu)的數(shù)據(jù)是不可變的(immutable),因此帶來(lái)的好處也是顯而易見(jiàn)的:
但是Lambda也有自身的局限性,舉個(gè)例子:在大數(shù)據(jù)量的情況下,要即席查詢過(guò)去24小時(shí)某個(gè)網(wǎng)站的pv數(shù).根據(jù)前面的數(shù)學(xué)表達(dá)式,Lambda架構(gòu)需要實(shí)現(xiàn)三部分程序,一部分程序是批處理程序,比如可能用Hive或者M(jìn)apReduce批量計(jì)算最近23.5個(gè)小時(shí)pv數(shù),一部分程序是Storm或Spark Streaming流式計(jì)算程序,計(jì)算0.5個(gè)小時(shí)內(nèi)的pv數(shù),然后還需要一個(gè)服務(wù)程序?qū)⑦@兩部分結(jié)果進(jìn)行合并,返回最終結(jié)果.因此Lambda架構(gòu)包含固有的開(kāi)發(fā)和運(yùn)維的復(fù)雜性.
因?yàn)橐陨系娜毕?Linkedin的Jay Kreps在2014年7月2日在O’reilly《Questioning the Lambda Architecture》提出了Kappa架構(gòu),如下圖:
Kappa在Lambda做的最大的改進(jìn)是用同一套實(shí)時(shí)計(jì)算框架代替了Lambda的批處理層,這樣做的好處是一套代碼或者一套技術(shù)棧可以解決一個(gè)問(wèn)題.它的做法是這樣的:
這樣相當(dāng)于用同一套計(jì)算框架和代碼解決了Lambda架構(gòu)中開(kāi)發(fā)和運(yùn)維比較復(fù)雜的問(wèn)題.當(dāng)然如果數(shù)據(jù)量很大的情況下,可以增加流式計(jì)算程序的并發(fā)度來(lái)解決速度的問(wèn)題.
由于金融行業(yè)在業(yè)務(wù)上受限于T+1交易,在技術(shù)上嚴(yán)重依賴關(guān)系型數(shù)據(jù)庫(kù)(特別是Oracle).在很多場(chǎng)景下,數(shù)據(jù)并不是以流的形式存在的,而且數(shù)據(jù)的更新頻率也并不是很實(shí)時(shí).比如為了做技術(shù)面分析的行情數(shù)據(jù),大多數(shù)只是使用收盤(pán)價(jià)和歷史收盤(pán)價(jià)(快照數(shù)據(jù))作為輸入,來(lái)計(jì)算各類指標(biāo),產(chǎn)生買賣點(diǎn)信號(hào).
因此這是一個(gè)典型的批處理的場(chǎng)景.另一方面,比如量化交易場(chǎng)景,很多實(shí)時(shí)的信號(hào)又是稍縱即逝,只有夠?qū)崟r(shí)才存在套利的空間,而且回測(cè)和實(shí)盤(pán)模擬又是典型的流處理.鑒于以上金融行業(yè)特有的場(chǎng)景,我們實(shí)現(xiàn)了我們自己的架構(gòu)(GF-Lambda),它介于Lambda和Kappa之間.一方面能夠滿足我們處理數(shù)據(jù)的需求;一方面又可以達(dá)到技術(shù)上的同構(gòu),減少開(kāi)發(fā)運(yùn)維成本.根據(jù)對(duì)數(shù)據(jù)實(shí)時(shí)性要求,將整個(gè)計(jì)算部分分為三類:
GF-Lambda的優(yōu)勢(shì)如下:
整個(gè)data flow采用腳本編寫(xiě),便于配置管理和升級(jí).而Oozie只能使用XML定義,升級(jí)遷移成本較大.
觸發(fā)方式靈活,整個(gè)PipeLine可以動(dòng)態(tài)生成,切實(shí)的做到了“analytics as a service”或者 “analysis automation”.
CEP在證券市場(chǎng)的應(yīng)用的有非常多,為了讀者更好的理解上述技術(shù)架構(gòu)的設(shè)計(jì),在此介紹幾個(gè)典型應(yīng)用場(chǎng)景.
1)自選股到價(jià)和漲跌幅提醒
自選股到價(jià)和漲跌幅提醒是股票交易軟件的一個(gè)基礎(chǔ)服務(wù)器,目的在于方便用戶簡(jiǎn)單、及時(shí)的盯盤(pán).其中我們使用MongoDB來(lái)存儲(chǔ)用戶的個(gè)性化設(shè)置信息,以便各類應(yīng)用可以靈活的定制自身的Schema.在功能上主要包括以下幾種:
主要的挑戰(zhàn)在于大數(shù)據(jù)量的實(shí)時(shí)計(jì)算,而采用GF-Lambda可以輕松解決這個(gè)問(wèn)題.數(shù)據(jù)處理流程如下:
首先從Kafka訂閱實(shí)時(shí)行情數(shù)據(jù)并進(jìn)行解析,轉(zhuǎn)化成RDD對(duì)象,然后再衍生出Key(market+stockCode),同時(shí)從Mongo增量加載用戶自選股預(yù)警設(shè)置數(shù)據(jù),然后將這兩份數(shù)據(jù)進(jìn)行一個(gè)Join,再分片對(duì)同一個(gè)Key的兩個(gè)對(duì)象做一個(gè)Filter,產(chǎn)生出預(yù)警信息,并進(jìn)行各個(gè)終端渠道推送.
2)自選股實(shí)時(shí)資訊
實(shí)時(shí)資訊對(duì)各類交易用戶來(lái)說(shuō)是非常重要的,特別是和自身嚴(yán)重相關(guān)的自選股實(shí)時(shí)資訊.一個(gè)公告、重大事項(xiàng)或者關(guān)鍵新聞的出現(xiàn)可能會(huì)影響到用戶的投資回報(bào),因此這類事件越實(shí)時(shí),對(duì)用戶來(lái)說(shuō)價(jià)值就越大.
在GF-Lambda平臺(tái)上,自選股實(shí)時(shí)資訊主要分為兩部分:實(shí)時(shí)資訊的采集及預(yù)處理(適配)、資訊信息與用戶信息的撮合.整個(gè)處理流程如下圖所示:
在上圖分割線左側(cè)是實(shí)時(shí)資訊的預(yù)處理部分,首先使用Spark JDBC接口從Oracle數(shù)據(jù)庫(kù)加載數(shù)據(jù)到Spark,形成DataFrame,再使用Spark SQL的高級(jí)API做數(shù)據(jù)的預(yù)處理(此處主要做表之間的關(guān)聯(lián)和過(guò)濾),最后將每個(gè)Partition上的數(shù)據(jù)轉(zhuǎn)化成協(xié)議要求的格式,寫(xiě)入Kafka中等待下游消費(fèi).
左側(cè)數(shù)據(jù)ETL的過(guò)程是完全由Airflow來(lái)進(jìn)行驅(qū)動(dòng)調(diào)度的,而且每次處理完就將狀態(tài)cache到Redis中,以便下次增量處理.在上圖的右側(cè)則是與用戶強(qiáng)相關(guān)的業(yè)務(wù)邏輯,將用戶配置的信息與實(shí)時(shí)資訊信息進(jìn)行撮合匹配,根據(jù)用戶設(shè)置的偏好來(lái)產(chǎn)生推送事件.
此處用Kafka來(lái)做數(shù)據(jù)間的解耦,好處是不言而喻的.首先是保證了消息之間的靈活性,因?yàn)樽髠?cè)部分產(chǎn)生的事件是一個(gè)基礎(chǔ)公共事件,而右側(cè)才是一個(gè)與業(yè)務(wù)緊密耦合的邏輯事件.基礎(chǔ)公共事件只有事件的基礎(chǔ)屬性,是可以被很多業(yè)務(wù)同時(shí)訂閱使用的.
其次從技術(shù)角度講左側(cè)是一個(gè)類似批處理的過(guò)程,而右側(cè)是一個(gè)流處理的過(guò)程,中間通過(guò)Kafka做一個(gè)轉(zhuǎn)換與對(duì)接.這個(gè)應(yīng)用其實(shí)是很具有代表性的,因?yàn)樵诖蟛糠智闆r下,數(shù)據(jù)源并不是以流的形式存在,更新的頻率也并不是那么實(shí)時(shí),所以大多數(shù)情況下都會(huì)涉及到batch layer與speed layer之間的轉(zhuǎn)換對(duì)接.
3)資金流選股策略
上面兩個(gè)應(yīng)用相對(duì)來(lái)說(shuō)處理流程比較簡(jiǎn)單,以下這個(gè)case是一個(gè)業(yè)務(wù)
稍微繁瑣的CEP應(yīng)用-資金流策略交易模型,該模型使用資金流流向來(lái)判斷股票在未來(lái)一段時(shí)間的漲跌情況.它基于這樣一個(gè)假設(shè),如果是資金流入的股票,則股價(jià)在未來(lái)一段時(shí)間上漲是大概率事件;如果是資金流出的股票,則股價(jià)在未來(lái)一段時(shí)間下跌是大概率事件.那么我們可以基于這個(gè)假設(shè)來(lái)構(gòu)建我們的策略交易模型.如下圖所示,這個(gè)模型主要分為三部分:
1)個(gè)股資金流指標(biāo)的實(shí)時(shí)計(jì)算
由于涉及到一些業(yè)務(wù)術(shù)語(yǔ),這里先做一個(gè)簡(jiǎn)單的介紹.
資金流是一種反映股票供求關(guān)系的指標(biāo),它的定義如下:證券價(jià)格在約定的時(shí)間段中處于上升狀態(tài)時(shí)產(chǎn)生的成交額是推動(dòng)指數(shù)上漲的力量,這部分成交額被定義為資金流入;證券價(jià)格在約定的時(shí)間段中下跌時(shí)的成交額是推動(dòng)指數(shù)下跌的力量,這部分成交額被定義為資金流出;若證券價(jià)格在約定的時(shí)間段前后沒(méi)有發(fā)生變化,則這段時(shí)間中的成交額不計(jì)入資金流量.當(dāng)天資金流入和流出的差額可以認(rèn)為是該證券當(dāng)天買賣兩種力量相抵之后,推動(dòng)價(jià)格變化的凈作用量,被定義為當(dāng)天資金凈流量.數(shù)量化定義如下:
其中,Volume為成交量,為i時(shí)刻收盤(pán)價(jià),為上一時(shí)刻收盤(pán)價(jià).
嚴(yán)格意義上講,每一個(gè)買單必須有一個(gè)相應(yīng)的賣單,因此真實(shí)的資金流入無(wú)法準(zhǔn)確的計(jì)算,只能通過(guò)其他替代方法來(lái)區(qū)分資金的流入和流出,通過(guò)高頻數(shù)據(jù),將每筆交易按照驅(qū)動(dòng)股價(jià)上漲和下跌的差異,確定為資金的流入或流出,最終匯聚成一天的資金流凈額數(shù)據(jù).根據(jù)業(yè)界開(kāi)發(fā)的CMSMF指標(biāo),采用高頻實(shí)時(shí)數(shù)據(jù)進(jìn)行資金流測(cè)算,主要出于以下兩方面考慮:一是采用高頻數(shù)據(jù)進(jìn)行測(cè)算,可以盡可能反映真實(shí)的市場(chǎng)信息;二是采取報(bào)價(jià)(最近買價(jià)、賣價(jià))作為比較基準(zhǔn),成交價(jià)大于等于上期最優(yōu)賣價(jià)視為流入,成交價(jià)小于等于上期最優(yōu)買價(jià)視為流出.
除了資金的流入、流出、凈額,還有一系列衍生指標(biāo),比如根據(jù)流通股本數(shù)多少衍生出的大、中、小單流入、流出、凈額,及資金流信息含量(IC)、資金流強(qiáng)度(MFP),資金流杠桿倍數(shù)(MFP),在這里就不一一介紹.
從技術(shù)角度講,第一部分我們通過(guò)訂閱實(shí)時(shí)行情信息,開(kāi)始計(jì)算當(dāng)天從開(kāi)市到各個(gè)時(shí)刻點(diǎn)的資金流入、流出的累計(jì)值,及衍生指標(biāo),并將這些指標(biāo)計(jì)算完成后重新寫(xiě)回到Kafka進(jìn)行存儲(chǔ),方便下游消費(fèi).因此第一部分完全是一個(gè)大數(shù)據(jù)量的實(shí)時(shí)流處理應(yīng)用,屬于Lambda的speed layer.
2)買賣信號(hào)量的產(chǎn)生及交易
第二部分在業(yè)務(wù)上屬于模型層,即根據(jù)當(dāng)前實(shí)時(shí)資金流指標(biāo)信息,構(gòu)建自己的策略模型,輸出買賣信號(hào).比如以一個(gè)簡(jiǎn)單的策略模型為例,如果同時(shí)滿足以下三個(gè)條件產(chǎn)生買的信號(hào).反之,產(chǎn)生賣的信號(hào):
在技術(shù)上,這個(gè)應(yīng)用也屬于Lambda的 speed layer,通過(guò)訂閱Kafka中的資金流指標(biāo),根據(jù)上面簡(jiǎn)單的模型,不斷的判斷是否要買或者賣,并調(diào)用接口發(fā)起買賣委托指令,最后根據(jù)回報(bào)結(jié)果操作持倉(cāng)表或者成交表.(注意此處在業(yè)務(wù)上只是以簡(jiǎn)單的模型舉例,沒(méi)有涉及到更多的細(xì)節(jié))
3)持倉(cāng)盈虧實(shí)時(shí)追蹤及交易
第三部分在業(yè)務(wù)上主要是準(zhǔn)實(shí)時(shí)的盈虧計(jì)算.在技術(shù)層面,屬于Lambda 的batch layer.通過(guò)訂閱實(shí)時(shí)行情和加載持倉(cāng)表/成交表,實(shí)時(shí)計(jì)算用戶的盈虧情況.當(dāng)然此處還有一些簡(jiǎn)單的止損策略,也可以根據(jù)盈利情況,發(fā)起賣委托指令,并操作持倉(cāng)表和成交表.最后將盈利情況報(bào)給服務(wù)層,進(jìn)行展示或者提供回調(diào)接口.詳細(xì)的處理流程如下圖所示:
正如文章前面強(qiáng)調(diào)的一樣,寫(xiě)這篇文章的初衷是希望大家從大數(shù)據(jù)豐富的生態(tài)中解放出來(lái),與業(yè)務(wù)深度的跨界融合,從而開(kāi)發(fā)出更多具有價(jià)值的大數(shù)據(jù)應(yīng)用,真正發(fā)揮大數(shù)據(jù)應(yīng)有的價(jià)值.這和Lambda架構(gòu)的作者Nathan Marz的理念也是十分吻合的,記得他還在BackType工作的時(shí)候,他們的團(tuán)隊(duì)才五個(gè)人,卻開(kāi)發(fā)了一個(gè)社會(huì)化媒體分析產(chǎn)品——在100TB的數(shù)據(jù)上提供各種豐富的實(shí)時(shí)分析,同時(shí)這個(gè)小的團(tuán)隊(duì)還負(fù)責(zé)上百臺(tái)機(jī)器的集群的部署、運(yùn)維和監(jiān)控.
當(dāng)他向別人展示產(chǎn)品的時(shí)候,很多人都很震驚他們只有五個(gè)人.經(jīng)常有人問(wèn)他:“How can so few people do so much?”.他的回答是:“It’s not what we’re doing, but what we’re not doing.”通過(guò)使用Lambda架構(gòu),他們避免了傳統(tǒng)大數(shù)據(jù)架構(gòu)的復(fù)雜性,從而產(chǎn)出變得非常顯著.
在五花八門(mén)的大數(shù)據(jù)技術(shù)層出不窮的當(dāng)下,Marz的理念更加重要.我們一方面需要與時(shí)俱進(jìn)關(guān)注最新的技術(shù)進(jìn)步 – 因?yàn)樾录夹g(shù)的出現(xiàn)可能反過(guò)來(lái)讓以前沒(méi)有考慮過(guò)或者不敢想的應(yīng)用場(chǎng)景變成可能,但另一方面更重要的是,大數(shù)據(jù)技術(shù)的合理運(yùn)用需要建立在對(duì)行業(yè)領(lǐng)域知識(shí)深刻理解的基礎(chǔ)上.大數(shù)據(jù)是金融科技的核心支撐技術(shù)之一,我們將持續(xù)關(guān)注最前沿的大數(shù)據(jù)技術(shù)與架構(gòu)理念,持續(xù)優(yōu)化最符合金融行業(yè)特點(diǎn)的解決方案,構(gòu)建能放飛業(yè)務(wù)專家專業(yè)創(chuàng)新能力的技術(shù)平臺(tái).
鄧昌甫,畢業(yè)于中山大學(xué),廣發(fā)證券IT研發(fā)工程師,一直從事大數(shù)據(jù)平臺(tái)的架構(gòu)、及大數(shù)據(jù)應(yīng)用的開(kāi)發(fā)、運(yùn)維和敏捷相關(guān)工具的引入和最佳實(shí)踐的推廣(Git/Jenkins/Gerrit/Zenoss).
文章出處:聊聊架構(gòu)(訂閱號(hào)ID:archtime)
轉(zhuǎn)載請(qǐng)注明本頁(yè)網(wǎng)址:
http://www.snjht.com/jiaocheng/4431.html