人力家:藉助 Information Schema 合理治理費用

業務簡介

人力家是由阿里釘釘和人力窩共同投資成立,幫助客戶進入人力資源數字化,依靠產品技術創新驅動戰略的互聯網公司。公司主要提供包括人事管理、薪酬管理、社保管理、增值服務在內的人力資源SaaS服務,加速對人力資源領域賦能,實現人力資源新工作方式。目前已服務電子商務、零售服務等領域的多行業客戶。

人力家是一家典型的創業公司,目前處於一個競爭激烈的市場環境中,公司具有多產品性質,每個產品的數據具有獨立性,同時爲了配合內部CRM數據需求,更好地把數據整合,對於數倉團隊來說是一個不小的挑戰,對於數倉團隊要求的是穩,準,及時響應。需要數倉團隊既要滿足內部的數據需求,也需要在計算的成本上實現優化。

業務痛點

MaxCompute作爲一款優秀的大數據產品,其不僅可以高性價比分析處理海量數據,同時MaxCompute支持開發接口和生態,爲數據、應用遷移、二次開發提供靈活性。QuickBI可以直連MaxCompute產出報表數據供公司內部分析、統計、決策。因爲公司開通的MaxCompute是按量付費規格,所以計算任務和QuickBI 報表每次不同的查詢都會耗費計算資源導致MaxCompute計算費用增加,在過去的一段時間,MaxCompute每個月的成本波動較大,不符合期望值,且不能有效、及時的發現一些高成本sql和多頻訪問報表數據集。

具體原因分析

分析 MaxCompute 賬單發現費用波動是因爲大計算任務和QuickBI報表數據集的自定義sql,主要爲以下五點。

1、單SQL查詢費用較高

MaxCompute計算和部分QuickBI報表按照時間維度來進行查詢數據,但是有些時間查詢跨度較大,或者基表數據量大從而形成一條大查詢sql。

2、分區不合理

部分MaxCompute計算邏輯和報表數據集設置不合理,有些查詢是直接查詢近3年分區的數據, 造成計算成本費用增加。

3、報表訪問頻率高,篩選項不同

部分QuickBI報表的數據集成本其實很低,但是每天訪問的次數確實很大,由於重複執行造成MaxCompute計算作業量增加,從而導致計算費用增加。

4、兼容報表增加維表數據

部分報表數據集爲了兼容數據產出,需要增加部分維表數據來進行關聯,但有些維表數據集其實很大,最後也會形成一條大查詢sql。

5、運行時間較長

MaxCompute部分計算sql和QuickBI報表數據集計算時間較長,影響整體業務運行時間和報表數據產出。

基於Information Schema分析項目作業

MaxCompute元數據服務Information Schema提供了項目元數據及使用歷史數據等信息。在ANSI SQL-92的Information Schema基礎上,添加了面向MaxCompute服務特有的字段及視圖。

租戶級別Information Schema是原項目級別Information Schema的升級版,是在每個阿里雲賬號下創建名爲SYSTEM_CATALOG的項目,並內置Information Schema,通過訪問該內置Schema提供的只讀視圖,查詢當前用戶所有項目的元數據信息以及使用歷史信息。元數據視圖列表如下

對於以上部分視圖元數據信息,我們更關心的是Information_Schema.TASKS_HISTORY表中每日任務計算的時間、成本和次數。

分析SQL腳本

這裏我們使用的是租戶級別的 Information Schema,相比於項目級別的 Information Schema,租戶級別的只需要創建一個計算節點就可以計算所有 project 的任務,而項目級別的 Information Schema 每個 project 都需要一個計算節點,這裏更推薦租戶級別的 Information Schema。

set odps.namespace.schema=true;
set odps.sql.decimal.odps2=true;

create table if not exists ads_project_cost_pay_di
(
    env_type  string comment '環境類型'
    ,cost_type string comment '消費類型'
    ,inst_id string comment  '唯一id,作業id'
    ,owner_name string comment  '作業所屬人'
    ,task_type string  comment  '作業類型  SQL:SQL作業 CUPID:Spark或Mars作業 SQLCost:SQL預估作業 SQLRT:查詢加速SQL作業 LOT:MapReduce作業 PS:PAI的Parameter Server AlgoTask:機器學習作業'
    ,input_records string comment  '作業輸入的records數目'
    ,output_records string comment '作業輸出的records數目'
    ,input_bytes string comment '實際掃描的數據量,與Logview相同。'
    ,output_bytes string comment '輸出字節數。'
    ,status string comment '數據採集瞬間的運行狀態(非實時狀態)。包含以下狀態:Terminated:作業已執行結束。Failed:作業失敗。 Cancelled:作業被取消。'
    ,cost_pay DECIMAL(18,5) comment '費用 單位元'
    ,complexity string  comment  '任務複雜度'
    ,settings string comment '上層調度或用戶傳入的信息,以JSON格式存儲。包含字段:USERAGENT、BIZID、SKYNET_ID和SKYNET_NODENAME。'
    ,sql_script string comment 'sql 代碼'
    ,start_time string comment '開始時間'
    ,end_time string comment '結束時間'
        ,data_collection string comment  'quickbi數據集'
)
comment 'odps 費用 明細'
partitioned by (ds string comment '分區')
;

insert overwrite table ads_project_cost_pay_di partition(ds=${bizdate})
select  case when task_catalog = 'renlijia_ng' then '生產' 
             when task_catalog = 'renlijia_ng_dev' then '測試'
             else  task_catalog
         end as   env_type
        ,if(regexp_count(settings,'quickbi')>0,'quickbi',task_catalog)cost_type
        ,inst_id
        ,owner_name
        ,task_type
        ,input_records
        ,output_records
        ,input_bytes
        ,output_bytes
        ,status
        ,nvl(case   when task_type = 'SQL' then cast(input_bytes/1024/1024/1024 * complexity * 0.3 as DECIMAL(18,5) )
                    when task_type = 'SQLRT' then cast(input_bytes/1024/1024/1024 * complexity * 0.3 as DECIMAL(18,5) )
                    when task_type = 'CUPID' and status='Terminated'then cast(cost_cpu/100/3600 * 0.66 as DECIMAL(18,5) ) 
                    else 0 
        end,0) cost_pay
        ,complexity 
        ,settings
        ,operation_text sql_script
        ,start_time
        ,end_time
        ,regexp_extract(operation_text,'(?<=quickbi=).*?(?==quickbi)',0)data_collection
from  SYSTEM_CATALOG.INFORMATION_SCHEMA.TASKS_HISTORY where ds=${bizdate};

注:sql成本計算公式(官方示例):

case   
when task_type = 'SQL' then cast(input_bytes/1024/1024/1024 * complexity * 0.3 as DECIMAL(18,5) )
when task_type = 'SQLRT' then cast(input_bytes/1024/1024/1024 * complexity * 0.3 as DECIMAL(18,5) )
when task_type = 'CUPID' and status='Terminated'then cast(cost_cpu/100/3600 * 0.66 as DECIMAL(18,5) ) 
else 0 
end;

治理前後MaxCompute整體成本對比

報表產出明細數據

因爲公司是按量付費的MaxCompute,所有我們主要關心的是成本問題和報表的訪問情況。對此我們主要從環境、數據集、用戶等維度進行分析。

QuickBI數據集(查ads_project_cost_pay_di表)

QuickBI報表Demo

QuickBI數據集字段是從sql-script中正則匹配出來,且QuickBI數據集需要單獨增加一個字段用來抽取數據集名。

1、手動在QuickBI數據集增加如下字段:

‘quickbi=xxx數據集=quickbi’ as 數據集自定義字段

2、利用MaxCompute函數regexp_extract按照如下方式正則匹配:

regexp_extract(operation_text,'(?<=quickbi=).*?(?==quickbi)',0)

分析改進項:

1、替換分區不合理數據表或數據集。

2、維表數據在上層加工,下層減少依賴項,做到最好只查一張表。

3、高頻訪問數據集優化存儲大小和QuickBI 報表儀表盤數量。

4、減少報表產出時間。

綜上:藉助MaxCompute 租戶級別Information Schema,拉取每日曆史作業信息,公司成功把每日MaxCompute成本降低到合理波動區間。

作者:石玉陽 人力家 高級數據研發工程師

點擊立即免費試用雲產品 開啓雲上實踐之旅!

原文鏈接

本文爲阿里雲原創內容,未經允許不得轉載。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章