說明:
以下內容,可以參考Esper官方網站《Qucik start & Tutorial 》(順序做了部分調整)。 PS:因為英語水平有限(大學期間剛過CET4的英語小盲童一枚),翻譯很爛(自己都感覺不能直視),描述不清的,可以隨時問。一有時間,將給予解釋。
Tutorial (教程)部分
1、簡介 (該部分在入門第一彈中有提起)
Esper 是一個事件流處理和事件關聯的引擎(CEP,complex event processing 復合事件處理)。作為實時事件驅動框架,當事件流中有事件條件發生時,Esper能夠觸發自定義動作(POJO)。Esper也是為了大量事件關聯而設計,當有數百萬的事件進來時,不能用經典的數據庫架構來存儲所有事件。
定制的事件處理語言EPL,允許表達豐富的事件條件、關聯性,也可跨越事件窗口,從而最大限度的減少為應對復雜情況而必須建立系統的開發難度。
Esper是輕量級的java內核實現,其可以完全嵌入到任何的java進程、javaEE應用服務器或者給予java的ESB(企業服務總線)。Esper可以很快完成傳入的大量消息或者事件處理的應用程序。
【總結】Esper是一個事件處理和復雜事件關聯處理的java內核的輕量級引擎。對於大量事件的處理,能夠用最短的時間做出反應,觸發相應的操作。另外,為Esper量身定制的事件處理語言——類SQL語言,對於表達事件的條件以及關聯關系的處理等非常方便。
2、事件流和復雜事件
信息對於作出明智的選擇是至關重要的。不僅現實生活中這是事實,而且在計算機處理中尤其是一些領域,比如金融、欺詐檢測、商業智能或是戰場操作等,也是很重要的。信息從不同的來源,以消息或者事件的形式流動,如股票價格在某一特定時間的狀態需要給出一個提示。也就是說,看離散的數據大部分時間是沒有意義的。交易者需要看到一段時間的股票走勢,以便結合其他信息在合適的時間做出最好的交易。
一條一條的離散事件是沒有意義的,事件流——一個無限的事件集合——可認為是一個滑動的窗口,進一步關聯是非常有意義的,並用最小的延遲對事件做出反應,對有效行動和競爭優勢是至關重要的。
【總結】事件流其實一個個離散的事件串接而成。現實中對於事件流的監控或者處理,比如股票信息等,需要實時性的計算其走勢,以便能夠及時的獲取有價值數據。事件流在Esper中是一個滑動的窗口,對事件關聯處理等至關重要。
3、Esper
關系型數據庫或者基於消息的系統比如JMS,真的很難處理時間數據和實時查詢。事實上,數據庫需要一個明確的查詢來返回有意義的數據,並且在數據放生變化時不適合推送數據。JMS系統是無狀態的,需要開發人員自己實現這個時間和聚合的邏輯。相比之下,Esper提供了更高的抽象和智能,可以認為是數據庫的倒置:不是存儲數據,而是對存儲的數據運行查詢,Esper允許應用程序存儲查詢,並讓數據運行通過。當滿足查詢的條件發生時,Esper會做出實時的響應。執行模塊是持續的,而不是只有在查詢提交的時候。這個概念是EDA(事件驅動架構)的關鍵基礎,在過去的10年,甚至更久都一直在積極的研究。然而,現實中對該系統重要性的認知最近才開始出現。
在Esper中,定制的EPL允許在引擎中注冊查詢。監聽類(POJO類)會在事件滿足EPL條件的時候由引擎進行調用。EPL能夠表達復雜的匹配條件,包括事件窗口、事件流關聯、過濾、聚合以及排序等。Esper statement也可以通過“followed by ” 即“->”條件從多個簡單的事件中獲取復雜事件。事件可以被描述成JavaBean類、傳統的java類、XML或者是Map,作為消息發布者,促進重用現有的系統。
【總結】在處理實時性的數據時,比如心跳監控、股票價格走勢等,Esper相對於關系型數據庫有天然的優勢,Esper不需要對完成的數據的存儲,便可以完成數據的實時查詢處理,從這點看,更像是數據庫的倒置——試想一下,數據庫是先存儲數據,通過編譯解析SQL,完成已存儲數據的查詢,Esper則是先編譯EPL語句,形成一個過濾(或處理)層(或者網),實時過來的數據,通過這個過濾層完成有效事件的篩選或形成有效事件。Esper的事件處理語言——EPL,是類SQL語言,其select 語句、from語句、where語句以及group by 、having等,甚至包括大部分的聚合函數等,都和標准的SQL語言一致。在EPL規則的編寫上,對於有數據庫開發經驗的人來說,上手十分容易。
4、開發事件驅動應用
用Esper來開發事件驅動應用並不困難。大概有下面的幾步:
1> 通過分析業務域和定義探測的情景或者需要報告的信息,定義應用程序應該完成的功能或任務。
2> 定義性能要求,特別是吞吐量和延遲。
3> 確定從什么地方獲取事件。
4> 根據業務確定事件格式和事件內容。
5> 設計導致復雜事件的事件關系。
6> 事件源。
7> 設計事件表示類型:java類、map、或XML等
8> 定義EPL語句,用於匹配模式和流的處理。
9> 比如,用CSV適配器作為事件模擬工具,測試檢測場景,或產生加載加載事件。
10> 在最終的環境上,測試吞吐量和延遲。
5、設計事件表示方式
在Esper當中,java類是一種簡單、豐富且通用的事件表示方式。通過接口和超類,java類提供了繼承性和多態性,通過一個對象graph,就可以表示一個復雜的業務域。Maps或XML也是事件表示的一種方式。
6、事件流分析
EPL語句從一個或者多個事件流中派生和聚合信息,加入或合並事件流,並將一個時間流的結果提供給后續的語句。EPL在select語句和where語句的使用上,和SQL很相似。不過EPL語句用事件流和views替換了數據庫的表格。和SQL中表格相似,views定義了可用於查詢和過濾的數據。Views可以表示為一個事件流上的一個窗口。Views也可以排序事件、從事件屬性獲取統計數據、進行事件分組或者處理唯一的事件屬性值。
下面的EPL語句用於計算股票事件過去30s的平均價格:
select avg(price) from StockTickEvent.win:time(30 sec)
下面EPL返回的是前100條股票事件的平均值:
select symbol, avg(price) as averagePrice from StockTickEvent.win:length(100) group by symbol
下面的例子關聯了兩個事件流。第一個事件流由欺詐告警事件組成,用於保存過去30分鍾的事件信息。第二個流則是withdrawal事件,用來保存過去30秒的事件。這兩個流通過account number進行關聯:
select fraud.accountNumber as accntNum, fraud.warning as warn, withdraw.amount as amount, MAX(fraud.timestamp, withdraw.timestamp) as timestamp, 'withdrawlFraud' as desc from FraudWarningEvent.win:time(30 min) as fraud, WithdrawalEvent.win:time(30 sec) as withdraw where fraud.accountNumber = withdraw.accountNumber
7、事件模式匹配
Event patterns match when an event or multiple events occur that match the pattern's definition.
一個或多個事件發生時,事件模式會匹配定義的模式(很別扭啊⊙﹏⊙b)。模式也可以是基於時間的。模式匹配時通過狀態機實現的。
模式表達式可以由連接了模式操作符的過濾器表達式組成。通過在圓括號中的嵌入表達式,可以實現更深的模式表達式嵌套。
5類操作符:
·控制模式探測器的創建和終止:every
· 邏輯操作符:and、or、not
· 操作事件順序的時間操作符:-> (緊跟着發生的,followed by)
· 過濾輸出事件的where條件,引起模式探測器的終止:如,timer:within
· 和觀察其他事件一樣,觀察者也觀察時間事件,如 timer:interval, timer:at
下面是一些EPL的例子:
//模式匹配的是在接下來60秒鍾IBM股票值大於80的所有事件 every StockTickEvent(symbol="IBM", price>80) where timer:within(60 seconds)
//每小時的第5分鍾給出提醒: every timer:at(5, *, *, *, *)
//當A事件發生時,如果后面跟的是B事件或C事件,則給出提醒(輸出A事件) A -> ( B or C )
//匹配的是每一個EventX,如果后跟EventY事件,並且其objectID和EventX的objectID一樣,則給出提醒(輸出a事件): every a=EventX -> every b=EventY(objectID=a.objectID)
8、模式匹配和事件流分析結合使用
當檢測到事件序列(或沒有事件發生)時,模式就會匹配。模式匹配的結果可以用於進一步的分析和處理。
下面的模式監測的是 Status事件發生后的10s沒有相同ID的status事件發生的場景。整個EPL語句進一步計算了所有發生的每個ID的事件總數。
select a.id, count(*) from pattern [ every a=Status -> (timer:interval(10 sec) and not Status(id=a.id) ] group by id
9、命名窗口
命名窗口在引擎中是全局的數據窗口,其可以參與到很多的語句查詢,並且可以被多個statement執行select、insert和delete操作。命名窗口和關系型數據庫系統的表很相似。
通過下面的幾步可以創建命名窗口:
create window AlertNamedWindow as (origin string, priority string, alarmNumber long)
當事件到達時,可以觸發一個select、update或delete操作。下面是一個select應用,簡單的統計數據窗口中的記錄行總數:
on TriggerEvent select count(*) from AlertNamedWindow
10、匹配-識別模式匹配(Match-Recognize Pattern Matching)
匹配-識別模式是一個基於正則表達式的模式匹配語法,是建議列入SQL的標准語法。
下面的匹配-識別模式,探測的是可能出現在事件中的模式,這些事件通過命名窗口(如上聲明)保存。這個模式查找的是兩個緊跟的事件,即事件之間沒有相同的origin。第一個事件必須有一個“high”優先級,第二個事件必須是“medium”優先級。
select * from AlertNamedWindow match_recognize ( partition by origin measures a1.origin as origin, a1.alarmNumber as alarmNumber1, a2.alarmNumber as alarmNumber2 pattern (a1 a2) define a1 as a1.priority = 'high', a2 as a2.priority = 'medium' )
11、變量(Variables)
變量是一個標量、對象或者事件值,可用於所有的statement,包括模式。變量可以用在EPL中任意位置的表達式中。
【總結】開發Esper應用時,事件類型建議采用Java類,對於事件信息的描述更為直觀(參考<a href="http://esper.codehaus.org/tutorials/tutorial/quickstart.html">Quick Start</a>)。在具有復雜關系的事件設計中,不建議使用Map的方式(可參考<a href="http://esper.codehaus.org/esper-4.9.0/doc/reference/en-US/html/performance.html#perf-tips-22">Esper參考文檔性能部分</a>)。在EPL設計時,根據業務需求,如果能通過標准的SQL語法完成的,盡量不要使用匹配模式,因為在運行時,需要對Pattern進行額外的解析,其規則較SQL復雜,性能上有少許損耗。
數據窗口的使用,能夠使得Esper處理更為復雜的應用場景,比如與分布式緩存、靜態數據的使用等。變量不難理解,不管是高級的開發語言如java、C/C++,還是腳本語言如ruby、JS等,都有變量的概念,其使用范圍,僅限於當前的Esper引擎實例。
另外,本節所描述的信息,如EPL、數據窗口等概念會在后續的更新中詳細描述。敬請期待!!
注:轉載請注明出處! 謝謝!