2023版最新最強大資料面試寶典

帶你聊技術發表於2023-02-16

此套面試題來自於各大廠的真實面試題及常問的知識點,如果能理解吃透這些問題,你的大資料能力將會大大提升,進入大廠指日可待!

複習大資料面試題,看這一套就夠了!

前言

此版本面試題相較於之前增加了很多數倉以及演算法相關的題,同時新增了資料湖,必備SQL題,Clickhouse,Doris,大資料演算法設計等面試題。

版本更新如下:

版本時間描述
V1.02020-12-18建立
V1.22021-01-17新增:spark 面試題
V1.32021-01-18新增:kafka 面試題
V1.42021-01-20新增:hbase 面試題
V1.52021-01-30新增:flink 面試題
V3.02022-01-10新增:資料倉儲,演算法等面試題
修復:部分答案不完整或有誤
V4.0(此版本)2023-02-12更新:資料倉儲及演算法;
新增:資料湖,必備SQL題,Clickhouse,Doris,大資料演算法設計題

本文目錄:

一、Hadoop
二、Hive
三、Spark
四、Kafka
五、HBase
六、Flink
七、Clickhouse
八、Doris
九、資料倉儲
九、資料湖
九、必備SQL題
八、必備演算法
九、大資料演算法設計題

Hadoop

Hadoop中常問的就三塊,第一:分散式儲存(HDFS);第二:分散式計算框架(MapReduce);第三:資源排程框架(YARN)。

1. 請說下HDFS讀寫流程

這個問題雖然見過無數次,面試官問過無數次,還是有不少面試者不能完整的說出來,所以請務必記住。並且很多問題都是從HDFS讀寫流程中引申出來的。

HDFS寫流程

  1. Client客戶端傳送上傳請求,透過RPC與NameNode建立通訊,NameNode檢查該使用者是否有上傳許可權,以及上傳的檔案是否在HDFS對應的目錄下重名,如果這兩者有任意一個不滿足,則直接報錯,如果兩者都滿足,則返回給客戶端一個可以上傳的資訊;

  2. Client根據檔案的大小進行切分,預設128M一塊,切分完成之後給NameNode傳送請求第一個block塊上傳到哪些伺服器上;

  3. NameNode收到請求之後,根據網路拓撲和機架感知以及副本機制進行檔案分配,返回可用的DataNode的地址;

注:Hadoop在設計時考慮到資料的安全與高效, 資料檔案預設在HDFS上存放三份, 儲存策略為本地一份,同機架內其它某一節點上一份, 不同機架的某一節點上一份

  1. 客戶端收到地址之後與伺服器地址列表中的一個節點如A進行通訊,本質上就是RPC呼叫,建立pipeline,A收到請求後會繼續呼叫B,B在呼叫C,將整個pipeline建立完成,逐級返回Client;

  2. Client開始向A上傳送第一個block(先從磁碟讀取資料然後放到本地記憶體快取),以packet(資料包,64kb)為單位,A收到一個packet就會傳送給B,然後B傳送給C,A每傳完一個packet就會放入一個應答佇列等待應答

  3. 資料被分割成一個個的packet資料包在pipeline上依次傳輸,在pipeline反向傳輸中,逐個傳送ack(命令正確應答),最終由pipeline中第一個DataNode節點A將pipelineack傳送給Client;

  4. 當一個block傳輸完成之後, Client再次請求NameNode上傳第二個block,NameNode重新選擇三臺DataNode給Client。

HDFS讀流程

  1. Client向NameNode傳送RPC請求。請求檔案block的位置;

  2. NameNode收到請求之後會檢查使用者許可權以及是否有這個檔案,如果都符合,則會視情況返回部分或全部的block列表,對於每個block,NameNode都會返回含有該block副本的DataNode地址;這些返回的DataNode地址,會按照叢集拓撲結構得出DataNode與客戶端的距離,然後進行排序,排序兩個規則:網路拓撲結構中距離 Client 近的排靠前;心跳機制中超時彙報的DataNode狀態為STALE,這樣的排靠後;

  3. Client選取排序靠前的DataNode來讀取block,如果客戶端本身就是DataNode,那麼將從本地直接獲取資料(短路讀取特性);

  4. 底層上本質是建立Socket Stream(FSDataInputStream),重複的呼叫父類DataInputStream的read方法,直到這個塊上的資料讀取完畢;

  5. 當讀完列表的block後,若檔案讀取還沒有結束,客戶端會繼續向NameNode 獲取下一批的block列表;

  6. 讀取完一個block都會進行checksum驗證,如果讀取DataNode時出現錯誤,客戶端會通知NameNode,然後再從下一個擁有該block副本的DataNode 繼續讀;

  7. read方法是並行的讀取block資訊,不是一塊一塊的讀取;NameNode只是返回Client請求包含塊的DataNode地址,並不是返回請求塊的資料

  8. 最終讀取來所有的block會合併成一個完整的最終檔案;

2. HDFS在讀取檔案的時候,如果其中一個塊突然損壞了怎麼辦

客戶端讀取完DataNode上的塊之後會進行checksum驗證,也就是把客戶端讀取到本地的塊與HDFS上的原始塊進行校驗,如果發現校驗結果不一致,客戶端會通知NameNode,然後再從下一個擁有該block副本的DataNode繼續讀

3. HDFS在上傳檔案的時候,如果其中一個DataNode突然掛掉了怎麼辦

客戶端上傳檔案時與DataNode建立pipeline管道,管道的正方向是客戶端向DataNode傳送的資料包,管道反向是DataNode向客戶端傳送ack確認,也就是正確接收到資料包之後傳送一個已確認接收到的應答。

當DataNode突然掛掉了,客戶端接收不到這個DataNode傳送的ack確認,客戶端會通知NameNode,NameNode檢查該塊的副本與規定的不符,NameNode會通知DataNode去複製副本,並將掛掉的DataNode作下線處理,不再讓它參與檔案上傳與下載。

4. NameNode在啟動的時候會做哪些操作

NameNode資料儲存在記憶體和本地磁碟,本地磁碟資料儲存在fsimage映象檔案和edits編輯日誌檔案

首次啟動NameNode

  1. 格式化檔案系統,為了生成fsimage映象檔案

  2. 啟動NameNode:

  • 讀取fsimage檔案,將檔案內容載入進記憶體
  • 等待DataNade註冊與傳送block report
  • 啟動DataNode:

    • 向NameNode註冊
    • 傳送block report
    • 檢查fsimage中記錄的塊的數量和block report中的塊的總數是否相同
  • 對檔案系統進行操作(建立目錄,上傳檔案,刪除檔案等):

    • 此時記憶體中已經有檔案系統改變的資訊,但是磁碟中沒有檔案系統改變的資訊,此時會將這些改變資訊寫入edits檔案中,edits檔案中儲存的是檔案系統後設資料改變的資訊。

    第二次啟動NameNode

    1. 讀取fsimage和edits檔案;

    2. 將fsimage和edits檔案合併成新的fsimage檔案;

    3. 建立新的edits檔案,內容開始為空;

    4. 啟動DataNode。

    5. Secondary NameNode瞭解嗎,它的工作機制是怎樣的

    Secondary NameNode是合併NameNode的edit logs到fsimage檔案中;

    它的具體工作機制:

    1. Secondary NameNode詢問NameNode是否需要checkpoint。直接帶回NameNode是否檢查結果;

    2. Secondary NameNode請求執行checkpoint;

    3. NameNode滾動正在寫的edits日誌;

    4. 將滾動前的編輯日誌和映象檔案複製到Secondary NameNode;

    5. Secondary NameNode載入編輯日誌和映象檔案到記憶體,併合並;

    6. 生成新的映象檔案fsimage.chkpoint;

    7. 複製fsimage.chkpoint到NameNode;

    8. NameNode將fsimage.chkpoint重新命名成fsimage;

    所以如果NameNode中的後設資料丟失,是可以從Secondary NameNode恢復一部分後設資料資訊的,但不是全部,因為NameNode正在寫的edits日誌還沒有複製到Secondary NameNode,這部分恢復不了。

    6. Secondary NameNode不能恢復NameNode的全部資料,那如何保證NameNode資料儲存安全

    這個問題就要說NameNode的高可用了,即 NameNode HA

    一個NameNode有單點故障的問題,那就配置雙NameNode,配置有兩個關鍵點,一是必須要保證這兩個NameNode的後設資料資訊必須要同步的,二是一個NameNode掛掉之後另一個要立馬補上。

    1. 後設資料資訊同步在 HA 方案中採用的是“共享儲存”。每次寫檔案時,需要將日誌同步寫入共享儲存,這個步驟成功才能認定寫檔案成功。然後備份節點定期從共享儲存同步日誌,以便進行主備切換。

    2. 監控NameNode狀態採用zookeeper,兩個NameNode節點的狀態存放在zookeeper中,另外兩個NameNode節點分別有一個程式監控程式,實施讀取zookeeper中有NameNode的狀態,來判斷當前的NameNode是不是已經down機。如果Standby的NameNode節點的ZKFC發現主節點已經掛掉,那麼就會強制給原本的Active NameNode節點傳送強制關閉請求,之後將備用的NameNode設定為Active。

    如果面試官再問HA中的 共享儲存 是怎麼實現的知道嗎?
    可以進行解釋下:NameNode 共享儲存方案有很多,比如Linux HA, VMware FT, QJM等,目前社群已經把由Clouderea公司實現的基於QJM(Quorum Journal Manager)的方案合併到HDFS的trunk之中並且作為預設的共享儲存實現。
    基於QJM的共享儲存系統主要用於儲存EditLog,並不儲存FSImage檔案。FSImage檔案還是在NameNode的本地磁碟上。
    QJM共享儲存的基本思想來自於Paxos演算法,採用多個稱為JournalNode的節點組成的JournalNode叢集來儲存EditLog。每個JournalNode儲存同樣的EditLog副本。每次NameNode寫EditLog的時候,除了向本地磁碟寫入 EditLog 之外,也會並行地向JournalNode叢集之中的每一個JournalNode傳送寫請求,只要大多數的JournalNode節點返回成功就認為向JournalNode叢集寫入EditLog成功。如果有2N+1臺JournalNode,那麼根據大多數的原則,最多可以容忍有N臺JournalNode節點掛掉。

    7. 在NameNode HA中,會出現腦裂問題嗎?怎麼解決腦裂

    假設 NameNode1 當前為 Active 狀態,NameNode2 當前為 Standby 狀態。如果某一時刻 NameNode1 對應的 ZKFailoverController 程式發生了“假死”現象,那麼 Zookeeper 服務端會認為 NameNode1 掛掉了,根據前面的主備切換邏輯,NameNode2 會替代 NameNode1 進入 Active 狀態。但是此時 NameNode1 可能仍然處於 Active 狀態正常執行,這樣 NameNode1 和 NameNode2 都處於 Active 狀態,都可以對外提供服務。這種情況稱為腦裂。

    腦裂對於NameNode這類對資料一致性要求非常高的系統來說是災難性的,資料會發生錯亂且無法恢復。zookeeper社群對這種問題的解決方法叫做 fencing,中文翻譯為隔離,也就是想辦法把舊的 Active NameNode 隔離起來,使它不能正常對外提供服務。

    在進行 fencing 的時候,會執行以下的操作:

    1. 首先嚐試呼叫這個舊 Active NameNode 的 HAServiceProtocol RPC 介面的 transitionToStandby 方法,看能不能把它轉換為 Standby 狀態。

    2. 如果 transitionToStandby 方法呼叫失敗,那麼就執行 Hadoop 配置檔案之中預定義的隔離措施,Hadoop 目前主要提供兩種隔離措施,通常會選擇 sshfence:

    • sshfence:透過 SSH 登入到目標機器上,執行命令 fuser 將對應的程式殺死;
    • shellfence:執行一個使用者自定義的 shell 指令碼來將對應的程式隔離。

    8. 小檔案過多會有什麼危害,如何避免

    Hadoop上大量HDFS後設資料資訊儲存在NameNode記憶體中,因此過多的小檔案必定會壓垮NameNode的記憶體。

    每個後設資料物件約佔150byte,所以如果有1千萬個小檔案,每個檔案佔用一個block,則NameNode大約需要2G空間。如果儲存1億個檔案,則NameNode需要20G空間。

    顯而易見的解決這個問題的方法就是合併小檔案,可以選擇在客戶端上傳時執行一定的策略先合併,或者是使用Hadoop的CombineFileInputFormat\<K,V\>實現小檔案的合併。

    9. 請說下HDFS的組織架構

    1. Client:客戶端

    • 切分檔案。檔案上傳HDFS的時候,Client將檔案切分成一個一個的Block,然後進行儲存

    • 與NameNode互動,獲取檔案的位置資訊

    • 與DataNode互動,讀取或者寫入資料

    • Client提供一些命令來管理HDFS,比如啟動關閉HDFS、訪問HDFS目錄及內容等

  • NameNode:名稱節點,也稱主節點,儲存資料的後設資料資訊,不儲存具體的資料

    • 管理HDFS的名稱空間

    • 管理資料塊(Block)對映資訊

    • 配置副本策略

    • 處理客戶端讀寫請求

  • DataNode:資料節點,也稱從節點。NameNode下達命令,DataNode執行實際的操作

    • 儲存實際的資料塊

    • 執行資料塊的讀/寫操作

  • Secondary NameNode:並非NameNode的熱備。當NameNode掛掉的時候,它並不能馬上替換NameNode並提供服務

    • 輔助NameNode,分擔其工作量

    • 定期合併Fsimage和Edits,並推送給NameNode

    • 在緊急情況下,可輔助恢復NameNode

    10. 請說下MR中Map Task的工作機制

    簡單概述

    inputFile透過split被切割為多個split檔案,透過Record按行讀取內容給map(自己寫的處理邏輯的方法) ,資料被map處理完之後交給OutputCollect收集器,對其結果key進行分割槽(預設使用的hashPartitioner),然後寫入buffer,每個map task 都有一個記憶體緩衝區(環形緩衝區),存放著map的輸出結果,當緩衝區快滿的時候需要將緩衝區的資料以一個臨時檔案的方式溢寫到磁碟,當整個map task 結束後再對磁碟中這個maptask產生的所有臨時檔案做合併,生成最終的正式輸出檔案,然後等待reduce task的拉取。

    詳細步驟

    1. 讀取資料元件 InputFormat (預設 TextInputFormat) 會透過 getSplits 方法對輸入目錄中的檔案進行邏輯切片規劃得到 block,有多少個 block就對應啟動多少個 MapTask。

    2. 將輸入檔案切分為 block 之後,由 RecordReader 物件 (預設是LineRecordReader) 進行讀取,以 \n 作為分隔符, 讀取一行資料, 返回 <key,value>, Key 表示每行首字元偏移值,Value 表示這一行文字內容。

    3. 讀取 block 返回 <key,value>, 進入使用者自己繼承的 Mapper 類中,執行使用者重寫的 map 函式,RecordReader 讀取一行這裡呼叫一次。

    4. Mapper 邏輯結束之後,將 Mapper 的每條結果透過 context.write 進行collect資料收集。在 collect 中,會先對其進行分割槽處理,預設使用 HashPartitioner。

    5. 接下來,會將資料寫入記憶體,記憶體中這片區域叫做環形緩衝區(預設100M),緩衝區的作用是 批次收集 Mapper 結果,減少磁碟 IO 的影響。我們的 Key/Value 對以及 Partition 的結果都會被寫入緩衝區。當然,寫入之前,Key 與 Value 值都會被序列化成位元組陣列

    6. 當環形緩衝區的資料達到溢寫比列(預設0.8),也就是80M時,溢寫執行緒啟動,**需要對這 80MB 空間內的 Key 做排序 (Sort)**。排序是 MapReduce 模型預設的行為,這裡的排序也是對序列化的位元組做的排序。

    7. 合併溢寫檔案,每次溢寫會在磁碟上生成一個臨時檔案 (寫之前判斷是否有 Combiner),如果 Mapper 的輸出結果真的很大,有多次這樣的溢寫發生,磁碟上相應的就會有多個臨時檔案存在。當整個資料處理結束之後開始對磁碟中的臨時檔案進行 Merge 合併,因為最終的檔案只有一個寫入磁碟,並且為這個檔案提供了一個索引檔案,以記錄每個reduce對應資料的偏移量。

    11. 請說下MR中Reduce Task的工作機制

    簡單描述

    Reduce 大致分為 copy、sort、reduce 三個階段,重點在前兩個階段。

    copy 階段包含一個 eventFetcher 來獲取已完成的 map 列表,由 Fetcher 執行緒去 copy 資料,在此過程中會啟動兩個 merge 執行緒,分別為 inMemoryMerger 和 onDiskMerger,分別將記憶體中的資料 merge 到磁碟和將磁碟中的資料進行 merge。待資料 copy 完成之後,copy 階段就完成了。

    開始進行 sort 階段,sort 階段主要是執行 finalMerge 操作,純粹的 sort 階段,完成之後就是 reduce 階段,呼叫使用者定義的 reduce 函式進行處理。

    詳細步驟

    1. Copy階段:簡單地拉取資料。Reduce程式啟動一些資料copy執行緒(Fetcher),透過HTTP方式請求maptask獲取屬於自己的檔案(map task 的分割槽會標識每個map task屬於哪個reduce task ,預設reduce task的標識從0開始)。

    2. Merge階段:在遠端複製資料的同時,ReduceTask啟動了兩個後臺執行緒對記憶體和磁碟上的檔案進行合併,以防止記憶體使用過多或磁碟上檔案過多。

      merge有三種形式:記憶體到記憶體;記憶體到磁碟;磁碟到磁碟。預設情況下第一種形式不啟用。當記憶體中的資料量到達一定閾值,就直接啟動記憶體到磁碟的merge。與map端類似,這也是溢寫的過程,這個過程中如果你設定有Combiner,也是會啟用的,然後在磁碟中生成了眾多的溢寫檔案。記憶體到磁碟的merge方式一直在執行,直到沒有map端的資料時才結束,然後啟動第三種磁碟到磁碟的merge方式生成最終的檔案。

    3. 合併排序:把分散的資料合併成一個大的資料後,還會再對合並後的資料排序。

    4. 對排序後的鍵值對呼叫reduce方法:鍵相等的鍵值對呼叫一次reduce方法,每次呼叫會產生零個或者多個鍵值對,最後把這些輸出的鍵值對寫入到HDFS檔案中。

    12. 請說下MR中Shuffle階段

    shuffle階段分為四個步驟:依次為:分割槽,排序,規約,分組,其中前三個步驟在map階段完成,最後一個步驟在reduce階段完成。

    shuffle 是 Mapreduce 的核心,它分佈在 Mapreduce 的 map 階段和 reduce 階段。一般把從 Map 產生輸出開始到 Reduce 取得資料作為輸入之前的過程稱作 shuffle。

    1. Collect階段:將 MapTask 的結果輸出到預設大小為 100M 的環形緩衝區,儲存的是 key/value,Partition 分割槽資訊等。

    2. Spill階段:當記憶體中的資料量達到一定的閥值的時候,就會將資料寫入本地磁碟,在將資料寫入磁碟之前需要對資料進行一次排序的操作,如果配置了 combiner,還會將有相同分割槽號和 key 的資料進行排序。

    3. MapTask階段的Merge:把所有溢位的臨時檔案進行一次合併操作,以確保一個 MapTask 最終只產生一箇中間資料檔案。

    4. Copy階段:ReduceTask 啟動 Fetcher 執行緒到已經完成 MapTask 的節點上覆制一份屬於自己的資料,這些資料預設會儲存在記憶體的緩衝區中,當記憶體的緩衝區達到一定的閥值的時候,就會將資料寫到磁碟之上。

    5. ReduceTask階段的Merge:在 ReduceTask 遠端複製資料的同時,會在後臺開啟兩個執行緒對記憶體到本地的資料檔案進行合併操作。

    6. Sort階段:在對資料進行合併的同時,會進行排序操作,由於 MapTask 階段已經對資料進行了區域性的排序,ReduceTask 只需保證 Copy 的資料的最終整體有效性即可。

    Shuffle 中的緩衝區大小會影響到 mapreduce 程式的執行效率,原則上說,緩衝區越大,磁碟io的次數越少,執行速度就越快。
    緩衝區的大小可以透過引數調整,  引數:mapreduce.task.io.sort.mb  預設100M

    13. Shuffle階段的資料壓縮機制瞭解嗎

    在shuffle階段,可以看到資料透過大量的複製,從map階段輸出的資料,都要透過網路複製,傳送到reduce階段,這一過程中,涉及到大量的網路IO,如果資料能夠進行壓縮,那麼資料的傳送量就會少得多。

    hadoop當中支援的壓縮演算法:
    gzip、bzip2、LZO、LZ4、Snappy,這幾種壓縮演算法綜合壓縮和解壓縮的速率,谷歌的Snappy是最優的,一般都選擇Snappy壓縮。谷歌出品,必屬精品。

    14. 在寫MR時,什麼情況下可以使用規約

    規約(combiner)是不能夠影響任務的執行結果的區域性彙總,適用於求和類,不適用於求平均值,如果reduce的輸入引數型別和輸出引數的型別是一樣的,則規約的類可以使用reduce類,只需要在驅動類中指明規約的類即可。

    15. YARN叢集的架構和工作原理知道多少

    YARN的基本設計思想是將MapReduce V1中的JobTracker拆分為兩個獨立的服務:ResourceManager和ApplicationMaster。

    ResourceManager負責整個系統的資源管理和分配,ApplicationMaster負責單個應用程式的的管理。

    1. ResourceManager: RM是一個全域性的資源管理器,負責整個系統的資源管理和分配,它主要由兩個部分組成:排程器(Scheduler)和應用程式管理器(Application Manager)。

    排程器根據容量、佇列等限制條件,將系統中的資源分配給正在執行的應用程式,在保證容量、公平性和服務等級的前提下,最佳化叢集資源利用率,讓所有的資源都被充分利用應用程式管理器負責管理整個系統中的所有的應用程式,包括應用程式的提交、與排程器協商資源以啟動ApplicationMaster、監控ApplicationMaster執行狀態並在失敗時重啟它。

    1. ApplicationMaster: 使用者提交的一個應用程式會對應於一個ApplicationMaster,它的主要功能有:

    • 與RM排程器協商以獲得資源,資源以Container表示。

    • 將得到的任務進一步分配給內部的任務。

    • 與NM通訊以啟動/停止任務。

    • 監控所有的內部任務狀態,並在任務執行失敗的時候重新為任務申請資源以重啟任務。

  • NodeManager: NodeManager是每個節點上的資源和工作管理員,一方面,它會定期地向RM彙報本節點上的資源使用情況和各個Container的執行狀態;另一方面,他接收並處理來自AM的Container啟動和停止請求。

  • Container: Container是YARN中的資源抽象,封裝了各種資源。一個應用程式會分配一個Container,這個應用程式只能使用這個Container中描述的資源。不同於MapReduceV1中槽位slot的資源封裝,Container是一個動態資源的劃分單位,更能充分利用資源。

  • 16. YARN的任務提交流程是怎樣的

    當jobclient向YARN提交一個應用程式後,YARN將分兩個階段執行這個應用程式:一是啟動ApplicationMaster;第二個階段是由ApplicationMaster建立應用程式,為它申請資源,監控執行直到結束。 具體步驟如下:

    1. 使用者向YARN提交一個應用程式,並指定ApplicationMaster程式、啟動ApplicationMaster的命令、使用者程式。

    2. RM為這個應用程式分配第一個Container,並與之對應的NM通訊,要求它在這個Container中啟動應用程式ApplicationMaster。

    3. ApplicationMaster向RM註冊,然後拆分為內部各個子任務,為各個內部任務申請資源,並監控這些任務的執行,直到結束。

    4. AM採用輪詢的方式向RM申請和領取資源。

    5. RM為AM分配資源,以Container形式返回。

    6. AM申請到資源後,便與之對應的NM通訊,要求NM啟動任務。

    7. NodeManager為任務設定好執行環境,將任務啟動命令寫到一個指令碼中,並透過執行這個指令碼啟動任務。

    8. 各個任務向AM彙報自己的狀態和進度,以便當任務失敗時可以重啟任務。

    9. 應用程式完成後,ApplicationMaster向ResourceManager登出並關閉自己。

    17. YARN的資源排程三種模型瞭解嗎

    在Yarn中有三種排程器可以選擇:FIFO Scheduler ,Capacity Scheduler,Fair Scheduler。

    Apache版本的hadoop預設使用的是Capacity  Scheduler排程方式。CDH版本的預設使用的是Fair Scheduler排程方式

    FIFO Scheduler(先來先服務):

    FIFO Scheduler把應用按提交的順序排成一個佇列,這是一個先進先出佇列,在進行資源分配的時候,先給佇列中最頭上的應用進行分配資源,待最頭上的應用需求滿足後再給下一個分配,以此類推。

    FIFO Scheduler是最簡單也是最容易理解的排程器,也不需要任何配置,但它並不適用於共享叢集。大的應用可能會佔用所有叢集資源,這就導致其它應用被阻塞,比如有個大任務在執行,佔用了全部的資源,再提交一個小任務,則此小任務會一直被阻塞。

    Capacity Scheduler(能力排程器):

    對於Capacity排程器,有一個專門的佇列用來執行小任務,但是為小任務專門設定一個佇列會預先佔用一定的叢集資源,這就導致大任務的執行時間會落後於使用FIFO排程器時的時間。

    Fair Scheduler(公平排程器):

    在Fair排程器中,我們不需要預先佔用一定的系統資源,Fair排程器會為所有執行的job動態的調整系統資源。

    比如:當第一個大job提交時,只有這一個job在執行,此時它獲得了所有叢集資源;當第二個小任務提交後,Fair排程器會分配一半資源給這個小任務,讓這兩個任務公平的共享叢集資源。

    需要注意的是,在Fair排程器中,從第二個任務提交到獲得資源會有一定的延遲,因為它需要等待第一個任務釋放佔用的Container。小任務執行完成之後也會釋放自己佔用的資源,大任務又獲得了全部的系統資源。最終的效果就是Fair排程器即得到了高的資源利用率又能保證小任務及時完成。

    Hive

    1. Hive內部表和外部表的區別

    未被external修飾的是內部表,被external修飾的為外部表。

    區別

    1. 內部表資料由Hive自身管理,外部表資料由HDFS管理;

    2. 內部表資料儲存的位置是hive.metastore.warehouse.dir(預設:/user/hive/warehouse),外部表資料的儲存位置由自己制定(如果沒有LOCATION,Hive將在HDFS上的/user/hive/warehouse資料夾下以外部表的表名建立一個資料夾,並將屬於這個表的資料存放在這裡);

    3. 刪除內部表會直接刪除後設資料(metadata)及儲存資料;刪除外部表僅僅會刪除後設資料,HDFS上的檔案並不會被刪除

    2. Hive有索引嗎

    Hive支援索引(3.0版本之前),但是Hive的索引與關係型資料庫中的索引並不相同,比如,Hive不支援主鍵或者外來鍵。並且Hive索引提供的功能很有限,效率也並不高,因此Hive索引很少使用。

    • 索引適用的場景:

    適用於不更新的靜態欄位。以免總是重建索引資料。每次建立、更新資料後,都要重建索引以構建索引表。

    • Hive索引的機制如下:

    hive在指定列上建立索引,會產生一張索引表(Hive的一張物理表),裡面的欄位包括:索引列的值、該值對應的HDFS檔案路徑、該值在檔案中的偏移量。

    Hive 0.8版本後引入bitmap索引處理器,這個處理器適用於去重後,值較少的列(例如,某欄位的取值只可能是幾個列舉值) 因為索引是用空間換時間,索引列的取值過多會導致建立bitmap索引表過大。

    注意:Hive中每次有資料時需要及時更新索引,相當於重建一個新表,否則會影響資料查詢的效率和準確性,Hive官方文件已經明確表示Hive的索引不推薦被使用,在新版本的Hive中已經被廢棄了

    擴充套件:Hive是在0.7版本之後支援索引的,在0.8版本後引入bitmap索引處理器,在3.0版本開始移除索引的功能,取而代之的是2.3版本開始的物化檢視,自動重寫的物化檢視替代了索引的功能。

    3. 運維如何對Hive進行排程

    1. 將hive的sql定義在指令碼當中;

    2. 使用azkaban或者oozie進行任務的排程;

    3. 監控任務排程頁面。

    4. ORC、Parquet等列式儲存的優點

    ORC和Parquet都是高效能的儲存方式,這兩種儲存格式總會帶來儲存和效能上的提升。

    Parquet:

    1. Parquet支援巢狀的資料模型,類似於Protocol Buffers,每一個資料模型的schema包含多個欄位,每一個欄位有三個屬性:重複次數、資料型別和欄位名。
      重複次數可以是以下三種:required(只出現1次),repeated(出現0次或多次),optional(出現0次或1次)。每一個欄位的資料型別可以分成兩種: group(複雜型別)和primitive(基本型別)。

    2. Parquet中沒有Map、Array這樣的複雜資料結構,但是可以透過repeated和group組合來實現的。

    3. 由於Parquet支援的資料模型比較鬆散,可能一條記錄中存在比較深的巢狀關係,如果為每一條記錄都維護一個類似的樹狀結可能會佔用較大的儲存空間,因此Dremel論文中提出了一種高效的對於巢狀資料格式的壓縮演算法:Striping/Assembly演算法。透過Striping/Assembly演算法,parquet可以使用較少的儲存空間表示複雜的巢狀格式,並且通常Repetition level和Definition level都是較小的整數值,可以透過RLE演算法對其進行壓縮,進一步降低儲存空間。

    4. Parquet檔案是以二進位制方式儲存的,是不可以直接讀取和修改的,Parquet檔案是自解析的,檔案中包括該檔案的資料和後設資料。

    ORC:

    1. ORC檔案是自描述的,它的後設資料使用Protocol Buffers序列化,並且檔案中的資料儘可能的壓縮以降低儲存空間的消耗。

    2. 和Parquet類似,ORC檔案也是以二進位制方式儲存的,所以是不可以直接讀取,ORC檔案也是自解析的,它包含許多的後設資料,這些後設資料都是同構ProtoBuffer進行序列化的。

    3. ORC會盡可能合併多個離散的區間儘可能的減少I/O次數。

    4. ORC中使用了更加精確的索引資訊,使得在讀取資料時可以指定從任意一行開始讀取,更細粒度的統計資訊使得讀取ORC檔案跳過整個row group,ORC預設會對任何一塊資料和索引資訊使用ZLIB壓縮,因此ORC檔案佔用的儲存空間也更小。

    5. 在新版本的ORC中也加入了對Bloom Filter的支援,它可以進一 步提升謂詞下推的效率,在Hive 1.2.0版本以後也加入了對此的支 持。

    5. 資料建模用的哪些模型?

    1. 星型模型
    2023版最新最強大資料面試寶典

    星形模式(Star Schema)是最常用的維度建模方式。星型模式是以事實表為中心,所有的維度表直接連線在事實表上,像星星一樣。 星形模式的維度建模由一個事實表和一組維表成,且具有以下特點:

    a. 維表只和事實表關聯,維表之間沒有關聯;

    b. 每個維表主鍵為單列,且該主鍵放置在事實表中,作為兩邊連線的外來鍵;

    c. 以事實表為核心,維表圍繞核心呈星形分佈。

    2. 雪花模型
    2023版最新最強大資料面試寶典

    雪花模式(Snowflake Schema)是對星形模式的擴充套件。雪花模式的維度表可以擁有其他維度表的,雖然這種模型相比星型更規範一些,但是由於這種模型不太容易理解,維護成本比較高,而且效能方面需要關聯多層維表,效能比星型模型要低。

    3. 星座模型
    2023版最新最強大資料面試寶典

    星座模式是星型模式延伸而來,星型模式是基於一張事實表的,而星座模式是基於多張事實表的,而且共享維度資訊。前面介紹的兩種維度建模方法都是多維表對應單事實表,但在很多時候維度空間內的事實表不止一個,而一個維表也可能被多個事實表用到。在業務發展後期,絕大部分維度建模都採用的是星座模式。

    數倉建模詳細介紹可檢視:通俗易懂數倉建模

    6. 為什麼要對資料倉儲分層?

    • 用空間換時間,透過大量的預處理來提升應用系統的使用者體驗(效率),因此資料倉儲會存在大量冗餘的資料。

    • 如果不分層的話,如果源業務系統的業務規則發生變化將會影響整個資料清洗過程,工作量巨大。

    • 透過資料分層管理可以簡化資料清洗的過程,因為把原來一步的工作分到了多個步驟去完成,相當於把一個複雜的工作拆成了多個簡單的工作,把一個大的黑盒變成了一個白盒,每一層的處理邏輯都相對簡單和容易理解,這樣我們比較容易保證每一個步驟的正確性,當資料發生錯誤的時候,往往我們只需要區域性調整某個步驟即可。

    資料倉儲詳細介紹可檢視:萬字詳解整個資料倉儲建設體系

    7. 使用過Hive解析JSON串嗎

    Hive處理json資料總體來說有兩個方向的路走

    1. 將json以字串的方式整個入Hive表,然後透過使用UDF函式解析已經匯入到hive中的資料,比如使用LATERAL VIEW json_tuple的方法,獲取所需要的列名。

    2. 在匯入之前將json拆成各個欄位,匯入Hive表的資料是已經解析過的。這將需要使用第三方的 SerDe。

    詳細介紹可檢視:Hive解析Json陣列超全講解

    8. sort by 和 order by 的區別

    order by 會對輸入做全域性排序,因此只有一個reducer(多個reducer無法保證全域性有序)只有一個reducer,會導致當輸入規模較大時,需要較長的計算時間。

    sort by不是全域性排序,其在資料進入reducer前完成排序. 因此,如果用sort by進行排序,並且設定mapred.reduce.tasks>1, 則sort by只保證每個reducer的輸出有序,不保證全域性有序

    9. 資料傾斜怎麼解決

    資料傾斜問題主要有以下幾種:

    1. 空值引發的資料傾斜

    2. 不同資料型別引發的資料傾斜

    3. 不可拆分大檔案引發的資料傾斜

    4. 資料膨脹引發的資料傾斜

    5. 表連線時引發的資料傾斜

    6. 確實無法減少資料量引發的資料傾斜

    以上傾斜問題的具體解決方案可檢視:Hive千億級資料傾斜解決方案

    注意:對於 left join 或者 right join 來說,不會對關聯的欄位自動去除null值,對於 inner join 來說,會對關聯的欄位自動去除null值。

    小夥伴們在閱讀時注意下,在上面的文章(Hive千億級資料傾斜解決方案)中,有一處sql出現了上述問題(舉例的時候原本是想使用left join的,結果手誤寫成了join)。此問題由公眾號讀者發現,感謝這位讀者指正。

    10. Hive 小檔案過多怎麼解決

    1. 使用 hive 自帶的 concatenate 命令,自動合併小檔案

    使用方法:

    #對於非分割槽表
    alter table A concatenate;

    #對於分割槽表
    alter table B partition(day=20201224) concatenate;

    注意:
    1、concatenate 命令只支援 RCFILE 和 ORC 檔案型別。
    2、使用concatenate命令合併小檔案時不能指定合併後的檔案數量,但可以多次執行該命令。
    3、當多次使用concatenate後檔案數量不在變化,這個跟引數 mapreduce.input.fileinputformat.split.minsize=256mb 的設定有關,可設定每個檔案的最小size。

    2. 調整引數減少Map數量

    設定map輸入合併小檔案的相關引數(執行Map前進行小檔案合併):

    在mapper中將多個檔案合成一個split作為輸入(CombineHiveInputFormat底層是Hadoop的CombineFileInputFormat方法):

    set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; -- 預設

    每個Map最大輸入大小(這個值決定了合併後檔案的數量):

    set mapred.max.split.size=256000000;   -- 256M

    一個節點上split的至少大小(這個值決定了多個DataNode上的檔案是否需要合併):

    set mapred.min.split.size.per.node=100000000;  -- 100M

    一個交換機下split的至少大小(這個值決定了多個交換機上的檔案是否需要合併):

    set mapred.min.split.size.per.rack=100000000;  -- 100M
    3. 減少Reduce的數量

    reduce 的個數決定了輸出的檔案的個數,所以可以調整reduce的個數控制hive表的檔案數量。

    hive中的分割槽函式 distribute by 正好是控制MR中partition分割槽的,可以透過設定reduce的數量,結合分割槽函式讓資料均衡的進入每個reduce即可:

    #設定reduce的數量有兩種方式,第一種是直接設定reduce個數
    set mapreduce.job.reduces=10;

    #第二種是設定每個reduce的大小,Hive會根據資料總大小猜測確定一個reduce個數
    set hive.exec.reducers.bytes.per.reducer=5120000000-- 預設是1G,設定為5G

    #執行以下語句,將資料均衡的分配到reduce中
    set mapreduce.job.reduces=10;
    insert overwrite table A partition(dt)
    select * from B
    distribute by rand();

    對於上述語句解釋:如設定reduce數量為10,使用 rand(), 隨機生成一個數 x % 10 , 這樣資料就會隨機進入 reduce 中,防止出現有的檔案過大或過小。

    4. 使用hadoop的archive將小檔案歸檔

    Hadoop Archive簡稱HAR,是一個高效地將小檔案放入HDFS塊中的檔案存檔工具,它能夠將多個小檔案打包成一個HAR檔案,這樣在減少namenode記憶體使用的同時,仍然允許對檔案進行透明的訪問。

    #用來控制歸檔是否可用
    set hive.archive.enabled=true;
    #通知Hive在建立歸檔時是否可以設定父目錄
    set hive.archive.har.parentdir.settable=true;
    #控制需要歸檔檔案的大小
    set har.partfile.size=1099511627776;

    使用以下命令進行歸檔:
    ALTER TABLE A ARCHIVE PARTITION(dt='2021-05-07', hr='12');

    對已歸檔的分割槽恢復為原檔案:
    ALTER TABLE A UNARCHIVE PARTITION(dt='2021-05-07', hr='12');

    注意:
    歸檔的分割槽可以檢視不能 insert overwrite,必須先 unarchive

    Hive 小檔案問題具體可檢視:解決hive小檔案過多問題

    11. Hive最佳化有哪些

    1. 資料儲存及壓縮:

    針對hive中表的儲存格式通常有orc和parquet,壓縮格式一般使用snappy。相比與textfile格式表,orc佔有更少的儲存。因為hive底層使用MR計算架構,資料流是hdfs到磁碟再到hdfs,而且會有很多次,所以使用orc資料格式和snappy壓縮策略可以降低IO讀寫,還能降低網路傳輸量,這樣在一定程度上可以節省儲存,還能提升hql任務執行效率;

    2. 透過調參最佳化:

    並行執行,調節parallel引數;

    調節jvm引數,重用jvm;

    設定map、reduce的引數;開啟strict mode模式;

    關閉推測執行設定。

    3. 有效地減小資料集將大表拆分成子表;結合使用外部表和分割槽表。
    4. SQL最佳化
    • 大表對大表:儘量減少資料集,可以透過分割槽表,避免掃描全表或者全欄位;

    • 大表對小表:設定自動識別小表,將小表放入記憶體中去執行。

    Hive最佳化詳細剖析可檢視:Hive企業級效能最佳化

    12. Tez引擎優點?

    Tez可以將多個有依賴的作業轉換為一個作業,這樣只需寫一次HDFS,且中間節點較少,從而大大提升作業的計算效能。

    Mr/tez/spark區別:

    Mr引擎:多job串聯,基於磁碟,落盤的地方比較多。雖然慢,但一定能跑出結果。一般處理,周、月、年指標

    Spark引擎:雖然在Shuffle過程中也落盤,但是並不是所有運算元都需要Shuffle,尤其是多運算元過程,中間過程不落盤  DAG有向無環圖。 兼顧了可靠性和效率。一般處理天指標

    Tez引擎:完全基於記憶體。  注意:如果資料量特別大,慎重使用。容易OOM。一般用於快速出結果,資料量比較小的場景

    Doris

    1. Doris的應用場景有哪些?

    首先 Doris 是一個有著MPP架構的分析型資料庫產品。對於PB數量級、結構化資料可以做到亞秒級查詢響應。使用上相容MySQL協議,語法是標準的SQL。Doris本身不依賴任何其他系統,相比Hadoop生態產品更易於運維。

    應用場景包括:固定歷史報表分析、實時資料分析、互動式資料分析等。

    一般情況下,使用者的原始資料,比如日誌或者在事務型資料庫中的資料,經過流式系統或離線處理後,匯入到Doris中以供上層的報表工具或者資料分析師查詢使用。

    2. Doris的架構介紹下

    Doris 的架構很簡潔,只設 FE(Frontend)、BE(Backend)兩種角色、兩個程式。

    • 以資料儲存的角度觀看,FE 儲存、維護叢集後設資料;BE 儲存物理資料,資料的可靠性由 BE 保證,BE 會對整個資料儲存多副本。

    • 以查詢處理的角度觀看,FE 節點接收、解析查詢請求,規劃查詢計劃,排程查詢執行,返回查詢結果;BE 節點依據 FE 生成的物理計劃,分散式地執行查詢。

    FE 主要有有三個角色,一個是 Leader,一個是 Follower,還有一個 Observer。Leader 跟 Follower,主要是用來達到後設資料的高可用,保證單節點當機的情況下,後設資料能夠實時地線上恢復,而不影響整個服務。Observer 只是用來擴充套件查詢節點,就是說如果在發現叢集壓力非常大的情況下,需要去擴充套件整個查詢的能力,那麼可以加 Observer 的節點。Observer 不參與任何的寫入,只參與讀取。

    在使用介面方面,Doris 採用 MySQL 協議,高度相容 MySQL 語法,支援標準 SQL,使用者可以透過各類客戶端工具來訪問 Doris,並支援與 BI 工具的無縫對接。

    3. Doris 的資料模型

    Doris 的資料模型主要分為3類:

    • Aggregate 聚合模型
    • Uniq 唯一主鍵模型
    • Duplicate 模型

    Aggregate 聚合模型

    聚合模型需要使用者在建表時顯式的將列分為 Key 列和 Value 列。該模型會自動的對 Key 相同的行,在 Value 列上進行聚合操作。

    當我們匯入資料時,對於 Key 列相同的行會聚合成一行,而 Value 列會按照設定的 AggregationType 進行聚合。 AggregationType 目前有以下四種聚合方式:

    • SUM:求和,多行的 Value 進行累加。
    • REPLACE:替代,下一批資料中的 Value 會替換之前匯入過的行中的 Value。
    • MAX:保留最大值。
    • MIN:保留最小值。

    例如:

    CREATE TABLE IF NOT EXISTS example_db.expamle_tbl
    (
        `user_id` LARGEINT NOT NULL COMMENT "使用者id",
        `date` DATE NOT NULL COMMENT "資料灌入日期時間",
        `city` VARCHAR(20COMMENT "使用者所在城市",
        `age` SMALLINT COMMENT "使用者年齡",
        `sex` TINYINT COMMENT "使用者性別",
        `last_visit_date` DATETIME REPLACE DEFAULT "1970-01-01 00:00:00" COMMENT "使用者最後一次訪問時間",
        `cost` BIGINT SUM DEFAULT "0" COMMENT "使用者總消費",
        `max_dwell_time` INT MAX DEFAULT "0" COMMENT "使用者最大停留時間",
        `min_dwell_time` INT MIN DEFAULT "99999" COMMENT "使用者最小停留時間"
    )
    AGGREGATE KEY(`user_id``date``city``age``sex`)
    ... /* 省略 Partition 和 Distribution 資訊 */
    ;

    Unique 唯一主鍵模型:

    在某些多維分析場景下,使用者更關注的是如何保證 Key 的唯一性,即如何獲得 Primary Key 唯一性約束。因此,我們引入了 Unique 的資料模型。該模型本質上是聚合模型的一個特例,也是一種簡化的表結構表示方式。我們舉例說明。

    這是一個典型的使用者基礎資訊表。這類資料沒有聚合需求,只需保證主鍵唯一性。(這裡的主鍵為 user_id + username)。那麼我們的建表語句如下:

    CREATE TABLE IF NOT EXISTS example_db.expamle_tbl
    (
        `user_id` LARGEINT NOT NULL COMMENT "使用者id",
        `username` VARCHAR(50NOT NULL COMMENT "使用者暱稱",
        `city` VARCHAR(20COMMENT "使用者所在城市",
        `age` SMALLINT COMMENT "使用者年齡",
        `sex` TINYINT COMMENT "使用者性別",
        `phone` LARGEINT COMMENT "使用者電話",
        `address` VARCHAR(500COMMENT "使用者地址",
        `register_time` DATETIME COMMENT "使用者註冊時間"
    )
    UNIQUE KEY(`user_id``user_name`)
    ... /* 省略 Partition 和 Distribution 資訊 */
    ;

    而這個表結構,完全同等於以下使用聚合模型描述的表結構:

    CREATE TABLE IF NOT EXISTS example_db.expamle_tbl
    (
        `user_id` LARGEINT NOT NULL COMMENT "使用者id",
        `username` VARCHAR(50NOT NULL COMMENT "使用者暱稱",
        `city` VARCHAR(20REPLACE COMMENT "使用者所在城市",
        `age` SMALLINT REPLACE COMMENT "使用者年齡",
        `sex` TINYINT REPLACE COMMENT "使用者性別",
        `phone` LARGEINT REPLACE COMMENT "使用者電話",
        `address` VARCHAR(500REPLACE COMMENT "使用者地址",
        `register_time` DATETIME REPLACE COMMENT "使用者註冊時間"
    )
    AGGREGATE KEY(`user_id``user_name`)
    ... /* 省略 Partition 和 Distribution 資訊 */

    即 Unique 模型完全可以用聚合模型中的 REPLACE 方式替代。其內部的實現方式和資料儲存方式也完全一樣。這裡不再繼續舉例說明。

    Duplicate 模型:

    在某些多維分析場景下,資料既沒有主鍵,也沒有聚合需求。因此,我們引入 Duplicate 資料模型來滿足這類需求。

    例如:

    CREATE TABLE IF NOT EXISTS example_db.expamle_tbl
    (
        `timestamp` DATETIME NOT NULL COMMENT "日誌時間",
        `type` INT NOT NULL COMMENT "日誌型別",
        `error_code` INT COMMENT "錯誤碼",
        `error_msg` VARCHAR(1024COMMENT "錯誤詳細資訊",
        `op_id` BIGINT COMMENT "負責人id",
        `op_time` DATETIME COMMENT "處理時間"
    )
    DUPLICATE KEY(`timestamp``type`)
    ... /* 省略 Partition 和 Distribution 資訊 */

    這種資料模型區別於 Aggregate 和 Uniq 模型。資料完全按照匯入檔案中的資料進行儲存,不會有任何聚合。即使兩行資料完全相同,也都會保留。 而在建表語句中指定的 DUPLICATE KEY,只是用來指明底層資料按照那些列進行排序。

    4. 介紹下Doris的ROLLUP

    ROLLUP

    ROLLUP 在多維分析中是“上卷”的意思,即將資料按某種指定的粒度進行進一步聚合

    在 Doris 中,我們將使用者透過建表語句建立出來的表稱為 Base 表(Base Table)。在 Base 表之上,我們可以建立任意多個 ROLLUP 表。這些 ROLLUP 的資料是基於 Base 表產生的,並且在物理上是獨立儲存的。

    ROLLUP 表的基本作用,在於在 Base 表的基礎上,獲得更粗粒度的聚合資料。

    Duplicate 模型中的 ROLLUP

    因為 Duplicate 模型沒有聚合的語意。所以該模型中的 ROLLUP,已經失去了“上卷”這一層含義。而僅僅是作為調整列順序,以命中字首索引的作用。

    5. Doris的字首索引瞭解嗎?

    不同於傳統的資料庫設計,Doris 不支援在任意列上建立索引。Doris 這類 MPP 架構的 OLAP 資料庫,通常都是透過提高併發,來處理大量資料的。

    本質上,Doris 的資料儲存在類似 SSTable(Sorted String Table)的資料結構中。該結構是一種有序的資料結構,可以按照指定的列進行排序儲存。在這種資料結構上,以排序列作為條件進行查詢,會非常的高效。

    在 Aggregate、Uniq 和 Duplicate 三種資料模型中。底層的資料儲存,是按照各自建表語句中,AGGREGATE KEY、UNIQ KEY 和 DUPLICATE KEY 中指定的列進行排序儲存的。

    而字首索引,即在排序的基礎上,實現的一種根據給定字首列,快速查詢資料的索引方式。

    在建表時,正確的選擇列順序,能夠極大地提高查詢效率

    ROLLUP 調整字首索引

    因為建表時已經指定了列順序,所以一個表只有一種字首索引。這對於使用其他不能命中字首索引的列作為條件進行的查詢來說,效率上可能無法滿足需求。因此,我們可以透過建立 ROLLUP 來人為的調整列順序,以獲得更好的查詢效率。

    6. 講下Doris的物化檢視

    物化檢視是將預先計算(根據定義好的 SELECT 語句)好的資料集,儲存在 Doris 中的一個特殊的表。

    物化檢視的出現主要是為了滿足使用者,既能對原始明細資料的任意維度分析,也能快速的對固定維度進行分析查詢

    使用場景(物化檢視主要針對Duplicate明細模型做聚合操作)

    • 分析需求覆蓋明細資料查詢以及固定維度查詢兩方面。
    • 查詢僅涉及表中的很小一部分列或行。
    • 查詢包含一些耗時處理操作,比如:時間很久的聚合操作等。
    • 查詢需要匹配不同字首索引。

    優勢

    • 對於那些經常重複的使用相同的子查詢結果的查詢效能大幅提升。
    • Doris自動維護物化檢視的資料,無論是新的匯入,還是刪除操作都能保證base 表和物化檢視表的資料一致性。無需任何額外的人工維護成本。
    • 查詢時,會自動匹配到最優物化檢視,並直接從物化檢視中讀取資料。

    7. 物化檢視和Rollup的區別是什麼

    在沒有物化檢視功能之前,使用者一般都是使用 Rollup 功能透過預聚合方式提升查詢效率的。但是 Rollup 具有一定的侷限性,他不能基於明細模型做預聚合。

    物化檢視則在覆蓋了 Rollup 的功能的同時,還能支援更豐富的聚合函式。所以物化檢視其實是 Rollup 的一個超集。

    物化檢視的侷限性

    1. 物化檢視的聚合函式的引數不支援表示式僅支援單列,比如: sum(a+b)不支援。

    2. 如果刪除語句的條件列,在物化檢視中不存在,則不能進行刪除操作。如果一定要刪除資料,則需要先將物化檢視刪除,然後方可刪除資料。

    3. 單表上過多的物化檢視會影響匯入的效率:匯入資料時,物化檢視和 base 表資料是同步更新的,如果一張表的物化檢視表超過10張,則有可能導致匯入速度很慢。這就像單次匯入需要同時匯入10張表資料是一樣的。

    4. 相同列,不同聚合函式,不能同時出現在一張物化檢視中,比如:select sum(a), min(a) from table 不支援。

    5. 物化檢視針對 Unique Key資料模型,只能改變列順序,不能起到聚合的作用,所以在Unique Key模型上不能透過建立物化檢視的方式對資料進行粗粒度聚合操作

    資料倉儲

    推薦數倉建設好文,建議讀一讀:萬字詳解整個資料倉儲建設體系

    1. ODS層採用什麼壓縮方式和儲存格式?

    壓縮採用Snappy,儲存採用orc,壓縮比是100g資料壓縮完10g左右。

    2. DWD層做了哪些事?

    1. 資料清洗
    • 空值去除
    • 過濾核心欄位無意義的資料,比如訂單表中訂單id為null,支付表中支付id為空
    • 對手機號、身份證號等敏感資料脫敏
    • 對業務資料傳過來的表進行維度退化和降維。
    • 將使用者行為寬表和業務表進行資料一致性處理
    1. 清洗的手段
    • Sql、mr、rdd、kettle、Python(專案中採用sql進行清除)

    3. DWS層做了哪些事?

    1. DWS層有3-5張寬表(處理100-200個指標 70%以上的需求)

    具體寬表名稱:使用者行為寬表,使用者購買商品明細行為寬表,商品寬表,購物車寬表,物流寬表、登入註冊、售後等。

    1. 哪個寬表最寬?大概有多少個欄位? 最寬的是使用者行為寬表。大概有60-100個欄位

    4. 事實表的型別?

    事實表有:事務事實表、週期快照事實表、累積快照事實表、⾮事實事實表。

    1) 事務事實表

    事務事實表記錄的是事務層⾯的事實,儲存的是最原⼦的資料,也稱“原⼦事實表”。事務事實表中的資料在事務事件發⽣後產⽣,資料的粒度通常是每個事務記錄⼀條記錄。

    2) 週期快照事實表

    以具有規律性的、可預⻅的時間間隔來記錄事實。它統計的是間隔週期內的度量統計,每個時間段⼀條記錄,是在事務事實表之上建⽴的聚集表。

    3)累積快照事實表

    累積快照表記錄的不確定的週期的資料。代表的是完全覆蓋⼀個事務或產品的⽣命週期的時間跨度,通常具有多個⽇期欄位,⽤來記錄整個⽣命週期中的關鍵時間點。

    4)⾮事實型事實表

    這個與上⾯三個有所不同。事實表中通常要保留度量事實和多個維度外來鍵,度量事實是事實表的關鍵所在。

    ⾮事實表中沒有這些度量事實,只有多個維度外來鍵。⾮事實型事實表通常⽤來跟蹤⼀些事件或說明某些活動的範圍。

    第⼀類⾮事實型事實表是⽤來跟蹤事件的事實表。例如:學⽣註冊事件

    第⼆類⾮事實型事實表是⽤來說明某些活動範圍的事實表。例如:促銷範圍事實表。

    5. 星型模型和雪花模型的區別

    1) 星型模式

    星形模式(Star Schema)是最常用的維度建模方式。星型模式是以事實表為中心,所有的維度表直接連線在事實表上,像星星一樣。星形模式的維度建模由一個事實表和一組維表成,且具有以下特點:a. 維表只和事實表關聯,維表之間沒有關聯;b. 每個維表主鍵為單列,且該主鍵放置在事實表中,作為兩邊連線的外來鍵;c. 以事實表為核心,維表圍繞核心呈星形分佈;

    2023版最新最強大資料面試寶典
    1. 雪花模式

    雪花模式(Snowflake Schema)是對星形模式的擴充套件。雪花模式的維度表可以擁有其他維度表的,雖然這種模型相比星型更規範一些,但是由於這種模型不太容易理解,維護成本比較高,而且效能方面需要關聯多層維表,效能也比星型模型要低。所以一般不是很常用

    2023版最新最強大資料面試寶典

    3.星座模式

    星座模式是星型模式延伸而來,星型模式是基於一張事實表的,而星座模式是基於多張事實表的,而且共享維度資訊。前面介紹的兩種維度建模方法都是多維表對應單事實表,但在很多時候維度空間內的事實表不止一個,而一個維表也可能被多個事實表用到。在業務發展後期,絕大部分維度建模都採用的是星座模式。

    2023版最新最強大資料面試寶典

    6. 資料漂移如何解決?

    1) 什麼是資料漂移?

    通常是指ods表的同⼀個業務⽇期資料中包含了前⼀天或後⼀天凌晨附近的資料或者丟失當天變更的資料,這種現象就叫做漂移,且在⼤部分公司中都會遇到的場景。

    2) 如何解決資料漂移問題?

    通常有兩種解決⽅案:

    1. 多獲取後⼀天的資料,保障資料只多不少

    2. 透過多個時間戳欄位來限制時間獲取相對準確的資料

    第⼀種⽅案⽐較暴⼒,這⾥不做過多解釋,主要來講解⼀下第⼆種解決⽅案。(這種解決⽅案在⼤資料之路這本書有體現)。

    第⼀種⽅案⾥,時間戳欄位分為四類:

    1. 資料庫表中⽤來標識資料記錄更新時間的時間戳欄位(假設這類欄位叫 modified time )。

    2. 資料庫⽇志中⽤來標識資料記錄更新時間的時間戳欄位·(假設這類宇段叫 log_time)。

    3. 資料庫表中⽤來記錄具體業務過程發⽣時間的時間戳欄位 (假設這類欄位叫 proc_time)。

    4. 標識資料記錄被抽取到時間的時間戳欄位(假設這類欄位extract time)。

    理論上這⼏個時間應該是⼀致的,但往往會出現差異,造成的原因可能為:

    1. 資料抽取需要⼀定的時間,extract_time往往晚於前三個時間。

    2. 業務系統⼿動改動資料並未更新modfied_time。

    3. ⽹絡或系統壓⼒問題,log_time或modified_time晚於proc_time。

    通常都是根據以上的某⼏個欄位來切分ODS表,這就產⽣了資料漂移。具體場景如下:

    1. 根據extract_time進⾏同步。

    2. 根據modified_time進⾏限制同步, 在實際⽣產中這種情況最常⻅,但是往往會發⽣不更新 modified time⽽導致的資料遺漏,或者凌晨時間產⽣的資料記錄漂移到後天 。由於⽹絡或者系統壓⼒問題, log_time 會晚proc_time ,從⽽導致凌晨時間產⽣的資料記錄漂移到後⼀天。

    3. 根據proc_time來限制,會違背ods和業務庫保持⼀致的原則,因為僅僅根據proc_time來限制,會遺漏很多其他過程的變化。

    第⼆種解決⽅案:

    1. ⾸先透過log_time多同步前⼀天最後15分鐘和後⼀天凌晨開始15分鐘的資料,然後⽤modified_time過濾⾮當天的資料,這樣確保資料不會因為系統問題被遺漏。

    2. 然後根據log_time獲取後⼀天15分鐘的資料,基於這部分資料,按照主鍵根據log_time做升序排序,那麼第⼀條資料也就是最接近當天記錄變化的。

    3. 最後將前兩步的資料做全外連線,透過限制業務時間proc_time來獲取想要的資料。

    7. 維度建模和正規化建模的區別

    通常資料建模有以下⼏個流程:

    1. 概念建模:即通常先將業務劃分多個主題。

    2. 邏輯建模:即定義各種實體、屬性和關係。

    3. 物理建模:設計資料物件的物理實現,⽐如表欄位型別、命名等。

    那麼正規化建模,即3NF模型具有以下特點:

    1. 原⼦性,即資料不可分割

    2. 基於第⼀個條件,實體屬性完全依賴於主鍵,不能存在僅依賴主關鍵字⼀部分屬性。即不能存在部分依賴

    3. 基於第⼆個條件,任何⾮主屬性不依賴於其他⾮主屬性。即消除傳遞依賴

    基於以上三個特點,3NF的最終⽬的就是為了降低資料冗餘,保障資料⼀致性;同時也有了資料關聯邏輯複雜的缺點。

    ⽽維度建模是⾯向分析場景的,主要關注點在於快速、靈活,能夠提供⼤規模的資料響應。

    常⽤的維度模型型別主要有:

    1. 星型模型:即由⼀個事實表和⼀組維度表組成,每個維表都有⼀個維度作為主鍵。事實表居中,多個維表呈輻射狀分佈在四周,並與事實表關聯,形成⼀個星型結構。

    2. 雪花模型:在星型模型的基礎上,基於正規化理論進⼀步層次化,將某些維表擴充套件成事實表,最終形成雪花狀結構。

    3. 星系模型:基於多個事實表,共享⼀些維度表。

    8. 談談後設資料的理解?

    狹義來講就是⽤來描述資料的資料。

    ⼴義來看,除了業務邏輯直接讀寫處理的業務資料,所有其他⽤來維護整個系統運轉所需要的資料,都可以較為後設資料。

    定義:後設資料metadata是關於資料的資料。在數倉系統中,後設資料可以幫助資料倉儲管理員和資料倉儲開發⼈員⽅便的找到他們所關⼼的資料;後設資料是描述資料倉儲內部資料的結構和建⽴⽅法的資料。按照⽤途可分為:技術後設資料、業務後設資料。

    技術後設資料

    儲存關於資料倉儲技術細節的資料,⽤於開發和管理資料倉儲使⽤的資料。

    1. 資料倉儲結構的描述,包括資料模式、檢視、維、層次結構和匯出資料的定義,以及資料集市的位置和內容。

    2. 業務系統、資料倉儲和資料集市的體系結構和模式。

    3. 由操作環境到資料倉儲環境的對映,包括後設資料和他們的內容、資料提取、轉換規則和資料重新整理規則、許可權等。

    業務後設資料

    從業務⻆度描述了資料倉儲中的資料,他提供了介於使⽤者和實際系統之間的語義層,使不懂計算機技術的業務⼈員也能讀懂數倉中的資料。

    1. 企業概念模型:表示企業資料模型的⾼層資訊。整個企業業務概念和相互關係。以這個企業模型為基礎,不懂sql的⼈也能做到⼼中有數

    2. 多維資料模型。告訴業務分析⼈員在資料集市中有哪些維、維的類別、資料⽴⽅體以及資料集市中的聚合規則。

    3. 業務概念模型和物理資料之間的依賴。業務檢視和實際數倉的表、欄位、維的對應關係也應該在後設資料知識庫中有所體現。

    9. 數倉如何確定主題域?

    主題

    主題是在較⾼層次上將資料進⾏綜合、歸類和分析利⽤的⼀個抽象概念,每⼀個主題基本對應⼀個宏觀的分析領域。在邏輯意義上,它是對企業中某⼀宏觀分析領域所涉及的分析物件。

    ⾯向主題的資料組織⽅式,就是在較⾼層次上對分析物件資料的⼀個完整並且⼀致的描述,能刻畫各個分析物件所涉及的企業各項資料,以及資料之間的聯絡。

    主題是根據分析的要求來確定的。

    主題域

    1. 從資料⻆度看(集合論)

    主題語通常是聯絡較為緊密的資料主題的集合。可以根據業務的關注點,將這些資料主題劃分到不同的主題域。主題域的確定由最終⽤戶和數倉設計⼈員共同完成。

    1. 從需要建設的數倉主題看(邊界論)

    主題域是對某個主題進⾏分析後確定的主題的邊界。

    數倉建設過程中,需要對主題進⾏分析,確定主題所涉及到的表、欄位、維度等界限。

    1. 確定主題內容

    數倉主題定義好以後,數倉中的邏輯模型也就基本成形了,需要在主題的邏輯關係中列出屬性和系統相關⾏為。此階段需要定義好資料倉儲的儲存結構,向主題模型中新增所需要的資訊和能充分代表主題的屬性組。

    10. 在處理大資料過程中,如何保證得到期望值

    1. 保證在資料採集的時候不丟失資料,這個尤為重要,如果在資料採集的時候就已經不準確,後面很難達到期望值

    2. 在資料處理的時候不丟失資料,例如sparkstreaming處理kafka資料的時候,要保證資料不丟失,這個尤為重要

    3. 前兩步中,如果無法保證資料的完整性,那麼就要透過離線計算進行資料的校對,這樣才能保證我們能夠得到期望值

    11. 你感覺數倉建設中最重要的是什麼

    數倉建設中,最重要的是資料準確性,資料的真正價值在於資料驅動決策,透過資料指導運營,在一個不準確的資料驅動下,得到的一定是錯誤的資料分析,影響的是公司的業務發展決策,最終導致公司的策略調控失敗。

    12. 資料倉儲建模怎麼做的

    數倉建設中最常用模型--Kimball維度建模詳解

    13. 資料質量怎麼監控

    單表資料量監控

    一張表的記錄數在一個已知的範圍內,或者上下浮動不會超過某個閾值

    1. SQL結果:var 資料量 = select count(*)from 表 where 時間等過濾條件

    2. 報警觸發條件設定:如果資料量不在[數值下限, 數值上限], 則觸發報警

    3. 同比增加:如果((本週的資料量 -上週的資料量)/上週的資料量*100)不在 [比例下線,比例上限],則觸發報警

    4. 環比增加:如果((今天的資料量 - 昨天的資料量)/昨天的資料量*100)不在 [比例下線,比例上限],則觸發報警

    5. 報警觸發條件設定一定要有。如果沒有配置的閾值,不能做監控 日活、周活、月活、留存(日周月)、轉化率(日、周、月)GMV(日、周、月) 復購率(日周月)

    單表空值檢測

    某個欄位為空的記錄數在一個範圍內,或者佔總量的百分比在某個閾值範圍內

    1. 目標欄位:選擇要監控的欄位,不能選“無”

    2. SQL結果:var 異常資料量 = select count(*) from 表 where 目標欄位 is null

    3. 單次檢測:如果(異常資料量)不在[數值下限, 數值上限],則觸發報警

    單表重複值檢測

    一個或多個欄位是否滿足某些規則

    1. 目標欄位:第一步先正常統計條數;select count(*) form 表;

    2. 第二步,去重統計;select count(*) from 表 group by 某個欄位

    3. 第一步的值和第二步的值做減法,看是否在上下線閥值之內

    4. 單次檢測:如果(異常資料量)不在[數值下限, 數值上限], 則觸發報警

    跨表資料量對比

    主要針對同步流程,監控兩張表的資料量是否一致

    1. SQL結果:count(本表) - count(關聯表)

    2. 閾值配置與“空值檢測”相同

    14. 資料分析方法論瞭解過哪些?

    資料商業分析的目標是利用大資料為所有職場人員做出迅捷,高質,高效的決策提供可規模化的解決方案。商業分析是創造價值的資料科學。

    資料商業分析中會存在很多判斷:

    1. 觀察資料當前發生了什麼?

    比如想知道線上渠道A、B各自帶來了多少流量,新上線的產品有多少使用者喜歡,新註冊流中註冊的人數有多少。這些都需要透過資料來展示結果。

    1. 理解為什麼發生?

    我們需要知道渠道A為什麼比渠道B好,這些是要透過資料去發現的。也許某個關鍵字帶來的流量轉化率比其他都要低,這時可以透過資訊、知識、資料沉澱出發生的原因是什麼。

    1. 預測未來會發生什麼?

    在對渠道A、B有了判斷之後,根據以往的知識預測未來會發生什麼。在投放渠道C、D的時候,猜測渠道C比渠道D好,當上線新的註冊流、新的最佳化,可以知道哪一個節點比較容易出問題,這些都是透過資料進行預測的過程。

    1. 商業決策

    所有工作中最有意義的還是商業決策,透過資料來判斷應該做什麼。這是商業分析最終的目的。

    大資料演算法設計題

    1. TOP K 演算法

    有 10 個⽂件,每個⽂件 1G,每個⽂件的每⼀⾏存放的都是⽤戶的 query,每個⽂件的query 都可能重複。要求你按照 query 的頻度排序。

    解答:

    1)⽅案 1:

    順序讀取 10 個⽂件,按照 hash(query)%10 的結果將 query 寫⼊到另外 10 個⽂件(記為)中。這樣新⽣成的⽂件每個的⼤⼩⼤約也 1G(假設 hash 函式是隨機的)。 找⼀臺記憶體在 2G 左右的機器,依次對⽤hash_map(query, query_count)來統計每個query 出現的次數。利⽤快速/堆/歸併排序按照出現次數進⾏排序。將排序好的 query 和對應的 query_cout 輸出到⽂件中。這樣得到了 10 個排好序的⽂件(記為)。 對這 10 個⽂件進⾏歸併排序(內排序與外排序相結合)。

    2)⽅案 2:

    ⼀般 query 的總量是有限的,只是重複的次數⽐較多⽽已,可能對於所有的 query,⼀次性就可以加⼊到記憶體了。這樣,我們就可以採⽤ trie 樹/hash_map等直接來統計每個 query出現的次數,然後按出現次數做快速/堆/歸併排序就可以了。

    3)⽅案 3:

    與⽅案 1 類似,但在做完 hash,分成多個⽂件後,可以交給多個⽂件來處理,採⽤分散式的架構來處理(⽐如MapReduce),最後再進⾏合併。

    2. 不重複的資料

    在2.5億個整數中找出不重複的整數,注,記憶體不⾜以容納這2.5億個整 數。

    解答:

    1)⽅案 1:採⽤ 2-Bitmap(每個數分配 2bit,00 表示不存在,01 表示出現⼀次,10 表示多次,11 ⽆意義)進⾏,共需記憶體 2^32 * 2 bit=1 GB 記憶體,還可以接受。然後掃描這 2.5億個整數,檢視 Bitmap 中相對應位,如果是 00 變 01,01 變 10,10 保持不變。所描完事後,檢視 bitmap,把對應位是 01 的整數輸出即可。

    2)⽅案 2:也可採⽤與第 1 題類似的⽅法,進⾏劃分⼩⽂件的⽅法。然後在⼩⽂件中找出不重複的整數,並排序。然後再進⾏歸併,注意去除重複的元素。


    來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024922/viewspace-2935571/,如需轉載,請註明出處,否則將追究法律責任。

    相關文章