数据产品通用复合指标查询计算的实践
本文由作者王改革授權網易云社區發布。
一、背景和實現目標
在開發嚴選數據產品(大麥商品數據運營平臺和移動數據工作臺VIPAPP)的時候,最多的業務場景就是對實時和離線數據模型中查詢、處理、統一數據結構返回給前端。所以在開發的同時也一直在思考如何將這些相似的數據處理流程統一起來,更關注數據指標本身。
開發中經常遇到的幾個問題是:
數據查詢連接管理分散
模型查詢結果緩存分散
對于模型數據查詢結果缺少統一的數據變換模塊支持,每日產出的實時數據指標以及離線數據指標經過后端邏輯做接口返回的時候,會有大量的get、set操作,如果同時需要計算指標同比、環比、占比、對比值等復合指標時,就會充斥大量的重復臟代碼。
依賴的數據服務對存儲在MySQL、GP、Kylin、HBase等存儲引擎的數據模型暫時沒有多模型的連接支持。
所以針對以上問題,我們希望能夠設計出能夠在數據產品中使用的通用指標查詢計算模塊(DPRequestManager),主要實現如下目標:
管理數據模型查詢,封裝對于 統一查詢服務(DQS)、MySQL等查詢請求,提供查詢連接池。
提供靈活的數據變換能力
能夠通過配置對相應指標(包括指標值、環比、占比、同比等)自動計算,減少過多的冗余代碼。
支持數據對象映射,減少頻繁的取值和賦值操作
支持查詢級別的緩存(可以根據系統需求自定義緩存時間、可以設定緩存條件),減少對依賴服務的查詢壓力。
二、通用指標查詢計算模塊(DPRequestManager)組織結構
紅色部分的并發查詢器負責管理數據產品與底層數據查詢存儲引擎的連接,統一管理各種數據查詢。DPRequestManager會作為數據產品模型查詢的統一入口,封裝底層數據模型存儲引擎,為數據查詢提供線程池服務。同時此部分還提供模型退化的能力。
統一緩存模塊負責對數據查詢做條件緩存,對于每日數據未產出或者其他情況可以對查詢結果約定一些必要條件來決定是否緩存查詢結果(緩存級別為請求級別)。
橙色部分的數據變換模塊可以對DQS獲取的多表數據進行靈活數據變換
配置模塊可以對數據關系映射以及相應的復合指標計算做相應配置,統一生成結果,減少冗余代碼
三、數據變換模塊支持操作
對于從模型存儲引擎查詢結果處理成List<Map<String, Object>>結構的,并提供提供以下數據變換操作。
命名規則:模塊內部將使用數據dataKey存放查詢處理結果,dateKey對應的list結果可以類比excel行列表,其中的列名對應Map結構的key值。
現在主要提供如下數據操作:
compose({"group_id", "group_name"}, "result_A", "resultB")
rename ("dk", {"sale_amount_day", "sale_qty_day"}, {"sale_amount, sale_qty"})
group(row -> new StringJoiner("_").add(row.get("week").add(row.get("group_id")))
aggregation({"week", "group_id", "group_name"}, {sum("sale_amount"), sum("sale_qty")})
四、指標計算配置以及對象關系映射
這個地方主要解決兩個問題:
模型數據查詢結果到數據對象的映射,減少頻繁的取值和賦值,現在通用的ORM框架都能解決這個問題,DPRequestManager為了配合復合指標計算通過反射來實現數據對象映射部分。
映射過程中的指標計算(指標表達式計算、環比、同比、占比等復合指標的計算)
DPRequestManager主要是通過兩個配置來配合解決復合指標計算的問題。
第一個配置主要是定義數據對象映射的數據篩選規則(目標數據集合、環比數據集合、占比數據集合等)
{
"clazz": StockDTO.class, "useDate": "2018-12-07", // 指定目標值日期 "hbDate": "2018-12-06", // 指定環比日期 "hbKey": "group_id", // 計算環比使用 "filterKey": "", // 過濾器 "filterValue": ""}
第二個配置是數據對象DTO的配置(通過注解對復合指標計算進行配置定義)
DTO配置主要使用了三個注解,@FromDO,@FunctionDO,@IgnoreAssign
@From 定義簡單按key取值
@FunctionDO定義復合指標計算規則(hb,tb,zb,avg,sum等)
@IgnoreAssign 對象映射是字段忽略
同時支持定義的復合指標對象的指標計算賦值。
@Datapublic class StockSingleVO extends BaseVO { // 簡單取值,默認駝峰轉下劃線取字段group_id
private Long groupId; @FromDO("'商品組:'+group_name") private String groupName; // 簡單取值,直接在庫量 @FromDO("stock_cnt_zhuzhan_1d") private Number stockCnt; // 環比,對在庫量字段計算環比 @FromDO("stock_cnt_zhuzhan_1d") @FunctionDO(types = FunctionTypeEnum.HB) private Number stockCntHB; // 簡單取值,計算在庫+在途量 @FromDO(value = "stock_cnt_zhuzhan_1d+onway_cnt_zhuzhan_1d") private Number stockAndOnwayCnt; // 環比計算,計算在庫+在途的環比 @FromDO(value = "stock_cnt_zhuzhan_1d+onway_cnt_zhuzhan_1d") @FunctionDO(types = FunctionTypeEnum.HB) private Number stockAndOnwayCntHB; // 占比計算 @FromDO(value = "stock_cnt_zhuzhan_1d+onway_cnt_zhuzhan_1d") @FunctionDO(types = FunctionTypeEnum.ZB) private Number stockAndOnwayCntZB;}
數據過濾規則配置和數據對象中定義的復合指標計算配置一起支持數據對象映射,這樣可以減少大量重復賦值取值以及手動計算復合指標的工作。同時配合使用數據變換模塊和數據對象映射能夠釋放更大的靈活性,將數據變換模塊、數據對象映射、復合指標計算模塊解耦。
模塊查詢代碼示例:
/**
- condition1,condition2為構造的指標查詢條件
*/EngineRequest request1 = new EngineRequest(EngineType.DQS, condition1, EngineResultTypeEnum.LIST); // 構造查詢請求1EngineRequest request2 = new EngineRequest(EngineType.DQS, condition2, EngineResultTypeEnum.LIST); // 構造查詢請求2// 構造配置1(數據過濾配置 -> 配置目標日期、環比日期、計算環比目標分組key)EngineConvertConfig config = new EngineConvertConfig<>(StockSingleVO.class, "2018-12-07", "group_id", null, null);
config.setHbDate("2018-12-06");
Listlist = requestEngineManager.initThreadLocal()
五、總結
數據產品中很多通用的部分可以抽出來作為單獨模塊或者服務。文中介紹的復合指標查詢模塊已經在大麥商品數據運營平臺中實踐,它把數據產品指標查詢、計算以及對象映射等公共部分提取出來,有效的提高開發效率并能夠降低開發成本。
文章來源: 網易云社區
總結
以上是生活随笔為你收集整理的数据产品通用复合指标查询计算的实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mybatis 实现SQL拦截并在控制台
- 下一篇: 以太坊DAPP[2]-×××-react