MaxCompute表設計最佳實踐

MaxCompute表設計最佳實踐

產生大量小文件的操做

MaxCompute表的小文件會影響存儲和計算性能,所以咱們先介紹下什麼樣的操做會產生大量小文件,從 而在作表設計的時候考慮避開此類操做。數據庫

  • 使用MaxCompute Tunnel SDK上傳數據,上傳過程當中,每commit一次就會產生一個文件。這時每 個文件太小(好比幾K),而且頻繁上傳(好比5秒上傳)一次,則一小時就會產生720個小文件,一 天就會產生17280個小文件。
  • 使用MaxCompute Tunnel SDK上傳數據,create了session可是沒有upload數據直接作了 commit,產生大量空目錄(服務側等同於小文件)。
  • 使用MaxCompute Console命令行工具Tunnel命令上傳時,將本地大文件切分太小,致使上傳後產 生文件數過多,文件太小。
  • 經過DataHub作數據歸檔,Datahub 的每一個shard寫 MaxCompute 有兩個條件:數據總量達到 64MB,commit 一次到 MaxCompute,造成一個文件。或者每隔 5 分鐘一次 commit,造成一個 文件。那麼:開的shard數多(好比20個shard),每一個shard數據在5分鐘內都遠遠達不到64M,比 如就是幾百K,就會產生大量小文件。那麼一天就會產生241220=5760個小文件。
  • 經過Dataworks等數據開發工具進行數據增量插入(insert into)到MaxCompute的表(或者表分 區)裏時,每一個insert into都會產生一個文件,若每次insert into 10條,天天累計insert insert 10000條記錄,則會產生1000個小文件。
  • 經過阿里雲DTS將數據從RDS等數據庫同步到MaxCompute,DTS進行數據同步時,會建立全量表和 增量表,增量表進程數據插入過程當中會由於每次數據插入條數較少而commit比較完整一次數據同步, 從而在增量表中形成小文件問題,好比每隔5分支執行一次同步,每次同步的數據量爲10條,一天內的 增量爲10000條,則會產生1000個小文件。此種場景,須要在數據同步完成後進行全量極限表和增量 數據表的merge。
  • 源數據採集客戶端太多,源數據經過T unnel直接進入到一個分區,每一個源數據採集客戶端提交一次數 據,都會在同一分區下產生一個獨立的文件致使產生大量小文件。
  • SLS 觸發 FunctionCompute持續高頻往MaxCompute中心接入文件,小文件流式數據進入 MaxCompute。

根據數據劃分項目空間

項目空間(Project)是MaxCompute最高層的對象,按項目空間進行資源的分配、隔離和管理,實現了 多租戶的管理能力。session

  • 若是多個應用須要共享「數據」,則推薦使用同一個項目空間。
  • 若是多個應用所需「數據」是無關的,則推薦使用不一樣的項目空間。 項目空間間的表和分區能夠經過Package受權的方式進行交換。

「維度表」設計的最佳實踐:

通常狀況下描述屬性的表設計爲維度表。維度表能夠和任意表組的任意表進行關聯,而且建立時不須要配 置分區信息,可是對單表數據量大小有所限制。維度表的設計和使用注意如下幾點:工具

  • 通常要求維度表單表不超過1000萬。
  • 維度表的數據不該該被大量更新。
  • 維度表和其餘表進行Join操做時可使用mapjoin。

拉鍊表設計 – 極限存儲的應用

極限存儲功能待發布,在此介紹主要提供設計思想。 基於MaxCompute的拉鍊表設計背景 在數據倉庫的數據模型設計過程當中,常常會遇到這樣的需求:性能

  • 數據量比較大。 表中的部分字段會被update,如用戶的地址,產品的描述信息,訂單的狀態、手機號碼等等。
  • 須要查看某一個時間點或者時間段的歷史快照信息。(好比,查看某一個訂單在歷史某一個時間點的 狀態,好比,查看某一個用戶在過去某一段時間內,更新過幾回等等)
  • 變化的比例和頻率不是很大,好比,總共有1000萬的會員,天天新增和發生變化的有10萬左右,若是表天天都保留一份全量,那麼每次全量中會保存不少不變的信息,對存儲是極大的浪費。 
    考慮極限存儲的使用: MaxCompute提供了將不一樣錶轉化爲極限存儲表的能力。極限存儲操做示例以下:
  1. 建立源表。
create table src_tbl (key0 STRING, key1 STRING, col0 STRING, col1 STRING, col2 STRING) PARTITIO N (datestam p_x STRING, pt0 STRING);
  1. 導入數據。
  2. 將src_tbl轉變爲極限存儲的表。
set odps.exstore.primarykey=key0,key1;
[set odps.exstore.ignorekey=col0;]
EXSTO RE exstore_tbl PARTITIO N (datestam p_x='20140801'); EXSTO RE exstore_tbl PARTITIO N (datestam p_x='20140802');

拉鍊表設計更詳細介紹能夠參考雲棲文章:https://yq.aliyun.com/articles/542146#? spm=a2c41.11181499.0.0開發工具

採集源表的設計

數據採集方式:流式數據寫入, 批量數據寫入,週期調度條式數據插入。 
大數據量狀況下,確保同一個業務單元的數據使用分區和表進行分;在數據量較小狀況下,優化採集頻率。大數據

  • 流式數據寫入。優化

    • 對於流式寫入的數據,通常採集的通道較多,相關採集通道應作有效區分,在單個數據通道寫入 量較大的狀況下應該進行按照時間進行分區設計。
    • 在採集通道數據量較小的狀況下能夠採起非分區表設計,對終端類型和採集時間設計成標準列字 段。
    • 採用Datahub進行數據寫入時應該合理規劃shard數量,放置因爲shard過多而形成採集通道流量 較小且通道較多的問題。
  • 批量數據寫入。批量數據寫入重點關注寫入週期 週期調度條式數據插入。
  • 避免週期數據插入,此種狀況下須要創建分區表,在新分區進行插入操做, 減小對於原來分區影響。

日誌表的設計

日誌實際上是個流水錶,不涉及記錄的更新,來一條採集一條,多條一塊兒存放,日誌表設計的主要注意幾 點:阿里雲

create table src_tbl (key0 STRING, key1 STRING, col0 STRING, col1 STRING, col2 STRING) PARTITIO N (datestam p_x STRING, pt0 STRING);
  set odps.exstore.primarykey=key0,key1;
[set odps.exstore.ignorekey=col0;]
EXSTO RE exstore_tbl PARTITIO N (datestam p_x='20140801'); EXSTO RE exstore_tbl PARTITIO N (datestam p_x='20140802');
  • 考慮是否須要對日誌進行去重處理。
  • 考慮是否須要擴展維度屬性。spa

    • 是否須要關聯維表擴展維度屬性字段考慮兩點:業務使用的頻次,關聯是否會形成的產出的延 遲。
    • 須要仔細選擇是否對於維度表進行擴展
  • 考慮區分終端類型。命令行

    • 日誌表因爲量大,考慮在業務分析使用時一般會按PC端,APP端來統計分析,同時PC端、APP端 的採集是兩套體系,所以一般的作法會按終端設計多個明細DWD表。
    • 若是終端較多,但數據量不大的狀況下,如一個終端的數據小於1T 可是採集次數較多,能夠考慮 不對終端進行分區,而設置終端信息爲普通列。

注意:

  • 對於日誌表進行分區設計,能夠按照日誌採集的時間按照天進行分區,在入數據前進行數據採集整 合,一批數據寫入提交一次(一般是64M)。
  • 日誌數據不多有對原來分區的更新操做,能夠採用insert 進行少許數據的插入,但通常須要限制插入 次數。
  • 若是有大量的更新的操做,須要採用insert overwrite操做避免小文件問題。
  • 對日誌表設置合理的分區和對已經⻓久不訪問的冷熱數據配置歸檔操做。

互動明細表的設計

週期快照表,天天對收藏的全部記錄進行快照存放。 
問題:歷史累計的記錄很是多,天天生成快照要拿當天增量表與前一天的全量表merge,很是耗資源。統 計最近1天的新增收藏數,須要掃描全量表,如何下降資源? 
建議的方案:創建一個事務性事實表,在創建一個存放當前有效收藏的週期快照表,以知足各類不一樣業務 的統計分析須要。
注意:

  • 設計互動明細表最重要的是要區分存量數據和增量數據之間的關係。 - 對於新分區的數據能夠寫入,做爲增量數據。
  • 應儘可能減小對於老的分區數據的修改和插入。
  • 在數據插入和全表覆蓋寫種選擇時應儘可能選用insert overwrite而並選擇insert into。

MaxCompute表數據更新與刪除操做

關係型數據庫支持的 delete/update/merge SQL ,在MaxCompute上的實現方式示例以下: 
表準備

-- 上日全量表
table1(key1 string,key2 string,col1 string,col2 string);
-- 今日增量表
table2(key1 string,key2 string,col1 string,col2 string);
​-- 今日增量表(刪除)
table3(key1 string,key2 string,col1 string,col2 string);

update(table2 表中的記錄的值,更新到table1表中)

insert overwrite table table1 select t1.key1
,t1.key2
,case when t2.key1 is not null then t2.col1 else t1.col1 end as col1 ,case when t2.key1 is not null then t2.col2 else t1.col2 end as col2
from table1 t1
left outer join table2 t2 on t1.key1=t2.key1 and t1.key2 = t2.key2 ;

delete(table2 表中的記錄,從table1表中刪除)

insert overwrite table table1 select t1.key1
,t1.key2 ,t1.col1 ,t1.col2
from table1 t1
left outer join table2 t2 on t1.key1=t2.key1 and t1.key2 = t2.key2 where t2.key1 is null
;

merge(沒有del)

insert overwrite table table1 select
from (
-- 先把上日存在,今日也存在的記錄從上日表中排除。剩下的就是今日沒有更新的記錄 select t1.key1
,t1.key2 ,t1.col1 ,t1.col2
from table1 t1
left outer join table2 t2 on t1.key1=t2.key1 and t1.key2 = t2.key2 where t2.key1 is null
union all
-- 再合併上今日增量,就是今天的全量 select t2.key1
select t2.key1
  ,t2.key2
  ,t2.col1
  ,t2.col2
from table2 t2)tt
;

merge(有del)
insert overwrite table table1 select
from (
-- 先把上日存在,今日也存在的記錄從上日表中排除,再把今日刪除的記錄排除。剩下的就是今日沒有更 新的記錄

insert overwrite table table1 select
from (
-- 先把上日存在,今日也存在的記錄從上日表中排除,再把今日刪除的記錄排除。剩下的就是今日沒有更 新的記錄
select t1.key1
,t1.key2 ,t1.col1 ,t1.col2
from table1 t1
left outer join table2 t2 on t1.key1=t2.key1 and t1.key2 = t2.key2 left outer join table3 t3 on t1.key1=t3.key1 and t1.key2 = t3.key2
where t2.key1 is null or t2.key1 is null
union all
-- 再合併上今日增量,就是今天的全量 select t2.key1
,t2.key2 ,t2.col1 ,t2.col2
from table2 t2)tt ;

表建立設計示例

場景:天氣狀況信息採集。

  • 基本信息: 數據信息包括地名,關於此地的屬性數如面積,基本人口數量等信息,天氣信息。
  • 屬性數據變化較小,天氣信息數採用多個終端採集,且數據量較大
  • 天氣信息變化較大,終端數量穩定的狀況下流量基本穩定。
    表設計指南:
  • 建議對數據信息劃分爲基本屬性表,和天氣日誌表,區分變化小和變化大的數據。
  • 由於數據量巨大,對天氣日誌表按照地域進行分區,也能夠按照時間如天進行二級分區,此種分區方 式避免因某一地或某一個時間的天氣變化而形成其餘無關數據變化。
  • 採集終端上使用datahub進行數據匯聚,依據穩定的流量值選擇合適的shard通道數量,批量數據方式 寫入到天氣日誌表中,不使用Insert into。

MaxCompute表的特點功能

生命週期

MaxCompute表/分區提供數據生命週期管理。表(分區)數據從最後一次更新時間算起,在通過指定的 時間後沒有變更,則此表(分區)將被MaxCompute自動回收。這個指定的時間就是生命週期,生命週期 設置爲表級別。

create table test_lifecycle(key string) lifecycle 100;/alter table test_l ifecycle set lifecycle 50;

MaxCompute會根據每張非分區表或者分區的的LastDataModifiedTime以及lifecycle的設置來判斷是 否要回收此非分區表或者分區表中的分區。 MaxCompute SQL提供touch操做用來修改分區的 LastDataModifiedTime。會將分區的LastDataModifiedTime修改成當前時間。修改 LastDataModifiedTime的值,MaxCompute會認爲表或分區的數據有變更,生命週期的計算會從新開始。

ALTER TABLE table_nam e TO UCH PARTITIO N(partition_col='partition_col_valu e', ...);

注意:

  • 合理規劃表的生命週期,在建立表時即設置生命週期,可有效減小存儲壓力。
  • 對錶數據的任何變更都會影響生命週期回收數據的判斷時間,包括小文件合併。

避免全表掃描

表設計:

  • 創建分區表或者對掃描條件進行列設計。
  • 對數據表進行合理分區。 對經常使用查詢條件設置成列名。
  • 讀經常使用查詢條件進行hash clustering
    數據計算:
  • 加分區過濾條件,或者減小掃描分區數,或者拆出中間小表而後再掃描小錶的歷史分區以減小數據掃描 量。
  • 把全局掃描表中間結果進行存儲造成中間表。
  • 若是天天都去掃一年的分區,計算消耗是很是大的,建議拆出一張中間表,天天作一次彙總,而後再 去掃描這張中間表的一年分區,掃描數據量會減小不少。

避免小文件

  • Reduce計算過程產生的小文件:只須要insert overwrite源表(或分區)便可,或者寫入到新表刪除 源表。
  • Tunnel數據採集過程當中產生的小文件建議:

    • 調用tunnelsdk時當buffer達到64M時提交一次;
    • 使用console時避免頻繁上傳小文件,建議積累較大時一次性上傳; 若是導入的是分區表,建議給分區設置生命週期,過時不用的數據自動清理;
    • 同第一種方案,insertoverwrite源表(或分區);
    • ALTER合併模式,經過console命令進行合併。
  • 使用臨時表建議建立時都加上生命週期,到期後垃圾回收自動回收。 - 申請過多的datahub shard將會產生小文件問題,申請datahub shard數目的策略 :

    • 默認吞吐量單個shard是1MB/s,能夠按照這個分配實際的shard數目(能夠在此基礎上多加幾 個);
    • 同步odps的邏輯是每一個shard有一個單獨的task(知足5分鐘或者64MB會commit一次),默認設置5分鐘是爲了儘快能在odps查到數據。若是是按照小時建partition,那個一個shard每一個小 時有12個文件。
    • 若是這個時候數據量不多,可是shard不少,在odps裏面就會不少小文件(shard*12/hour)。
    • 不要過多的分配shard,按需分配。

轉化Hash Clustering表

Hash Clustering表的優點:優化Bucket Pruning/優化Aggregation/優化存儲。 在建立表時使用CLUSTERED BY指定Hash Key,MaxCompute將對指定列進行Hash運算,按照Hash 值分散到各個Bucket裏面。
Hash Key指選擇原則:

  • 選擇重複鍵值少的列
  • SORTED BY用於指定在Bucket內字段的排序方式。
    如何轉化爲HashClustering表:
ALTER TABLE table_nam e [CLUSTERED BY (col_nam e [, col_nam e, ...]) [SO RTED B Y (col_nam e [ASC | DESC] [, col_nam e [ASC | DESC] ...])] INTO num ber_of_buck ets BUCKETS]

ALTER TABLE語句適用於存量表,在增長了新的彙集屬性以後,新的分區將作hash cluster存儲。 建立 完HashClustering的表以後使用insert overwrite從另一個源表進行轉化。
注意,Hash Clustering表有如下限制:

  • 不支持insert into,只能經過insert overwrite來添加數據。
  • 不支持tunnel直接upload到range cluster表,由於tunnel上傳數據是無序的。

原文連接 

相關文章
相關標籤/搜索