【面試題】大數據開發第1輪面試

面試總結:

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 的記憶體使用。

參考資料:
//mp.weixin.qq.com/s/2KFZp4bHKw9iNyDPOTim1A
//issues.apache.org/jira/browse/HDFS-8998
//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,所以這個成本很值得。

參考資料:
//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。

參考資料:
//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)
參考資料:
//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

參考資料:
//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 ;

參考資料:
//mp.weixin.qq.com/s/w7p2oZ-Yt_QYr7kbIkzgrg
//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
啟動優先順序
文件體積
恢復速度
數據安全性 丟數據 根據策略決定
輕重

參考資料:
//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對應的節點告訴客戶端,客戶端可以去該節點執行命令。

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

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

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

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

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

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

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