一.需求
1.需求描述
統計每天,每個網點的快遞單數(有修改,攬收狀態,簽收狀態,是否退件等)
表: waybill
字段: 時間 :input_time,網點 network ,訂單唯一ID : waybillId
2. 需求sql翻譯
select date(input_time) day,network,count(distinct waybillId) waybillCout from waybill group by date(input_time) ,network
3. 需求難點
由於 waybill有更新,所以需要去重 distinct
聚合 group
二.方案和對比
方案 | 方案說明 | 去重 | 聚合 | java 查詢時長 | 數據延時 | 性能消耗 | 開發維護難度 |
flink累加 | 來一條,數據累加一條數據, 去重和聚合都在flink代碼實現 |
困難:由於數據有更新, 需要把數據緩存到redis, 然後做去重 |
困難:需要把數據緩存 到redis,然後做聚合 |
秒級 | 無延時 | 低 | 難:每個統計都要新加代碼, 然後部署flink;flink掛了的時候,數據恢復困難,一般需要寫個離線的代碼恢復數據 |
es全量計算 | 把數據全量存入到es, 使用es唯一鍵去重, java api 聚合 |
易 | 易 | 數據量大的時候, 查詢時間很長 |
無延時 | 高:每次查詢都 要全量計算一次 |
新需求只用加java代碼 |
es數據預聚合 | 把數據全量存入到es, 每10秒預聚合一次 |
易 | 易 | 秒級 | 10秒延時 | 高:頻繁預計算 | 新需求只用加java代碼:由於 本次開發是全量計算,所以要改 成預計算,改造工作量比較大 |
整合方案 | 把數據全量存儲到es , 使用es 唯一鍵去重, 每天(每小時)預聚合一次, 今天(當前小時)的數據使用 明細數據聚合, 今天(當前小時)以前的歷史 數據查詢聚合好的數據 |
易 | 易 | 秒級 | 無延時 | 低:今天數據全量計算, 歷史數據查詢預聚合數據 |
低: 需要把原來的count , 轉化爲sun |
三.整合方案詳細說明
方案說明:
把數據全量存儲到es ,使用es 唯一鍵去重,每天(每小時)預聚合一次,今天(當前小時)的數據使用明細數據聚合,今天(當前小時)以前的歷史數據查詢聚合好的數據
方案難點:
明細數據和聚合數據數據結構不一樣,如果寫兩份代碼的話,開發任務量比較大
解決方法:
統一數據結構 :給明細數據加2個字段,ct:1,數據條數 ,isDt : 1 ,是不是明細數
- 改造前數據:
time | network | waybillId | isDt | ct |
2019/12/9 11:00:09 | Anetwork | XXXXX | 無 | 無 |
2019/12/8 11:00:09 | Anetwork | YYYYY | 無 | 無 |
- 改造後數據:
time | network | waybillId | isDt | ct |
2019/12/9 11:00:09 | Anetwork | XXXXX | 1 | 1 |
2019/12/8 11:00:09 | Anetwork | YYYYY | 1 | 1 |
2019/12/8 00:00:00 | Anetwork | 0 | 1 |
數據結構改造以後的sql翻譯:
select date(input_time) day,network,sum(ct) waybillCout from waybillgroup by date(input_time) ,network
where (isDt =1 and input_time >='today ' ) --今天(當前小時)的數據使用明細數據聚合
or (isDt =0 and input_time <'today ' ) -- 今天(當前小時)以前的歷史數據查詢聚合好的數據