文 | 閔令超 網易智企高級應用開發工程師
前言
數據報表分析對於企業管理者的分析決策有着至關重要的作用,因此數據報表的靈活可用以及數據的准確性顯得至關重要。本文會介紹基於 Elasticsearch 的數據指標系統,希望對大家有一定的借鑒和幫助。
背景
數據報表通常在業務開發中是必不可少的一部分,對於 To B 的應用更是如此。企業在使用產品的過程中必然需要對於整個的業務情況有一個准確的判斷和分析,這就需要我們能夠提供給企業盡可能多維度的詳細的數據報表。
初始數據報表方案
在項目的初期,為了業務的快速發展,往往采取的是比較簡單的架構進行處理,如下圖所示。根據產品對於指標的定義,通常開發通過代碼的形式直接定義指標的運算,依賴自研或者開源的定時任務調度系統,跑出相應的指標計算結果,保存到中間表中,查詢的時候根據不同的篩選條件,從不同的中間表中獲取指標的計算結果。
存在的問題
- 口徑不一致。在上述架構中,當不同的業務有數據交叉場景時,往往是從其他業務方復制相關指標計算的代碼拿來使用,這會造成數據指標口徑發生變化時,各個業務的相同的指標出現了指標口徑不一致的問題。
- 開發效率低。每次添加指標/修改指標都需要修改代碼、添加數據庫字段等多步驟 ,導致整個的指標開發周期特別的長。
- 不同維度的指標的計算邏輯處理邏輯、任務不同,每次修改邏輯需要修改多個地方。
基於 Elasticsearch 的數據報表方案
隨着業務的發展,指標的定義越來越多,報表也變得越來越豐富,基於定時任務架構的弊端暴露的越來越明顯,開發的負擔變的越來越重,在這時候,就需要對上述架構升級,減少業務開發的工作量。此階段,由於數據量仍然不是很大,同時為了業務方便開發和維護,可以參考數倉系統,搭建一個簡易的數據指標系統。
考慮到上述存在的問題,首先需要明確大的方向和目標。
- 規范化數據指標的開發流程,保證數據口徑的統一。
- 提供數據指標平台,便於業務開發能夠基於 SQL 開發大部分的指標,減少指標的開發工作量,提高指標的開發效率。
- 明確整個數據報表的生產流程,參考數倉建設方案,規范化整個數據指標的產出流程。
- 提供有效的 SDK,方便業務方的調用。
- 需要支持多數據源,在業務中往往不止一個數據源,可能會有 MySQL、Hive、ElasticSearch 等多個數據源,所以需要支持從多數據源匯集數據的能力。
- 需要對於指標的異常進行及時告警,方便開發排查業務異常。
術語簡介
- 原子指標:原子指標是指最細粒度的指標,即不能再向下拆分的指標,例如 指標 A=指標 B+指標 C,那么這里指標 B 和指標 C 即為原子指標。
- 復合指標:復合指標是多個原子指標通過計算處理獲取的結果,例如 指標 A=指標 B+指標 C,這里指標 A 就是表示復合指標。
- 維度:數據查詢的角度。一般是指日期、客服組等信息。如下圖中標紅部分即為維度信息。
- 時間周期:時間周期是用來描述一個指標的計算范圍。在統計指標的過程中必須指定用於計算的時間周期字段,通常,原子指標的計算的最小時間周期為小時,天數據基於小時數據做聚合得出。
- 報表:報表是一系列復合指標/原子指標的集合,通常業務方獲取的指標數據都是一張報表。
- 業務域:一個項目往往會有多條業務線,每條業務線我們可以理解為一個業務域,以七魚為例,如在線會話、呼叫等,任何的原子指標、復合指標、報表都屬於某一個業務域。
架構
基於上述目標,這里以 Elasticsearch 的聚合查詢能力為依托,搭建如下的數據指標平台架構。
整體分為5大部分:
- 原始數據層: 主要是關系型數據庫中的表數據
- 明細層: 主要是通過 binlog 同步到 Elasticsearch 中保存。
- 業務層:主要包括兩大部分,指標計算和項目管理。指標計算主要是基於明細層數據以及業務開發和產品定義的指標口徑,產出相應維度的指標。項目管理主要是維度、指標、業務域相關配置等。
- 網關:提供統一的 SDK 便於業務方的直接調用。
- 業務方/控制台,業務方調用sdk獲取報表數據以及維度、指標等控制台的配置。
從整個架構體系來看,上述架構主要是統一了各個業務的原始層和明細層數據,並基於此開發了數據指標配置系統,能夠快速的響應業務需求,將數據指標的開發周期大大縮短,也避免了開發人員直接在代碼里面編寫指標計算代碼,帶來口徑不統一或者重復建設的問題。
原始數據層/明細層
從上圖中可以看到,最底層部分是原始數據層和明細層,這個是整個架構的基礎所在。從原始層到明細層同步采用 binlog+ 自定義消息的同步方式,具體架構如下:
同步數據主要有三種模式:
- binlog 模式。通過 binlog 模式,同步數據庫中相應表中的數據,根據指定的關聯表的唯一鍵,可以將多張表的數據同步到一張大寬表中,方便指標的運算。binlog 同步可以依靠開源的 Canal、Maxwell 等組件,也可以是自研組件等。
- 全量同步模式。當 binlog 同步出現數據丟失,或者需要歷史數據同步時,采用全量同步的模式進行數據的補全和修正。全量同步主要依賴業務的定時任務調度系統。
- 自定義 topic。當數據統計需要添加自定義字段而又不想在數據庫中添加相應字段時,可以通過自定義 topic 將想要添加的字段添加到對應的大寬表中。
明細層數據的存儲在 es 中,通過明細層可以完成業務到數據的轉換,保存維度信息以及最細粒度的數據。聚合層可基於明細層進行復雜的指標計算。
明細層數據保存在 Elasticsearch 中,我們需要考慮索引的分片規則,防止由於分片規則導致索引的數據分布不均勻,會對於搜索和聚合產生較大的影響。對於索引的划分,通常采用月份進行划分索引,這樣保證明細數據在各個索引中會比較均勻的分布,同時,當索引較多時,也方便對於歷史索引做冷數據處理,聚合的速度也能夠保存比較穩定的狀態,不會因為某個索引的數據過多,降低聚合的速度。
聚合層
聚合層負責對業務指標進行沉淀、向上提供統一的計算口徑,同時可以基於現有的指標進行組合查詢,避免重復計算指標。目前指標的查詢計算均通過 Elasticsearch 計算。通過依賴 ElasticsearchSql 組件,可以使得業務方通過編寫 SQL 的方式定義原子指標,如下
SELECT COUNT(*)
FROM table_1
WHERE condition_1<>2 AND condition_2=2 GROUP BY A,B
如上面語句所示,WHERE 即原子指標計算的查詢條件,GROUP BY 即指標計算的維度。具體計算流程如下:
當然在聚合指標數據的過程中,過多的指標聚合查詢,可能會導致 Elasticsesrch 的 CPU 負載過高,為了避免這個問題我們需要調整任務策略,每個指標一次批量處理多家企業,這樣可以大大降低請求的次數,提高了任務的執行速度,保證了 Elasticsearch 集群的穩定。
在實際的業務指標開發中,經常會碰到產品對於指標的定義的改變,當指標定義改變時,需要測試用戶對於改指標變化的反饋程度,以及能夠提供相應的策略,方便回滾到老的指標定義的數據。
針對上面的問題,我們提出了環境和版本的概念。指標的上線會有業務定義的多套環境,例如灰度和全量。通過環境,可以給一部分企業嘗試切換新的指標定義,測試反饋效果。同時,每一個原子指標會有多個版本,每一次定義的改變都會產生一個版本,復合指標可以選擇相應版本的指標進行結果的計算,如果客戶對於新的指標定義不滿意,依然可以回滾到之前的版本。具體的操作流程如下圖所示:
業務方調用
業務方添加指標並調用的整個流程如下圖:
如上圖所示,業務方需要添加指標時,需要在原子指標池中添加相應的指標計算規則,默認初始化版本為 V1,如果需要同步歷史數據則在添加指標時創建歷史數據同步任務,創建完任務之后,系統會自動計算並同步所選時間段的指標數據,歷史數據同步完成之后方可在指標建模中勾選新指標。指標建模完成之后,通常是需要業務方在自己的定制化報表中添加建模之后的指標,通過 SDK 獲取相應的報表時,會自動返回添加的指標值。
總結與展望
當然,上述的架構仍有一定的局限性,當業務發展到比較大的規模,業務線逐漸增多,業務數據量級也逐漸增大,企業對於數據的需求要求會變的更加的多樣,往往我們的報表不能充分的滿足客戶的需求,這個時候,就需要給客戶提供自定義報表的能力,使其不局限於系統內提供的報表查詢維度,對於一個指標,企業可以從任意的可選維度進行查詢分析。這個時候這套方案已經不能滿足客戶的需求。所以需要對報表系統再次進行架構升級,這時候可以搭建業務內部的數倉系統,整合內部企業分析以及對外數據報表輸出能力。