【面試題】大資料開發第1輪面試

水木青楓發表於2020-08-29

面試總結:

1、HDFS小檔案

小檔案的產生原因
1) 資料本身的特點:比如我們在 HDFS 上儲存大量的圖片、短視訊、短音訊等檔案,這些檔案本身較小,達不到一個block的大小,而且數量眾多。
2) MapReduce產生:例如使用查詢一張含有海量資料的表,然後儲存在另外一張表中,而這個查詢只有簡單的過濾條件(比如 select * from iteblog where from = 'hadoop'),這種情況只會啟動大量的 Map 來處理,這種情況可能會產生大量的小檔案。Reduece 設定不合理,也會產生大量小檔案。
3)實時流處理:比如我們使用 Spark Streaming 從外部資料來源接收資料,然後經過 ETL 處理之後儲存到 HDFS 中。這種情況下在每個 Job 中會產生大量的小檔案。

小檔案的影響
1)namenode 會記錄儲存檔案的後設資料資訊,大量小檔案會佔用大量的namenode記憶體,從而影響到HDFS的橫向擴充套件能力。
2)使用mapreduce處理這些小檔案,每個小檔案會啟動一個mapreduce,開啟一個JVM,這樣會佔用叢集的大量資源。

小檔案解決辦法
1)使用 HAR File:
執行一個 MapReduce 任務將小檔案打包成 HAR 檔案,使用 HAR 檔案對客戶端沒有任何影響,所有的原始檔案都可見並且可訪問的(通過 har://URL)。但在 HDFS 端它內部的檔案數減少了。
Hadoop 在進行最終檔案的讀取時,需要先訪問索引資料,所以在效率上會比直接讀取 HDFS 檔案慢一些。
2)Sequence Files
Sequence Files 使用小檔名作為 key,並且檔案內容作為 value,實踐中這種方式非常管用。
和 HAR 不同的是,這種方式還支援壓縮。該方案對於小檔案的存取都比較自由,不限制使用者和檔案的多少,但是 SequenceFile 檔案不能追加寫入,適用於一次性寫入大量小檔案的操作。
3)HBase儲存
小檔案儲存到類似於 HBase 的 KV 資料庫裡面,也可以將 Key 設定為小檔案的檔名,Value 設定為小檔案的內容,相比使用 SequenceFile 儲存小檔案,使用 HBase 的時候我們可以對檔案進行修改,甚至能拿到所有的歷史修改版本。
4)從 Hadoop 底層解決小檔案問題 - HDFS-8998
小檔案佔用了一個block,把小block合併成大block。

5)從 Hadoop 底層解決小檔案問題 - HDFS-8286
把 NameNode 管理的後設資料從儲存在記憶體轉向儲存到第三方KV儲存系統裡,從而減緩 NameNode 的記憶體使用。

參考資料:
https://mp.weixin.qq.com/s/2KFZp4bHKw9iNyDPOTim1A
https://issues.apache.org/jira/browse/HDFS-8998
https://issues.apache.org/jira/browse/HDFS-8286

2、kafka 如何實現高吞吐

1)順序讀寫
kafka的訊息是不斷追加到檔案中的,這個特性使kafka可以充分利用磁碟的順序讀寫效能。
順序讀寫不需要硬碟磁頭的尋道時間,只需很少的扇區旋轉時間,所以速度遠快於隨機讀寫。
順序 I/O: 600MB/s
隨機 I/O: 100KB/s
2)零拷貝
零拷貝(zero-copy)"是一種系統呼叫機制,就是跳過“使用者緩衝區”的拷貝,建立一個磁碟空間和記憶體的直接對映,資料不再複製到“使用者態緩衝區”。
系統上下文切換減少為2次,可以提升一倍的效能
3)檔案分段
kafka的佇列topic被分為了多個區partition,每個partition又分為多個段segment,所以一個佇列中的訊息實際上是儲存在N多個片段檔案中
kafka的佇列topic被分為了多個區partition,每個partition又分為多個段segment,所以一個佇列中的訊息實際上是儲存在N多個片段檔案中
4)批量傳送
Kafka允許進行批量傳送訊息,先將訊息快取在記憶體中,然後一次請求批量傳送出去
比如可以指定快取的訊息達到某個量的時候就發出去,或者快取了固定的時間後就傳送出去
如100條訊息就傳送,或者每5秒傳送一次
這種策略將大大減少服務端的I/O次數
5)資料壓縮
Kafka還支援對訊息集合進行壓縮,Producer可以通過GZIP或Snappy格式對訊息集合進行壓縮
壓縮的好處就是減少傳輸的資料量,減輕對網路傳輸的壓力
Producer壓縮之後,在Consumer需進行解壓,雖然增加了CPU的工作,但在對大資料處理上,瓶頸在網路上而不是CPU,所以這個成本很值得。

參考資料:
https://mp.weixin.qq.com/s/vf4su_rl-UOGS8vHTCeDrg

3. Spark Streaming 如何消費 Kafka 的資料

兩種方式:Receiver-based Approach、Direct Approach (No Receivers)
1)Receiver-based Approach
Receiver 的實現使用了 Kafka 的高階消費者 API,對於所有的 Receivers,接收到的資料將會儲存在 Spark executors 中,然後由 SS 啟動的 Job 來處理這些資料。

2)Direct Approach (No Receivers)
定期地從 Kafka 的 topic+partition 中查詢最新的偏移量,再根據定義的偏移量範圍在每個批處理時間間隔裡面處理資料。當作業需要處理的資料來臨時,Spark 通過呼叫 Kafka 的低階消費者 API 讀取一定範圍的資料。

優缺點:
Direct 比 Receiver 好的地方:簡化並行、高效、恰好一次語義。
Direct 缺點:需要手動維護讀取 Kakfa 的偏移量到 ZooKeeper。

參考資料:
https://mp.weixin.qq.com/s/C-m1ATNL2udLqo51zSe2Ow

4、Scala 隱式轉換

隱式轉換:我們需要某個類中的一個方法,但是這個類沒有提供這樣的一個方法,所以我們需要隱式轉換,轉換成提供了這個方法的類,然後再呼叫這個方法。
隱式轉換實現的方式:
1)通過伴生物件實現
2)寫一個專門的類用於轉換,需要手動匯入方式

5、堆排序

堆排序是利用堆的性質進行的一種選擇排序。
堆實際上是一棵完全二叉樹,其滿足性質:任何一結點大於等於或者小於等於其左右子樹結點。
堆分為大頂堆和小頂堆,滿足 “任何一結點大於等於其左右子樹結點” 的稱為大頂堆,滿足 “任何一結點小於等於其左右子樹結點” 的稱為小頂堆。
大頂堆的堆頂肯定是最大的,小頂堆的堆頂是最小的。

void HeapAdjust(int array[], int left, int right)
{
    int index = left;
  
    for (int i = left * 2; i <= right; i = i * 2)
    {
        if (i < right && array[i] < array[i + 1])  // 找到孩子中較大者
            i++;
        if (array[index] > array[i])
            return;
        swap(array[index], array[i]);
        index = i;
    }
}

void HeapSort(int array[], int left, int right)
{
    int len = right - left + 1;
  
    for (int i = len / 2; i >= left; i--)  // 把陣列調整成大頂堆
        HeapAdjust(array, i, right);
  
    for (int i = right; i > left; i--)     // 排序
    {
        swap(array[left], array[i]);
        HeapAdjust(array, left, i - 1);
    }
}

堆排序時間複雜度:O(nlogn)
參考資料:
https://mp.weixin.qq.com/s/0H9jQDjG4oMv3nxEcJiCOw

7、Linux 如何檢視埠是否佔用

netstat -anp | grep 3306
如果埠的連線狀態是 listen,說明被佔用了。

tcp6       0      0 :::3306                 :::*                    LISTEN      5364/mysqld
tcp6       0      0 192.168.56.10:3306      192.168.56.10:35180     ESTABLISHED 5364/mysqld
tcp6       0      0 192.168.56.10:3306      192.168.56.10:35174     ESTABLISHED 5364/mysqld

參考資料:
https://www.cnblogs.com/shining5/p/8074080.html

8、Impala 和 Spark SQL 的比較

兩者都可以很好地處理結構化資料,都是基於記憶體計算的。
Imapla 是 MPP 分散式查詢引擎,適用於即席查詢。
Spark SQL 常用於基於Spark RDD 的運算。

個人經驗:
實際生產中使用 impala 場景比較多,impala 查詢速度快,效能好。但是有一點需要注意,impala 的後設資料快取機制,在寫入資料到hive後,不能立即用 impala 查詢到資料,因為有快取機制。需要清理快取重新索引後,才能在 impala 上查到資料。

invalidata metadata <tablename> ;
或者
refresh <tablename> ; 

這兩個方式也有區別,涉及到 schema 變動的,必須使用 invalidata metadata ;

參考資料:
https://mp.weixin.qq.com/s/w7p2oZ-Yt_QYr7kbIkzgrg
https://blog.csdn.net/qq_35995514/article/details/102897599

9、Redis 持久化策略

RDB、AOF持久化策略。

RDB(=Redis DataBase):把資料以快照的形式儲存在磁碟上,這是預設的持久化策略,在配置檔案裡可以配置觸發持久化操作的條件。

AOF(Append Only File):將每一個收到的寫命令都通過write函式追加到檔案中。

優缺點:
1)RDB 在恢復大資料集時的速度比 AOF 的恢復速度要快。
2)在資料丟失的情況下,AOF 丟失的資料比 RDB 少。
3)RDB 檔案比 AOF 小

專案 RDB AOF
啟動優先順序
檔案體積
恢復速度
資料安全性 丟資料 根據策略決定
輕重

參考資料:
https://segmentfault.com/a/1190000016021217

10、 Redis 叢集

Redis 叢集的三種模式:
主從模式複製、哨兵模式、Cluster 模式。
1)主從複製模式
以主庫為準,從庫內容非同步複製主資料庫,從而達成主從內容基本一致的情況。
特點:
1.master一般是接受讀寫的,slave只接受讀操作。
2.當master接受寫操作後會將命令傳送給slave執行,從而實現資料一致性
3.一個master下面可以有多個slave,但是一個slave上面只能有一個master
原理:
1 從伺服器連線主伺服器傳送sync命令。
2 主伺服器持久化資料生成rdb檔案並快取這段時間的寫命令
3 主伺服器向從伺服器傳送rdb檔案和快取的命令
4 從伺服器載入rdb快照後執行快取的命令(從伺服器初始化完成)
5 主伺服器每接收到一個寫命令就傳送給從伺服器執行(從伺服器初始化完成後的操作)

2)哨兵模式
哨兵模式是建立在主從模式基礎之上,從節點使用哨兵模式進行監控主節點,如果主掛了,從庫自動升級為主節點,等待主庫恢復了,主庫會自動變為從庫。
此時,如果升級為主庫的從節點掛了,此時變為從庫的主節點不會變為主庫,出現這種問題,我們一般採用的是主從都進行哨兵模式配置,互相監控對方,從而達到高可用。

3)Cluster 模式
cluster模式採用了無中心節點的方式來實現,每個主節點都會與其它主節點保持連線。節點間通過gossip協議交換彼此的資訊,同時每個主節點又有一個或多個從節點。
客戶端連線叢集時,直接與redis叢集的每個主節點連線,根據hash演算法取模將key儲存在不同的雜湊槽上;
在叢集中採用資料分片的方式,將redis叢集分為16384個雜湊槽。這些雜湊槽分別儲存於三個主節點中。
每個節點會儲存一份資料分佈表,節點會將自己的slot資訊傳送給其他節點,節點間不停的傳遞資料分佈表。
客戶端連線叢集時,通過叢集中某個節點地址進行連線。客戶端嘗試向這個節點執行命令時,比如獲取某個key值,如果key所在的slot剛好在該節點上,則能夠直接執行成功。如果slot不在該節點,則節點會返回MOVED錯誤,同時把該slot對應的節點告訴客戶端,客戶端可以去該節點執行命令。

參考資料:
https://mp.weixin.qq.com/s/S1n16saQwuv51rsNvCrlnQ
https://mp.weixin.qq.com/s/oH2uzyVJTiU031WzuehDHA

11.如果目前有一個實際的業務場景,如何資料建模?

1)數倉分層:ODS層 -> DW層(DWD|DWS|DWB) -> ADS層
好處:清晰資料結構、資料血緣追蹤、資料血緣追蹤、把複雜問題簡單化、把複雜問題簡單化。

2)建模方法:維度建模 or 關係建模
維度建模:
維度建模以分析決策的需求出發構建模型,構建的資料模型為分析需求服務,因此它重點解決使用者如何更快速完成分析需求,同時還有較好的大規模複雜查詢的響應效能,更直接面向業務。
星型模型:由一個事實表和一組維表組成。每個維表都有一個維作為主鍵,所有這些維的主鍵組合成事實表的主鍵。強調的是對維度進行預處理,將多個維度集合到一個事實表,形成一個寬表。
優點:技術要求不高,快速上手,敏捷迭代,快速交付;更快速完成分析需求,較好的大規模複雜查詢的響應效能
缺點:維度表的冗餘會較多,視野狹窄

關係建模:
是資料倉儲之父Inmon推崇的、從全企業的高度設計一個3NF模型的方法,用實體加關係描述的資料模型描述企業業務架構,在正規化理論上符合3NF,站在企業角度面向主題的抽象,而不是針對某個具體業務流程的實體物件關係抽象。
雪花模型:一個或多個維表沒有直接連線到事實表上,而是通過其他維表連線到事實表上時,其圖解就像多個雪花連線在一起。
優點:規範性較好,冗餘小,資料整合和資料一致性方面得到重視,比如運營商可以參考國際電信運營業務流程規範(ETOM),有所謂的最佳實踐。
缺點:需要全面瞭解企業業務、資料和關係;實施週期非常長,成本昂貴;對建模人員的能力要求也非常高,容易爛尾。

個人理解:
在上一家公司使用的是維度建模,快速迭代快速交付,因為公司業務以及部門之間的協同關係,沒辦法從一個全域性的高度來架構整個資料倉儲,只能先跟著專案需求走,完成資料倉儲的搭建和後續的報表、使用者畫像的需求開發。

參考資料:
https://mp.weixin.qq.com/s/lo_nIKpIl5G47XUvsEWtYw

相關文章