中國大數據教育領跑者

IT培訓上市機構

您現在的位置:首頁 > 大數據培訓 > 大數據面試題>大數據面試題整理 -- hadoop 部分(2)>

大數據面試題整理 -- hadoop 部分(2)

2019-04-12 13:29:06 作者:魔據大數據學院

 11. mapreduce 的 shuffle 調優參數

 
具體參考:MapReduce Shuffle性能調優
 
Map 端優化參數
 
選項 類型 默認值 描述
io.sort.mb int 100 緩存map中間結果的buffer大小(MB)
io.sort.record.percent float 0.05 io.sort.mb中用來保存map output記錄邊界的百分比,其他緩存用來保存數據
io.sort.spill.percent float 0.80 map開始做spill操作的閾值
io.sort.factor int 10 做merge操作時同時操作的stream數上限
min.num.spill.for.combine int 3 combiner函數運行的最小spill數
mapred.compress.map.output boolean false map中間結果是否采用壓縮
mapred.map.output.compression.codec class name org.apache.hadoop.io.compress.DefaultCodec map中間結果的壓縮格式
Reduce 端優化參數
 
選項 類型 默認值 描述
mapred.reduce.parallel.copies int 5 每個reduce并行下載map結果的最大線程數
mapred.reduce.copy.backoff int 300 reduce下載線程最大等待時間(in sec)
io.sort.factor int 10 同上
mapred.job.shuffle.input.buffer.percent float 0.7 用來緩存shuffle數據的reduce task heap百分比
mapred.job.shuffle.merge.percent float 0.66 緩存的內存中多少百分比后開始做merge操作
mapred.job.reduce.input.buffer.percent float 0.0 sort完成后reduce計算階段用來緩存數據的百分比
12. hive 都在 mysql 中建了哪些表,分別用來干什么
 
詳情參考一下連接:
 
Hive的元數據表結構詳解
 
重要的表有:
 
存儲Hive版本的元數據表(VERSION)
 
Hive數據庫相關的元數據表(DBS、DATABASE_PARAMS)
 
Hive 表和視圖相關的元數據表(TBLS、TABLE_PARAMS、TBL_PRIVS,這三張表通過TBL_ID關聯)
 
Hive 表分區相關的元數據表(主要涉及 PARTITIONS、PARTITION_KEYS、PARTITION_KEY_VALS、PARTITION_PARAMS)
 
Hive 文件存儲信息相關的元數據表(主要涉及SDS、SD_PARAMS、SERDES、SERDE_PARAMS)
 
13. hive 面試用神 sql,級聯求和
 
需求:現有用戶的每月消費金額情況如下,希望輸出的結果如下,請用一個 hive sql 實現:
 
用戶 時間 金額
A 2015-01 5
A 2015-01 15
B 2015-01 5
A 2015-01 8
B 2015-01 25
A 2015-01 5
A 2015-02 4
A 2015-02 6
B 2015-02 10
B 2015-02 5
要求輸出結果:
 
+---------+----------+--------+-------------+--+
| a.name  |  a.time  | count  | accumulate  |
+---------+----------+--------+-------------+--+
| A       | 2015-01  | 33     | 33          |
| A       | 2015-02  | 10     | 43          |
| B       | 2015-01  | 30     | 30          |
| B       | 2015-02  | 15     | 45          |
+---------+----------+--------+-------------+--+
實現思路:
 
第一步,先求個用戶的月總金額
select username,month,sum(salary) as salary from t_access_times group by username,month
 
+-----------+----------+---------+--+
| username  |  month   | salary  |
+-----------+----------+---------+--+
| A         | 2015-01  | 33      |
| A         | 2015-02  | 10      |
| B         | 2015-01  | 30      |
| B         | 2015-02  | 15      |
+-----------+----------+---------+--+
第二步,將月總金額表 自己連接 自己連接
 
select *
from 
(select username,month,sum(salary) as salary from t_access_times group by username,month) A 
inner join 
(select username,month,sum(salary) as salary from t_access_times group by username,month) B
on
A.username=B.username
 
+-------------+----------+-----------+-------------+----------+-----------+--+
| a.username  | a.month  | a.salary  | b.username  | b.month  | b.salary  |
+-------------+----------+-----------+-------------+----------+-----------+--+
| A           | 2015-01  | 33        | A           | 2015-01  | 33        |
| A           | 2015-01  | 33        | A           | 2015-02  | 10        |
| A           | 2015-02  | 10        | A           | 2015-01  | 33        |
| A           | 2015-02  | 10        | A           | 2015-02  | 10        |
| B           | 2015-01  | 30        | B           | 2015-01  | 30        |
| B           | 2015-01  | 30        | B           | 2015-02  | 15        |
| B           | 2015-02  | 15        | B           | 2015-01  | 30        |
| B           | 2015-02  | 15        | B           | 2015-02  | 15        |
+-------------+----------+-----------+-------------+----------+-----------+--+
 
第三步,從上一步的結果中進行分組查詢,分組的字段是 a.username a.month。求月累計值:將 b.month <= a.month 的所有 b.salary 求和即可
select A.username,A.month,max(A.salary) as salary,sum(B.salary) as accumulate
from 
(select username,month,sum(salary) as salary from t_access_times group by username,month) A 
inner join 
(select username,month,sum(salary) as salary from t_access_times group by username,month) B
on
A.username=B.username
where B.month <= A.month
group by A.username,A.month
order by A.username,A.month;
 
 
+---------+----------+--------+-------------+--+
| a.name  |  a.time  | count  | accumulate  |
+---------+----------+--------+-------------+--+
| A       | 2015-01  | 33     | 33          |
| A       | 2015-02  | 10     | 43          |
| B       | 2015-01  | 30     | 30          |
| B       | 2015-02  | 15     | 45          |
+---------+----------+--------+-------------+--+
14. sqoop 在導入數據到 mysql 中,如何讓數據不重復導入?如果存在數據問題 sqoop如何處理?
 
--update-key ID --update-mode allowinsert,如何數據存在就更新,不存在就插入。
 
15. 使用 Hive 或者自定義 MapReduce 實現如下邏輯:
 
product_no  lac_id moment start_time user_id county_id staytime city_id
13429100031 22554 8 2013-03-11 08:55:19.151754088 571 571 282 571
13429100082 22540 8 2013-03-11 08:58:20.152622488 571 571 270 571
13429100082 22691 8 2013-03-11 08:56:37.149593624 571 571 103 571
13429100087 22705 8 2013-03-11 08:56:51.139539816 571 571 220 571
13429100087 22540 8 2013-03-11 08:55:45.150276800 571 571 66 571
13429100082 22540 8 2013-03-11 08:55:38.140225200 571 571 133 571
13429100140 26642 9 2013-03-11 09:02:19.151754088 571 571 18 571
13429100082 22691 8 2013-03-11 08:57:32.151754088 571 571 287 571
13429100189 22558 8 2013-03-11 08:56:24.139539816 571 571 48 571
13429100349 22503 8 2013-03-11 08:54:30.152622440 571 571 211 571
字段解釋:
 
product_no:用戶手機號
 
lac_id:用戶所在基站
 
start_time:用戶在此基站的開始時間
 
staytime:用戶在此基站的逗留時間
 
需求描述:
 
根據 lac_id 和 start_time 知道用戶當時的位置,根據 staytime 知道用戶各個基站的逗留時長。根據軌跡合并連續基站的 staytime。最終得到每一個用戶按時間排序在每一個基站駐留時長
 
期望輸出舉例:
 
13429100082 22540 8 2013-03-11 08:58:20.152622488 571 571 270 571
13429100082 22691 8 2013-03-11 08:56:37.149593624 571 571 390 571
13429100082 22540 8 2013-03-11 08:55:38.140225200 571 571 133 571
13429100087 22705 8 2013-03-11 08:56:51.139539816 571 571 220 571
13429100087 22540 8 2013-03-11 08:55:45.150276800 571 571 66 571
考慮用 mapreduce 實現
 
實現參考MR 基站
 
問題分析:針對每個product_no按照start_time進行排序(本例降序),如果相鄰兩項的lac_id相同,則將staytime進行相加保存到后一項中,并將前一項移除。
 
自己已經做出來了。
 
請隨意使用各種類型的腳本語言實現:批量將指定目錄下的所有文件中的 $HADOOP_HOME$替換成/home/ocetl/app/hadoop
 
Python(沒有驗證)
 
import string,os,sys dir=’/var’
 
files=os.listdir(dir) for f in files: tmpContents = ‘’; for s in f.readlines(): tmpContents += s.replace(“$HADOOP_HOME$”,”/home/ocetl/app/hadoop”)
 
f.write(tmpContents) f.close()
shell(已驗證)
 
#!/bin/bash
ls $1 | while read line
do
sed -i 's,\$HADOOP_HOME\$,\/home\/hadoop,g' $1$line
echo $1$line
done
16. mapreduce 的 shuffle 執行流程
 
maptask中的 OutputCollector 收集我們的 map() 方法輸出的 kv 對,放到內存緩沖區(環形緩沖區)中(默認 100M)
 
當緩沖區的存儲的數據超過了閾值(默認80%)時,會調用 spiller 線程從內存緩沖區溢出到本地磁盤文件,可能會溢出多個文件
 
多個溢出文件會被合并成大的溢出文件
 
在溢出過程中,及合并的過程中,都要調用 partitoner 進行分區和針對 key 進行排序(默認是快速排序)
 
reducetask 根據自己的分區號,去各個 maptask 機器上取相應的結果分區數據,將這些文件再進行合并和排序(歸并排序)。
 
reducetask 合并完成后,shuffle 的過程也就結束了,后面進入 reducetask 的邏輯運算過程。
 
Shuffle 中的緩沖區大小會影響到 mapreduce 程序的執行效率,==原則上說,緩沖區越大,磁盤 io 的次數越少,執行速度就越快==
 
緩沖區的大小可以通過參數調整, 參數:io.sort.mb 默認100M
 
17. hdfs 的 checkpoint 過程描述
 
HA 模式下的元數據合并
 
在HA模式下checkpoint過程由StandBy NameNode來進行,以下簡稱為SBNN,Active NameNode簡稱為ANN。
 
主要由4個步驟:
 
SBNN 檢查是否達到 checkpoint 條件:離上一次 checkpoint 操作是否已經有一個小時,或者 HDFS 已經進行了100萬次操作。
 
SBNN 檢查達到 checkpoint 條件后,將 ANN 的最后一次操作日志讀取到本地,將磁盤中的 fsimage 文件和 edits 文件加載到內存,合并成一份新的 fsimage 文件
 
然后 SBNN 通過 HTTP 聯系 ANN。
 
ANN 通過 HTTP 方式從 SBNN 獲取最新的 fsimage 文件并將舊的 fsimage 文件刪除。
 
由于HA機制,會使得Standby NameNode和Active NameNode都擁有最新的fsimage和edits文件。
 
非 HA 模式的元數據合并
 
內存中有一份完整的元數據
 
磁盤有一個“準完整”的元數據鏡像
 
當客戶端對 hdfs 中的文件進行新增或者修改操作,相應的記錄首先被記入 edits 這種 log 日志中,當客戶端操作成功后,相應的元數據會更新到內存中
 
每隔一段時間,會由secondary namenode將namenode上積累的所有edits和一個最新的fsimage下載到本地,并加載到內存進行merge(合并)(這個過程稱為checkpoint)
 
secondary namenode將合并好之后的新的fsimage鏡像文件回傳給namenode,namenode將舊的fsimage刪除使用新的fsimage和新的edits.inprogress文件
 
namenode 和 secondary namenode 的工作目錄存儲結構完全相同,所以,當 namenode 故障退出需要重新恢復時,可以從 secondary namenode 的工作目錄中將 fsimage 拷貝到 namenode 的工作目錄,以恢復 namenode 的元數據
 
這樣做的缺點就是:secondary namenode 的 fsimage 不是最新的。
 
什么時候進行 checkpoint?
 
由兩個參數
 
dfs.namenode.checkpoint.preiod (兩次checkpoint之間的時間間隔,默認值是3600秒,即 1 小時)
dfs.namenode.checkpoint.txns (兩次checkpoint之間最大的操作記錄,默認值是 100萬次 )來決定。
period 參數表示,經過 1 小時就進行一次 checkpoint,txns 參數表示,hdfs 經過 100 萬次操作后就要進行 checkpoint 了。這兩個參數任意一個得到滿足,都會觸發 checkpoint 過程。進行 checkpoint 的節點每隔 dfs.namenode.checkpoint.check.period (默認值是 60 )秒就會去統計一次 hdfs 的操作次數。
 
18. hdfs 的讀數據流程
 
client跟namenode通信查詢元數據,找到文件塊所在的datanode服務器
 
分別連接目標datanode,并發讀取文件塊,并在合并讀取到的文件
 
datanode 以 packet 為單位向客戶端發送。客戶端接收后先存在本地緩存,然后再寫入文件。
 
19. hdfs 的寫數據流程
 
client 跟 namenode 通信請求上傳文件,namenode 檢查目標文件是否已存在(文件已存在則報錯不能上傳),父目錄是否存在(目錄不存在報錯無法上傳),以及客戶端是否有新建文件的權限。
 
namenode 返回是否可以上傳,如果可以上傳,namenode 會返回這個文件是否被分塊以及分塊的具體信息。
 
client 請求第一個 block 該傳輸到哪些 datanode 服務器上
 
namenode 返回 3 個 datanode 服務器 ABC
 
client 請求 3 臺 dn 中的一臺 A 上傳數據(本質上是一個 RPC 調用,建立 pipeline,連接離自己最近的 datanode),A收到請求會繼續調用 B,然后 B 調用 C,將整個 pipeline 建立完成,逐級返回客戶端
 
client開始往A上傳第一個block(先從磁盤讀取數據放到一個本地內存緩存),以packet為單位,A收到一個packet就會傳給B,B傳給C;A每傳一個packet會放入一個應答隊列等待應答
 
當一個block傳輸完成之后,client再次請求namenode上傳第二個block的服務器,以此類推。
 
如果傳輸過程中,有某個 datanode 出現了故障,那么當前的 pipeline 會被關閉,出現故障的 datanode 會從當前的 pipeline 中移除,剩余的 block 會繼續剩下的 datanode 中繼續以 pipeline 的形式傳輸,同時 Namenode 會分配一個新的 datanode,保持 replicas 設定的數量。
 
20. Hive sql 優化解決數據傾斜問題
 
Hive 中出現數據傾斜的情況,一般發生在 sql 中的 group by 和 join 上,且和數據邏輯綁定比較深。個人認為解決數據傾斜問題的重點應該放在對數據的設計和業務的理解上。
 
優化方案:
 
使用 map side join,參考 hive使用技巧(四)——巧用MapJoin解決數據傾斜問題
 
針對 count(distinct) 操作,先轉換成 group,然后再外面加上 count
 
Hive 的萬能鑰匙:hive.groupby.skewindata=true
 
left semi join 使用,實現 in 操作
 
盡量盡早的過濾數據,減少每個階段的數據量,把 where 條件寫到 join 的里面,減少 join 的數據量。
 
針對大量 key 為空的情況,將空的 key 和非空 key 做區分,空的 key 不做 join 操作。
 
避免使用 order by,原因如下:order by 會對輸入做全局排序,因此只有一個 reducer,會導致當輸入規模較大時,需要較長的計算時間。
 
盡量避免一個 sql 包含復雜的邏輯,可以將整個步驟拆分成多個中間表來完成。
 
join 操作,數據量小的表要放在 join 的左邊
 
union all 的部分大于 2,或每個 union 的部分數據量很大,那么應該拆分成多個 insert into 語句。
 
具體參考 hive的查詢注意事項以及優化總結
 
9. hbase 的 rowkey 設計原則
 
rowkey長度原則
 
==建議越短越好,不要超過16個字節==,原因如下:
 
數據的持久化文件HFile中是按照KeyValue存儲的,如果rowkey過長,比如超過100字節,1000w行數據,光rowkey就要占用100*1000w=10億個字節,將近1G數據,這樣會極大影響HFile的存儲效率。
MemStore將緩存部分數據到內存,如果rowkey字段過長,內存的有效利用率就會降低,系統不能緩存更多的數據,這樣會降低檢索效率。
目前操作系統都是64位系統,內存8字節對齊,控制在16個字節,8字節的整數倍利用了操作系統的最佳特性。
rowkey散列原則
 
如果rowkey按照時間戳的方式遞增,不要將時間放在二進制碼的前面,建議將rowkey的高位作為散列字段,由程序隨機生成,低位放時間字段,這樣將提高數據均衡分布在每個RegionServer,以實現負載均衡的幾率。如果沒有散列字段,首字段直接是時間信息,所有的數據都會集中在一個RegionServer上,這樣在數據檢索的時候負載會集中在個別的RegionServer上,造成熱點問題,會降低查詢效率。
 
rowkey唯一原則
 
必須在設計上保證其唯一性,rowkey是按照字典順序排序存儲的,因此,設計rowkey的時候,要充分利用這個排序的特點,將經常讀取的數據存儲到一塊,將最近可能會被訪問的數據放到一塊。
 
10. hbase 常見的避免熱點的方法
 
加鹽
 
這里所說的加鹽不是密碼學中的加鹽,而是在rowkey的前面增加隨機數,具體就是給rowkey分配一個隨機前綴以使得它和之前的rowkey的開頭不同。分配的前綴種類數量應該和你想使用數據分散到不同的region的數量一致。加鹽之后的rowkey就會根據隨機生成的前綴分散到各個region上,以避免熱點。
 
哈希
 
哈希會使同一行永遠用一個前綴加鹽。哈希也可以使負載分散到整個集群,但是讀卻是可以預測的。使用確定的哈希可以讓客戶端重構完整的rowkey,可以使用get操作準確獲取某一個行數據
 
反轉
 
第三種防止熱點的方法時反轉固定長度或者數字格式的rowkey。這樣可以使得rowkey中經常改變的部分(最沒有意義的部分)放在前面。這樣可以有效的隨機rowkey,但是犧牲了rowkey的有序性。
 
反轉rowkey的例子以手機號為rowkey,可以將手機號反轉后的字符串作為rowkey,這樣的就避免了以手機號那樣比較固定開頭導致熱點問題
 
時間戳反轉
 
一個常見的數據處理問題是快速獲取數據的最近版本,使用反轉的時間戳作為rowkey的一部分對這個問題十分有用,可以用 Long.Max_Value - timestamp 追加到key的末尾,例如 [key][reverse_timestamp] , [key] 的最新值可以通過scan [key]獲得[key]的第一條記錄,因為HBase中rowkey是有序的,第一條記錄是最后錄入的數據。
 
比如需要保存一個用戶的操作記錄,按照操作時間倒序排序,在設計rowkey的時候,可以這樣設計
 
[userId反轉][Long.Max_Value - timestamp],在查詢用戶的所有操作記錄數據的時候,直接指定反轉后的userId,startRow是[userId反轉][000000000000],stopRow是[userId反轉][Long.Max_Value - timestamp]
 
如果需要查詢某段時間的操作記錄,startRow是[user反轉][Long.Max_Value - 起始時間],stopRow是[userId反轉][Long.Max_Value - 結束時間]
 
11. hbase 的列族如何設計
 
hbase 列族設計優化文章
 
Hbase官方文檔中寫明,目前列族數量最優不超過3個。原因如下:
 
每個 RegionServer 包含多個 Region,每個 Region 包含多個Store,每個 Store 包含一個 MemStore 和多個 StoreFile。
 
在 Hbase 的表中,每個列族對應 Region 中的一個Store,Region的大小達到閾值時會分裂,因此如果表中有多個列族,則可能出現以下現象:
 
一個Region中有多個Store,如果每個CF的數據量分布不均勻時,比如CF1為100萬,CF2為1萬,則 Region分裂時導致CF2在每個Region中的數據量太少,查詢CF2時會橫跨多個Region導致效率降低。
 
如果每個CF的數據分布均勻,比如CF1有50萬,CF2有50萬,CF3有50萬,則Region分裂時導致每個 CF 在Region的數據量偏少,查詢某個CF時會導致橫跨多個Region的概率增大。
 
多個CF代表有多個Store,也就是說有多個MemStore,也就導致內存的消耗量增大,使用效率下降。
 
Region 中的 緩存刷新 和 壓縮 是基本操作,即一個CF出現緩存刷新或壓縮操作,其它CF也會同時做一樣的操作,當列族太多時就會導致IO頻繁的問題。
 
12. hbase 的整體架構
 
hbase 架構圖
HMaster
HMaster用于協調多個 HRegionServer,偵測各個RegionServer之間的狀態,并平衡RegionServer之間的負載。HMaster還有一個職責就是負責分配Region給RegionServer。==如果無Master過程中,數據讀取仍照常進行,但是,region切分、負載均衡等無法進行==
 
HRegionServer
對于一個HRegionServer而言,其包括了多個HRegion。HRegionServer的作用只是管理表格,以及實現讀寫操作。Client直接連接HRegionServer,并通信獲取HBase中的數據。對于Region而言,則是真實存放HBase數據的地方,也就說Region是HBase可用性和分布式的基本單位.==每個 RegionServer 包含多個 Region,每個 Region 包含多個Store,每個 Store 包含一個 MemStore 和多個 StoreFile。每個 HStore 對應 Table 中的一個 Column Familiy 的存儲。==
 
Zookeeper
對于 HBase 而言,Zookeeper的作用是至關重要的。首先Zookeeper是作為HBase Master的HA解決方案。也就是說,是Zookeeper保證了至少有一個HBase Master 處于運行狀態。并且Zookeeper負責Region和Region Server的注冊。
 
22. mapreduce 中的 MRAppMaster 和 YarnChild 的作用分別是什么?
 
MRAppMaster
 
在YARN中,MRAppMaster負責管理MapReduce作業的生命周期,包括作業管理、資源申請與再分配、Container啟動與釋放、作業恢復等。
 
具體參考:YARN MapReduce MRAppMaster-剖析
 
YarnChild
 
YarnChild:運行具體的 map/reduce task。
 
RunJar:完成job的初始化,包括獲取jobID,將jar包上傳至hdfs等。
 
job啟動過程:
 
ResourceManager,NodeManager->RunJar->MRAppMaster->YarnChild
 
job退出過程:
 
YarnChild->MRAppMaster->RunJar
 
 

相關推薦
[免責聲明]本文來源于網絡轉載,僅供學習交流使用,不構成商業目的。版權歸原作者所有,如涉及作品內容、版權和其它問題請在30日內與本網聯系,我們將在第一時進行處理
六合图库118万众图库

值班手機:18501996998

咨詢QQ: 226594285 / 428683440

校區地址:北京市海淀區中關村科技園首農藍海中心C座-7層

全國咨詢熱線:400-690-5006

點擊關注:

魔據教育官方微博

魔據官方微信