大資料工程師面試題—3
2.13. 簡述hadoop的排程器
FIFO schedular:預設,先進先出的原則
Capacity schedular:計算能力排程器,選擇佔用最小、優先順序高的先執行,依此類推
Fair schedular:公平排程,所有的job具有相同的資源。
2.14. 列出你開發mapreduce的語言
java
2.15. 手寫程式
wordcount
mapper:
String vStr = value.toString().split(",")[3];
ctx.write(new Text(vStr),new IntWriteble(1));
reducer :
for(IntWriteble v : value){
ctx.write(key,v);
}
2.16. 不同語言的優缺點
你認為用Java,Streaming,pipe方式開發map/reduce,各有哪些優缺點。
hadoop是java寫的,java的整合效果最好,並且平臺環境統一。
2.17. hive有哪些儲存元資料的方式,各有什麼特點。
記憶體資料庫derby,安裝小,但是資料存在記憶體,不穩定
mysql資料庫,資料儲存模式可以自己設定,持久化好,檢視方便。
2.18. combiner和partition的作用
combiner是reduce的實現,在map端執行計算任務,減少map端的輸出資料。作用就是優化。但是combiner的使用場景是mapreduce的map
輸出結果和reduce輸入輸出一樣。
partition的預設實現是hashpartition,是map端將資料按照reduce個數取餘,進行分割槽,不同的reduce來copy自己的資料。partition
的作用是將資料分到不同的reduce進行計算,加快計算效果。
2.19. hive內部表和外部表的區別
內部表:載入資料到hive所在的hdfs目錄,刪除時,元資料和資料檔案都刪除
外部表:不載入資料到hive所在的hdfs目錄,刪除時,只刪除表結構。
2.20. hbase的rowkey怎麼建立好?列族怎麼建立比較好?
hbase儲存時,資料按照Row key的字典序(byte order)排序儲存。設計key時,要充分排序儲存這個特性,將經常一起讀取的行儲存放到一起。
(位置相關性)
一個列族在資料底層是一個檔案,所以將經常一起查詢的列放到一個列族中,列族儘量少,減少檔案的定址時間。
2.21. 用mapreduce怎麼處理資料傾斜問題?
資料傾斜:map /reduce程式執行時,reduce節點大部分執行完畢,但是有一個或者幾個reduce節點執行很慢,導致整個程式的處理時間很長,
這是因為某一個key的條數比其他key多很多(有時是百倍或者千倍之多),這條key所在的reduce節點所處理的資料量比其他節點就大很多,
從而導致某幾個節點遲遲執行不完,此稱之為資料傾斜。
用hadoop程式進行資料關聯時,常碰到資料傾斜的情況,這裡提供一種解決方法。
自己實現partition類,用key和value相加取hash值:
方式1:
原始碼:
public int getPartition(K key, V value,int numReduceTasks) {
return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
}
修改後
public int getPartition(K key, V value,int numReduceTasks) {
return (((key).hashCode()+value.hashCode()) & Integer.MAX_VALUE) % numReduceTasks;
}
方式2:
public class HashPartitioner<K, V> extends Partitioner<K, V> {
private int aa= 0;
/** Use {@link Object#hashCode()} to partition. */
public int getPartition(K key, V value,int numReduceTasks) {
return (key.hashCode()+(aa++) & Integer.MAX_VALUE) % numReduceTasks;
}
方式3:
重新設計key
2.22. hadoop框架中怎麼來優化
從應用程式角度進行優化。由於mapreduce是迭代逐行解析資料檔案的,怎樣在迭代的情況下,編寫高效率的應用程式,是一種優化思路。
對Hadoop引數進行調優。當前hadoop系統有190多個配置引數,怎樣調整這些引數,使hadoop作業執行儘可能的快,也是一種優化思路。
從系統實現角度進行優化。這種優化難度是最大的,它是從hadoop實現機制角度,發現當前Hadoop設計和實現上的缺點,然後進行原始碼級
地修改。該方法雖難度大,但往往效果明顯。
linux核心引數調整
2.22.1. 從應用程式角度進行優化
(1) 避免不必要的reduce任務
如果mapreduce程式中reduce是不必要的,那麼我們可以在map中處理資料, Reducer設定為0。這樣避免了多餘的reduce任務。
(2) 為job新增一個Combiner
為job新增一個combiner可以大大減少shuffle階段從map task拷貝給遠端reduce task的資料量。一般而言,combiner與reducer相同。
(3) 根據處理資料特徵使用最適合和簡潔的Writable型別
Text物件使用起來很方便,但它在由數值轉換到文字或是由UTF8字串轉換到文字時都是低效的,且會消耗大量的CPU時間。當處理那些非
文字的資料時,可以使用二進位制的Writable型別,如IntWritable, FloatWritable等。二進位制writable好處:避免檔案轉換的消耗;
使map task中間結果佔用更少的空間。
(4) 重用Writable型別
很多MapReduce使用者常犯的一個錯誤是,在一個map/reduce方法中為每個輸出都建立Writable物件。例如,你的Wordcout mapper方法可能
這樣寫:
public void map(...) {
…
for (String word : words) {
output.collect(new Text(word), new IntWritable(1));
}
}
這樣會導致程式分配出成千上萬個短週期的物件。Java垃圾收集器就要為此做很多的工作。更有效的寫法是:
class MyMapper … {
Text wordText = new Text();
IntWritable one = new IntWritable(1);
public void map(...) {
for (String word: words) {
wordText.set(word);
output.collect(wordText, one);
}
}
}
(5) 使用StringBuffer而不是String
當需要對字串進行操作時,使用StringBuffer而不是String,String是read-only的,如果對它進行修改,會產生臨時物件,
而StringBuffer是可修改的,不會產生臨時物件。
2.22.2. 對引數進行調優
檢視linux的服務,可以關閉不必要的服務
ntsysv
停止列印服務
#/etc/init.d/cups stop
#chkconfig cups off
關閉ipv6
#vim /etc/modprobe.conf
新增內容
alias net-pf-10 off
alias ipv6 off
調整檔案最大開啟數
檢視: ulimit -a 結果:open files (-n) 1024
臨時修改: ulimit -n 4096
持久修改:
vi /etc/security/limits.conf在檔案最後加上:
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
修改linux核心引數
vi /etc/sysctl.conf
新增
net.core.somaxconn = 32768
#web應用中listen函式的backlog預設會給我們核心引數的net.core.somaxconn限制到128,而nginx定義的NGX_LISTEN_BACKLOG預設為511,
所以有必要調整這個值。
調整swap分割槽什麼時候使用:
檢視:cat /proc/sys/vm/swappiness
設定:vi /etc/sysctl.conf
在這個文件的最後加上這樣一行: vm.swappiness=10
表示實體記憶體使用到90%(100-10=90)的時候才使用swap交換區
關閉noatime
vi /etc/fstab
/dev/sda2 /data ext3 noatime,nodiratime 0 0
設定readahead buffer
blockdev --setra READAHEAD 512 /dev/sda
以下是修改mapred-site.xml檔案
修改最大槽位數
槽位數是在各個tasktracker上的mapred-site.xml上設定的,預設都是2
<property>
<name>mapred.tasktracker.map.tasks.maximum</name>
<!--maptask的最大數-->
<value>2</value>
</property>
<property>
<name>mapred.tasktracker.reduce.tasks.maximum</name>
<!--reducetask的最大數-->
<value>2</value>
</property>
調整心跳間隔
叢集規模小於300時,心跳間隔為300毫秒
mapreduce.jobtracker.heartbeat.interval.min 心跳時間
mapred.heartbeats.in.second 叢集每增加多少節點,時間增加下面的值
mapreduce.jobtracker.heartbeat.scaling.factor 叢集每增加上面的個數,心跳增多少
啟動帶外心跳
mapreduce.tasktracker.outofband.heartbeat 預設是false
配置多塊磁碟
mapreduce.local.dir
配置RPC hander數目
mapred.job.tracker.handler.count 預設是10,可以改成50,根據機器的能力
配置HTTP執行緒數目
tasktracker.http.threads 預設是40,可以改成100 根據機器的能力
選擇合適的壓縮方式
以snappy為例:
<property>
<name>mapred.compress.map.output</name>
<value>true</value>
</property>
<property>
<name>mapred.map.output.compression.codec</name>
<value>org.apache.hadoop.io.compress.SnappyCodec</value>
</property>
啟用推測執行機制
推測執行(Speculative Execution)是指在分散式叢集環境下,因為程式BUG,負載不均衡或者資源分佈不均等原因,造成同一個job的多個
task執行速度不一致,有的task執行速度明顯慢於其他task(比如:一個job的某個task進度只有10%,而其他所有task已經執行完畢),
則這些task拖慢了作業的整體執行進度,為了避免這種情況發生,Hadoop會為該task啟動備份任務,讓該speculative task與原始task同時
處理一份資料,哪個先執行完,則將誰的結果作為最終結果。
推測執行優化機制採用了典型的以空間換時間的優化策略,它同時啟動多個相同task(備份任務)處理相同的資料塊,哪個完成的早,則採用哪個task的結果,這樣可防止拖後腿Task任務出現,進而提高作業計算速度,但是,這樣卻會佔用更多的資源,在叢集資源緊缺的情況下,設計合理的推測執行機制可在多用少量資源情況下,減少大作業的計算時間。
mapred.map.tasks.speculative.execution 預設是true
mapred.rduce.tasks.speculative.execution 預設是true
設定是失敗容忍度
mapred.max.map.failures.percent 作業允許失敗的map最大比例 預設值0,即0%
mapred.max.reduce.failures.percent 作業允許失敗的reduce最大比例 預設值0,即0%
mapred.map.max.attemps 失敗後最多重新嘗試的次數 預設是4
mapred.reduce.max.attemps 失敗後最多重新嘗試的次數 預設是4
啟動jvm重用功能
mapred.job.reuse.jvm.num.tasks 預設值1,表示只能啟動一個task,若為-1,表示可以最多執行數不限制
設定任務超時時間
mapred.task.timeout 預設值600000毫秒,也就是10分鐘。
合理的控制reduce的啟動時間
mapred.reduce.slowstart.completed.maps 預設值0.05 表示map任務完成5%時,開始啟動reduce任務
跳過壞記錄
當任務失敗次數達到該值時,才會進入skip mode,即啟用跳過壞記錄數功能,也就是先試幾次,不行就跳過
mapred.skip.attempts.to.start.skipping 預設值 2
map最多允許跳過的記錄數
mapred.skip.map.max.skip.records 預設值0,為不啟用
reduce最多允許跳過的記錄數
mapred.skip.reduce.max.skip.records 預設值0,為不啟用
換記錄存放的目錄
mapred.skip.out.dir 預設值${mapred.output.dir}/_logs/