第1部分 申請ID.. 3html
第2部分 部署kafka. 4java
2.1 部署86節點kafka. 4node
2.2 配置86節點zookeeper. 5mysql
2.3 部署87節點kafka. 5linux
2.4 配置87節點zookeeper. 5ios
第3部分 啓動zookeeper. 5c++
3.1 啓動86節點啓動zookeeper-1服務... 5web
3.2 啓動87節點啓動zookeeper-二、zookeeper-3服務... 6面試
第4部分 啓動kafka. 6正則表達式
4.1 啓動86節點kafka服務... 6
4.2 啓動87節點kafka服務... 6
第5部分 建立topic. 7
5.1 測試Topic(可選)... 7
5.2 建立生產的topic. 7
第1部分 選擇題
1.1 Hadoop選擇題
1.1.1 Hdfs
1. 下面哪一個程序負責 HDFS 數據存儲?
a)NameNode
b)Jobtracker
c)Datanode
d)secondaryNameNode
e)tasktracker
2. HDfS 中的 block 默認保存幾份?
a)3份
b)2份
c)1份
d)不肯定
3. 下列哪一個程序一般與NameNode 在一個節點啓動?
a)SecondaryNameNode
b)DataNode
c)TaskTracker
d)Jobtracker
注:haoop1.X
分析:
hadoop 的集羣是基於 master/slave 模式,namenode 和 jobtracker 屬於 master,datanode 和 tasktracker屬於 slave,master 只有一個,而 slave 有多個。SecondaryNameNode 內存需求和 NameNode 在一個數量級上,因此一般 secondary NameNode(運行在單獨的物理機器上)和 NameNode 運行在不一樣的機器上。
JobTracker 和 TaskTracker
JobTracker 對應於 NameNode
TaskTracker 對應於 DataNode
DataNode 和 NameNode 是針對數據存放來而言的
JobTracker 和 TaskTracker 是對於 MapReduce 執行而言的
mapreduce 中幾個主要概念,mapreduce 總體上能夠分爲這麼幾條執行線索:
jobclient,JobTracker 與 TaskTracker。
一、JobClient 會在用戶端經過 JobClient 類將應用已經配置參數打包成 jar 文件存儲到 hdfs,並把路徑提交到 Jobtracker,而後由 JobTracker 建立每個 Task(即 MapTask 和 ReduceTask)並將它們分發到各個 TaskTracker 服務中去執行
二、JobTracker 是一個 master 服務,軟件啓動以後 JobTracker 接收 Job,負責調度 Job 的每個子任務 task運行於 TaskTracker 上,並監控它們,若是發現有失敗的 task 就從新運行它。通常狀況應該把 JobTracker 部署在單獨的機器上。
三、TaskTracker 是運行在多個節點上的 slaver 服務。TaskTracker 主動與 JobTracker 通訊,接收做業,並負責直接執行每個任務。TaskTracker 都須要運行在 HDFS 的 DataNode 上
4. HDFS 默認 Block Size
a)32MB
b)64MB
c)128MB
注:舊版本是64MB
5. Client 端上傳文件的時候下列哪項正確
a)數據通過 NameNode 傳遞給 DataNode
b)Client 端將文件切分爲 Block,依次上傳
c)Client 只上傳數據到一臺 DataNode,而後由 NameNode 負責 Block 複製工做
分析:
Client 向 NameNode 發起文件寫入的請求。
NameNode 根據文件大小和文件塊配置狀況,返回給 Client 它所管理部分 DataNode 的信息。
Client 將文件劃分爲多個 Block,根據 DataNode 的地址信息,按順序寫入到每個 DataNode 塊中。
6. 下面與 HDFS 相似的框架是?C
A NTFS
B FAT32
C GFS
D EXT3
7. 的
8. 的
1.1.2 集羣管理
1. 下列哪項一般是集羣的最主要瓶頸
a)CPU
b)網絡
c)磁盤 IO
d)內存
解析:
因爲大數據面臨海量數據,讀寫數據都須要 io,而後還要冗餘數據,hadoop 通常備 3 份數據,因此 IO就會打折扣。
2. 關於SecondaryNameNode 哪項是正確的?
a)它是 NameNode 的熱備
b)它對內存沒有要求
c)它的目的是幫助 NameNode 合併編輯日誌,減小 NameNode 啓動時間
d)SecondaryNameNode 應與 NameNode 部署到一個節點
3. 下列哪項能夠做爲集羣的管理?
a)Puppet b)Pdsh c)ClouderaManager d)Zookeeper
分析:
A:puppetpuppet 是一種 Linux、Unix、windows 平臺的集中配置管理系統
B:pdsh 能夠實如今在多臺機器上執行相同的命令
詳細參考:集羣管理小工具介紹-pdsh
C:能夠參考 Cloudera Manager 四大功能【翻譯】
首先這裏給管理下一個定義:部署、配置、調試、監控,屬於管理
4. 配置機架感知的下面哪項正確
a)若是一個機架出問題,不會影響數據讀寫
b)寫入數據的時候會寫到不一樣機架的 DataNode 中
c)MapReduce 會根據機架獲取離本身比較近的網絡數據
5. 下列哪一個是 Hadoop 運行的模式
a)單機版 b)僞分佈式 c)分佈式
6. Cloudera 提供哪幾種安裝 CDH 的方法
a)Cloudera manager b)Tarball c)Yum d)Rpm
7. 的
8. D d
9. 的
10. 的
1.2 Hbase選擇題
1.2.1 Hbase基礎
1. HBase 來源於哪篇博文? C
A TheGoogle File System
BMapReduce
CBigTable
D Chubby
2. 下面對 HBase 的描述哪些是正確的? B、C、D
A 不是開源的
B 是面向列的
C 是分佈式的
D 是一種 NoSQL 數據庫
3. HBase 依靠()存儲底層數據 A
A HDFS
B Hadoop
C Memory
DMapReduce
4. HBase 依賴()提供消息通訊機制 A
AZookeeper
B Chubby
C RPC
D Socket
5. HBase 依賴()提供強大的計算能力 D
AZookeeper
B Chubby
C RPC
DMapReduce
6. MapReduce 與 HBase 的關係,哪些描述是正確的? B、C
A 二者不可或缺,MapReduce 是 HBase 能夠正常運行的保證
B 二者不是強關聯關係,沒有 MapReduce,HBase 能夠正常運行
CMapReduce 能夠直接訪問 HBase
D 它們之間沒有任何關係
7. 下面哪些選項正確描述了HBase 的特性? A、B、C、D
A 高可靠性
B 高性能
C 面向列
D 可伸縮
8. 下面哪些概念是 HBase 框架中使用的?A、C
A HDFS
B GridFS
CZookeeper
D EXT3
9. D
1.2.2 Hbase核心
1. LSM 含義是?A
A 日誌結構合併樹
B 二叉樹
C 平衡二叉樹
D 長平衡二叉樹
2. 下面對 LSM 結構描述正確的是? A、C
A 順序存儲
B 直接寫硬盤
C 須要將數據 Flush 到磁盤
D 是一種搜索平衡樹
3. LSM 更能保證哪一種操做的性能?B
A 讀
B 寫
C 隨機讀
D 合併
4. LSM 的讀操做和寫操做是獨立的?A
A 是。
B 否。
C LSM 並不區分讀和寫
D LSM 中讀寫是同一種操做
5. LSM 結構的數據首先存儲在()。 B
A 硬盤上
B 內存中
C 磁盤陣列中
D 閃存中
6. HFile 數據格式中的 Data 字段用於()。A
A 存儲實際的 KeyValue 數據
B 存儲數據的起點
C 指定字段的長度
D 存儲數據塊的起點
7. HFile 數據格式中的 MetaIndex 字段用於()。D
A Meta 塊的長度
B Meta 塊的結束點
C Meta 塊數據內容
D Meta 塊的起始點
8. HFile 數據格式中的 Magic 字段用於()。A
A 存儲隨機數,防止數據損壞
B 存儲數據的起點
C 存儲數據塊的起點
D 指定字段的長度
9. HFile 數據格式中的 KeyValue 數據格式,下列選項描述正確的是()。A、D
A 是 byte[]數組
B 沒有固定的結構
C 數據的大小是定長的
D 有固定的結構
10. HFile 數據格式中的 KeyValue 數據格式中 Value 部分是()。C
A 擁有複雜結構的字符串
B 字符串
C 二進制數據
D 壓縮數據
11. D
1.2.3 HBase 高級應用介紹
1. HBase 中的批量加載底層使用()實現。A
AMapReduce
B Hive
CCoprocessor
D BloomFilter
2. HBase 性能優化包含下面的哪些選項?A、B、C、D
A 讀優化
B 寫優化
C 配置優化
D JVM 優化
3. Rowkey 設計的原則,下列哪些選項的描述是正確的?A、B、C
A 儘可能保證越短越好
B 能夠使用漢字
C 能夠使用字符串
D 自己是無序的
4. HBase 構建二級索引的實現方式有哪些? A、B
AMapReduce
BCoprocessor
C BloomFilter
D Filter
5. 關於 HBase 二級索引的描述,哪些是正確的?A、B
A 核心是倒排表
B 二級索引概念是對應 Rowkey 這個「一級」索引
C 二級索引使用平衡二叉樹
D 二級索引使用 LSM 結構
6. 下列關於 Bloom Filter 的描述正確的是?A、C
A 是一個很長的二進制向量和一系列隨機映射函數
B 沒有誤算率
C 有必定的誤算率
D 能夠在 Bloom Filter 中刪除元素
7. D
1.2.4 HBase 安裝、部署、啓動
1. HBase 官方版本能夠安裝在什麼操做系統上?A、B、C
A CentOS
B Ubuntu
C RedHat
D Windows
2. HBase 虛擬分佈式模式須要()個節點?A
A 1
B 2
C 3
D 最少 3 個
3. HBase 分佈式模式最好須要()個節點?C
A 1
B 2
C 3
D 最少
4. 下列哪些選項是安裝 HBase 前所必須安裝的?A、B
A 操做系統
B JDK
C ShellScript
D JavaCode
5. 解壓.tar.gz 結尾的 HBase 壓縮包使用的 Linux 命令是?A
A tar-zxvf
B tar -zx
C tar -s
D tar -nf
6. D
7. D
1.3 Zookeeper選擇題
1.3.1 Zookeeper基礎
1. 下面與 Zookeeper 相似的框架是?D
AProtobuf
B Java
C Kafka
D Chubby
2. 的
3. D
4. D
5. D
6. D
7. D
8. D
9. d
第2部分 判斷題
第2部分
2.1 Hadoop判斷題
2.1.1 集羣管理
1. Ganglia 不只能夠進行監控,也能夠進行告警。(正確)
解析:
ganglia 做爲一款最經常使用的 Linux 環境中的監控軟件,它擅長的的是從節點中按照用戶的需求以較低的代價
採集數據。可是 ganglia 在預警以及發生事件後通知用戶上並不擅長。最新的 ganglia 已經有了部分這方面
的功能。可是更擅長作警告的還有 Nagios。Nagios,就是一款精於預警、通知的軟件。經過將 Ganglia 和
Nagios 組合起來,把 Ganglia 採集的數據做爲 Nagios 的數據源,而後利用 Nagios 來發送預警通知,能夠
完美的實現一整套監控管理的系統。
2. Nagios 不能夠監控 Hadoop 集羣,由於它不提供 Hadoop支持。(錯誤 )
分析:
Nagios 是集羣監控工具,並且是雲計算三大利器之一
3. 若是 NameNode 意外終止,SecondaryNameNode 會接替它使集羣繼續工做。(錯誤 )
分析:
SecondaryNameNode 是幫助恢復,而不是替代
4. Cloudera CDH 是須要付費使用的。(錯誤)
分析:
第一套付費產品是 Cloudera Enterpris,Cloudera Enterprise 在美國加州舉行的 Hadoop 大會 (HadoopSummit) 上公開,以若干私有管理、監控、運做工具增強 Hadoop 的功能。收費採起合約訂購方式,價格隨用的 Hadoop 叢集大小變更。
5. NameNode 負責管理 metadata,client 端每次讀寫請求,它都會從磁盤中讀取或則會寫入 metadata信息並反饋 client 端。(錯誤)
分析:
NameNode 不須要從磁盤讀取 metadata,全部數據都在內存中,硬盤上的只是序列化的結果,只有每次namenode 啓動的時候纔會讀取。
1)文件寫入
Client 向 NameNode 發起文件寫入的請求。
NameNode 根據文件大小和文件塊配置狀況,返回給 Client 它所管理部分 DataNode 的信息。
Client 將文件劃分爲多個 Block,根據 DataNode 的地址信息,按順序寫入到每個 DataNode 塊中。
2)文件讀取
Client 向 NameNode 發起文件讀取的請求。
NameNode 返回文件存儲的 DataNode 的信息。
Client 讀取文件信息。
6. NameNode 本地磁盤保存了 Block 的位置信息。( 我的認爲正確,歡迎提出其它意見)
分析:
DataNode 是文件存儲的基本單元,它將 Block 存儲在本地文件系統中,保存了 Block 的 Meta-data,同時週期性地將全部存在的 Block 信息發送給 NameNode。
7. DataNode 經過長鏈接與 NameNode 保持通訊。錯誤
分析:
經過心跳機制。
(1).長鏈接
Client 方與 Server 方先創建通信鏈接,鏈接創建後不斷開,而後再進行報文發送和接收。這種方式下因爲通信鏈接一直存在,此種方式經常使用於點對點通信。
(2).短鏈接
Client 方與 Server 每進行一次報文收發交易時才進行通信鏈接,交易完畢後當即斷開鏈接。此種方式經常使用於一點對多點通信,好比多個 Client 鏈接一個 Server.
8. Hadoop 自身具備嚴格的權限管理和安全措施保障集羣正常運行。(錯誤)
9. Slave 節點要存儲數據,因此它的磁盤越大越好。(錯誤)
分析:
一旦 Slave 節點宕機,數據恢復是一個難題
10. hadoop dfsadmin –report 命令用於檢測 HDFS 損壞塊。(錯誤)
分析:
hadoop dfsadmin -report
用這個命令能夠快速定位出哪些節點 down 掉了,HDFS 的容量以及使用了多少,以及每一個節點的硬盤使用狀況。
固然 NameNode 有個 http 頁面也能夠查詢,可是這個命令的輸出更適合咱們的腳本監控 dfs 的使用情況
11. Hadoop 默認調度器策略爲 FIFO(正確 )
12. 集羣內每一個節點都應該配 RAID,這樣避免單磁盤損壞,影響整個節點運行。(錯誤)
分析:
首先明白什麼是 RAID:磁盤陣列(Redundant Arrays of Independent Disks,RAID),有「獨立磁盤構成的具備冗餘能力的陣列」之意。
這句話錯誤的地方在於太絕對,具體狀況具體分析。題目不是重點,知識才是最重要的。
由於 hadoop 自己就具備冗餘能力,因此若是不是很嚴格不須要都配備 RAID。
13. Hadoop 環境變量中的 HADOOP_HEAPSIZE 用於設置全部 Hadoop 守護線程的內存。它默認是 200 GB。( 錯誤)
分析:
hadoop 爲各個守護進程(namenode,secondarynamenode,jobtracker,datanode,tasktracker)統一分配的內存在 hadoop-env.sh 中設置,參數爲 HADOOP_HEAPSIZE,默認爲 1000M。
14. DataNode 首次加入 cluster 的時候,若是 log 中報告不兼容文件版本,那須要 NameNode執行―Hadoopnamenode -format‖操做格式化磁盤。(錯誤 )
分析:
這個報錯是說明 DataNode 所裝的 Hadoop 版本和其它節點不一致,應該檢查 DataNode 的 Hadoop 版本
15. D
16. D
17. 的
18. D
19. 的
20. D的
21. D的
22. D
23. d
2.1.2 Hdfs
1. Block Size 是不能夠修改的。(錯誤)
解析:
Hadoop 的基礎配置文件是 hadoop-default.xml,默認創建一個 Job 的時候會創建 Job 的 Config,Config
首先讀入hadoop-default.xml的配置,而後再讀入hadoop-site.xml的配置(這個文件初始的時候配置爲空),
hadoop-site.xml 中主要配置須要覆蓋的 hadoop-default.xml 的系統級配置。具體配置能夠參考下:
<property>
<name>dfs.block.size</name>//block 的大小,單位字節,後面會提到用處,必須是 512 的倍數,因
爲採用 crc 做文件完整性校驗,默認配置 512 是 checksum 的最小單元。
<value>5120000</value>
<description>The default block size for new files.</description>
</property>
2. Hadoop 支持數據的隨機讀寫。(錯)
分析:
lucene 是支持隨機讀寫的,而 hdfs 只支持隨機讀。可是 HBase 能夠來補救。
HBase 提供隨機讀寫,來解決 Hadoop 不能處理的問題。HBase 自底層設計開始即聚焦於各類可伸縮性問題:表能夠很―高‖,有數十億個數據行;也能夠很―寬‖,有數百萬個列;水平分區並在上千個普通商用機節點上自動複製。表的模式是物理存儲的直接反映,使系統有可能提升高效的數據結構的序列化、存儲和檢索。
3. 由於 HDFS 有多個副本,因此 NameNode 是不存在單點問題的。(錯誤 )
分析:
副本針對DataName而講的
4. 的
5. 的
6. 的
2.1.3 MapReduce
1. Hadoop 是 Java 開發的,因此 MapReduce 只支持 Java 語言編寫。(錯誤 )
分析:
支持c++等語言,須要經過接口。
2. 每一個 map 槽就是一個線程。(錯誤)
分析:
一個task對應一個線程
分析:首先咱們知道什麼是 map 槽,map 槽->map slot,map slot 只是一個邏輯值 ( org.apache.hadoop.mapred.TaskTracker.TaskLauncher.numFreeSlots ),而不是對應着一個線程或者進程
3. Mapreduce 的 input split 就是一個 block。(錯誤)
分析:
應該是一個block數組
一、運行mapred程序;
二、本次運行將生成一個Job,因而JobClient向JobTracker申請一個JobID以標識這個Job;
三、JobClient將Job所須要的資源提交到HDFS中一個以JobID命名的目錄中。這些資源包括JAR包、配置文件、InputSplit、等;
四、JobClient向JobTracker提交這個Job;
五、JobTracker初始化這個Job;
六、JobTracker從HDFS獲取這個Job的Split等信息;
七、JobTracker向TaskTracker分配任務;
八、TaskTracker從HDFS獲取這個Job的相關資源;
九、TaskTracker開啓一個新的JVM;
十、TaskTracker用新的JVM來執行Map或Reduce;
InputSplit也是一個interface,具體返回什麼樣的implement,這是由具體的InputFormat來決定的。InputSplit也只有兩個接口函數:
long getLength() throws IOException;
String[] getLocations() throws IOException;
這個interface僅僅描述了Split有多長,以及存放這個Split的Location信息(也就是這個Split在HDFS上存放的機器。它可能有多個replication,存在於多臺機器上)。除此以外,就再沒有任何直接描述Split的信息了。好比:Split對應於哪一個文件?在文件中的起始和結束位置是什麼?等等重要的特徵都沒有描述到。
爲何會這樣呢?由於關於Split的那些描述信息,對於MapReduce框架來講是不須要關心的。框架只關心Split的長度(主要用於一些統計信息)和Split的Location(主要用於Split的調度,後面會細說)。
而Split中真正重要的描述信息仍是隻有InputFormat會關心。在須要讀取一個Split的時候,其對應的InputSplit會被傳遞到InputFormat的第二個接口函數getRecordReader,而後被用於初始化一個RecordReader,以解析輸入數據。也就是說,描述Split的重要信息都被隱藏了,只有具體的InputFormat本身知道。它只須要保證getSplits返回的InputSplit和getRecordReader所關心的InputSplit是一樣的implement就好了。這就給InputFormat的實現提供了巨大的靈活性。
4. 的
5. 的
6. 的
7. D
8. 的
第3部分 敘述題
第3部分
3.1 Hadoop敘述題
3.1.1 Hadoop部署
1. hdfs的體系結構
解答:
hdfs有namenode、secondraynamenode、datanode組成。
爲n+1模式
namenode負責管理datanode和記錄元數據
secondraynamenode負責合併日誌
datanode負責存儲數據
2. 簡要描述如何安裝配置一個apache開本來hadoop,只描述便可,無需列出完整步驟,能列出步驟更好。
流程:
1.建立hadoop用戶
2.修改IP
3.安裝JDK,並配置環境變量
4.修改host文件映射
5.安裝SSH,配置無祕鑰通訊
6.上傳解壓hadoop安裝包
7.配置conf文件夾下的hadoop-env.sh、core-site.xlmapre-site.xml、hdfs-site.xml
8.配置hadoop的環境變量
9.Hadoop namenode -format
10.start-all
3. 啓動hadoop集羣時報下圖錯誤,分析什麼緣由:
解答:
一、權限問題,可能曾經用root啓動過集羣。(例如hadoop搭建的集羣,是tmp/hadoop-hadoop/.....)
二、多是文件夾不存在
三、解決: 刪掉tmp下的那個文件,或改爲當前用戶
4. 請列出hadoop的進程名稱
解答:
1.namenode:管理集羣,並記錄datanode文件信息。
2.Secondname:能夠作冷備,對必定範圍內的數據作快照性備份。
3.Datanode:存儲數據。
4.Jobtracker:管理任務,並將任務分配給tasktracker。
5.Tasktracker:任務執行者
5. Hadoop的核心配置是什麼?
解答:
Hadoop的核心配置經過兩個xml文件來完成:
1.hadoop-default.xml;
2.hadoop-site.xml。
這些文件都使用xml格式,所以每一個xml中都有一些屬性,包括名稱和值,可是當下這些文件都已不復存在。
6. 那當下又該如何配置?
解答:
Hadoop如今擁有3個配置文件:
1,core-site.xml;
2,hdfs-site.xml;
3,mapred-site.xml。
這些文件都保存在conf/子目錄下。
7. 「jps」命令的用處?
解答:
這個命令能夠檢查Namenode、Datanode、Task Tracker、 Job Tracker是否正常工做。
8. 簡要描述如何安裝配置一個apache 開源版 hadoop,描述便可,列出步驟更好
解答:
9. 請列出正常工做的 hadoop 集羣中 hadoop 都須要啓動哪些進程,他們的做用分別是什麼?
解答:
10. 啓動 hadoop 報以下錯誤,該如何解決?
error org.apache.hadoop.hdfs.server.namenode.NameNode
org.apache.hadoop.hdfs.server.common.inconsistentFSStateExceptio
n Directory /tmp/hadoop-root/dfs/name is in an inconsistent
state storage direction does not exist or is not accessible?
11. 請寫出如下執行命令
1)殺死一個 job?
2)刪除 hdfs 上的/tmp/aaa 目錄
3)加入一個新的存儲節點和刪除一個計算節點須要刷新集羣狀態命令?
解答:
hadoop job -list 記錄job-id、hadoop job -kill job-id
hadoop fs -rmr /tmp/aaa
添加新節點:
hadoop -daemon.sh start datanode
hadoop -daemon.sh start tasktracker
移除一個節點:
hadoop mradmin -refreshnodes
hadoop dfsadmin -refreshnodes
12. 請列出你所知道的 hadoop 調度器,並簡要說明其工做方法?
解答:
1.FIFO schedular:默認,先進先出的原則
2.Capacity schedular:計算能力調度器,選擇佔用最小,優先級高的先執行,以此類推。
3.Fair schedular:公平調度,全部的job具備相同的資源。
13. 請列出在你之前工做中所使用過的開發 mapreduce 的語言?
解答:
14. 你認爲用 Java,Streaming,pipe 方式開發 mapreduce,各有哪些優缺點?
解答:
15. hadoop框架中怎麼來優化
解答:
(1) 從應用程序角度進行優化。因爲mapreduce是迭代逐行解析數據文件的,怎樣在迭代的狀況下,編寫高效率的應用程序,是一種優化思路。
(2) 對Hadoop參數進行調優。當前hadoop系統有190多個配置參數,怎樣調整這些參數,使hadoop做業運行儘量的快,也是一種優化思路。
(3) 從系統實現角度進行優化。這種優化難度是最大的,它是從hadoop實現機制角度,發現當前Hadoop設計和實現上的缺點,而後進行源碼級地修改。該方法雖難度大,但每每效果明顯。
(4)linux內核參數調整
1. 使用自定義Writable
自帶的Text很好用,可是字符串轉換開銷較大,故根據實際須要自定義Writable,注意做爲Key時要實現WritableCompareable接口
避免output.collect(new Text( ),new Text())
提倡key.set( ) value.set( ) output.collect(key,value)
前者會產生大量的Text對象,使用完後Java垃圾回收器會花費大量的時間去收集這些對象
2. 使用StringBuilder
不要使用Formatter StringBuffer( 線程安全)
StringBuffer儘可能少使用多個append方法,適當使用+
3. 使用DistributedCache加載文件
好比配置文件,詞典,共享文件,避免使用static變量
4. 充分使用Combiner Parttitioner Comparator。
Combiner : 對map任務進行本地聚合
Parttitioner : 合適的Parttitioner避免reduce端負載不均
Comparator : 二次排序
好比求天天的最大氣溫,map結果爲日期:氣溫,若氣溫是降序的,直接取列表首元素便可
5. 使用自定義InputFormat和OutputFormat
6. MR應避免
靜態變量:不能用於計數,應使用Counter
大對象:Map List
遞歸:避免遞歸深度過大
超長正則表達式:消耗性能,要在map或reduce函數外編譯正則表達式
不要建立本地文件:變向的把HDFS裏面的數據轉移到TaskTracker,佔用網絡帶寬
不要大量建立目錄和文件
不要大量使用System.out.println,而使用Logger
不要自定義過多的Counter,最好不要超過100個
不要配置過大內存,mapred.child.java.opts -Xmx2000m是用來設置mapreduce任務使用的最大heap量
7.關於map的數目
map數目過大[建立和初始化map的開銷],通常是由大量小文件形成的,或者dfs.block.size設置的過小,對於小文件能夠archive文件或者Hadoop fs -merge合併成一個大文件.
map數目過少,形成單個map任務執行時間過長,頻繁推測執行,且容易內存溢出,並行性優點不能體現出來。dfs.block.size通常爲256M-512M
壓縮的Text 文件是不能被分割的,因此儘可能使用SequenceFile,能夠切分
8.關於reduce的數目
reduce數目過大,產生大量的小文件,消耗大量沒必要要的資源,reduce數目太低呢,形成數據傾斜問題,且一般不能經過修改參數改變。
可選方案:mapred.reduce.tasks設爲-1變成AutoReduce。
Key的分佈,也在某種程度上決定了Reduce數目,因此要根據Key的特色設計相對應的Parttitioner 避免數據傾斜
9.Map-side相關參數優化
io.sort.mb(100MB):一般k個map tasks會對應一個buffer,buffer主要用來緩存map部分計算結果,並作一些預排序提升map性能,若map輸出結果較大,能夠調高這個參數,減小map任務進行spill任務個數,下降 I/O的操做次數。若map任務的瓶頸在I/O的話,那麼將會大大提升map性能。如何判斷map任務的瓶頸?
io.sort.spill.percent(0.8):spill操做就是當內存buffer超過必定閾值(這裏一般是百分比)的時候,會將buffer中得數據寫到Disk中。而不是等buffer滿後在spill,不然會形成map的計算任務等待buffer的釋放。通常來講,調整 io.sort.mb而不是這個參數。
io.sort.factor(10):map任務會產生不少的spill文件,而map任務在正常退出以前會將這些spill文件合併成一個文件,即merger過程,缺省是一次合併10個參數,調大io.sort.factor,減小merge的次數,減小Disk I/O操做,提升map性能。
min.num.spill.for.combine:一般爲了減小map和reduce數據傳輸量,咱們會制定一個combiner,將map結果進行本地彙集。這裏combiner可能在merger以前,也可能在其以後。那麼何時在其以前呢?當spill個數至少爲min.num.spill.for.combine指定的數目時同時程序指定了Combiner,Combiner會在其以前運行,減小寫入到Disk的數據量,減小I/O次數。
10.壓縮(時間換空間)
MR中的數據不管是中間數據仍是輸入輸出結果都是巨大的,若不使用壓縮不只浪費磁盤空間且會消耗大量網絡帶寬。一樣在spill,merge(reduce也對有一個merge)亦能夠使用壓縮。若想在cpu時間和壓縮比之間尋找一個平衡,LzoCodec比較適合。一般MR任務的瓶頸不在CPU而在於I/O,因此大部分的MR任務都適合使用壓縮。
11. reduce-side相關參數優化
reduce:copy->sort->reduce,也稱shuffle
mapred.reduce.parellel.copies(5):任一個map任務可能包含一個或者多個reduce所須要數據,故一個map任務完成後,相應的reduce就會當即啓動線程下載本身所須要的數據。調大這個參數比較適合map任務比較多且完成時間比較短的Job。
mapred.reduce.copy.backoff:reduce端從map端下載數據也有可能因爲網絡故障,map端機器故障而失敗。那麼reduce下載線程確定不會無限等待,當等待時間超過mapred.reduce.copy.backoff時,便放棄,嘗試從其餘地方下載。需注意:在網絡狀況比較差的環境,咱們須要調大這個參數,避免reduce下載線程被誤判爲失敗。
io.sort.factor:recude將map結果下載到本地時,亦須要merge,若是reduce的瓶頸在於I/O,可嘗試調高增長merge的併發吞吐,提升reduce性能、
mapred.job.shuffle.input.buffer.percent(0.7):reduce從map下載的數據不會馬上就寫到Disk中,而是先緩存在內存中,mapred.job.shuffle.input.buffer.percent指定內存的多少比例用於緩存數據,內存大小可經過mapred.child.java.opts來設置。和map相似,buffer不是等到寫滿才往磁盤中寫,也是到達閾值就寫,閾值由mapred.job,shuffle.merge.percent來指定。若Reduce下載速度很快,容易內存溢出,適當增大這個參數對增長reduce性能有些幫助。
mapred.job.reduce.input.buffer.percent (0):當Reduce下載map數據完成以後,就會開始真正的reduce的計算,reduce的計算必然也是要消耗內存的,那麼在讀物reduce所須要的數據時,一樣須要內存做爲buffer,這個參數是決定多少的內存百分比做爲buffer。默認爲0,也就是說reduce所有從磁盤讀數據。若redcue計算任務消耗內存很小,那麼能夠設置這個參數大於0,使一部份內存用來緩存數據。
16. 從應用程序角度進行優化
解答:
(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是可修改的,不會產生臨時對象。
17. datanode在什麼狀況下不會備份
解答:
當分備份數爲1時。
18. combiner出如今那個過程
解答:
出如今map階段的map方法後。
19. 3個datanode中有一個datanode出現錯誤會怎樣?
解答:
這個datanode的數據會在其餘的datanode上從新作備份。
20. 描述一下hadoop中,有哪些地方使用了緩存機制,做用分別是什麼?
解答:
21. 如何肯定hadoop集羣的健康狀態
解答:
22. hadoop 的 namenode 宕機,怎麼解決
解答:
先分析宕機後的損失,宕機後直接致使client沒法訪問,內存中的元數據丟失,可是硬盤中的元數據應該還存在,若是隻是節點掛了,重啓便可,若是是機器掛了,重啓機器後看節點是否能重啓,不能重啓就要找到緣由修復了。可是最終的解決方案應該是在設計集羣的初期就考慮到這個問題,作namenode的HA。
23. 一個datanode 宕機,怎麼一個流程恢復
解答:
Datanode宕機了後,若是是短暫的宕機,能夠實現寫好腳本監控,將它啓動起來。若是是長時間宕機了,那麼datanode上的數據應該已經被備份到其餘機器了,那這臺datanode就是一臺新的datanode了,刪除他的全部數據文件和狀態文件,從新啓動。
24. 的
25. D
26. 的
27. 的
28. 的
29. 的
30. d
3.1.2 Hadoop原理
1. 請簡述 hadoop 怎麼樣實現二級排序?
解答:
在Reduce階段,先對Key排序,再對Value排序
最經常使用的方法是將Value放到Key中,實現一個組合Key,而後自定義Key排序規則(爲Key實現一個WritableComparable)。
2. 如何使用MapReduce實現兩個表join,能夠考慮一下幾種狀況:(1)一個表大,一個表小(可放到內存中);(2)兩個表都是大表?
解答:
第一種狀況比較簡單,只需將小表放到DistributedCache中便可;
第二種狀況經常使用的方法有:map-side join(要求輸入數據有序,一般用戶Hbase中的數據錶鏈接),reduce-side join,semi join(半鏈接)
3. MapReduce中排序發生在哪幾個階段?這些排序是否能夠避免?爲何?
解答:
一個MapReduce做業由Map階段和Reduce階段兩部分組成,這兩階段會對數據排序,從這個意義上說,MapReduce框架本質就是一個Distributed Sort。在Map階段,在Map階段,Map Task會在本地磁盤輸出一個按照key排序(採用的是快速排序)的文件(中間可能產生多個文件,但最終會合併成一個),在Reduce階段,每一個Reduce Task會對收到的數據排序,這樣,數據便按照Key分紅了若干組,以後以組爲單位交給reduce()處理。不少人的誤解在Map階段,若是不使用Combiner便不會排序,這是錯誤的,無論你用不用Combiner,Map Task均會對產生的數據排序(若是沒有Reduce Task,則不會排序, 實際上Map階段的排序就是爲了減輕Reduce端排序負載)。因爲這些排序是MapReduce自動完成的,用戶沒法控制,所以,在hadoop 1.x中沒法避免,也不能夠關閉,但hadoop2.x是能夠關閉的。
4. 請簡述 mapreduce 中,combiner,partition 做用?
解答:
combiner是reduce的實現,在map端運行計算任務,減小map端的輸出數據。
做用就是優化。
可是combiner的使用場景是mapreduce的map輸出結果和reduce輸入輸出同樣。
partition的默認實現是hashpartition,是map端將數據按照reduce個數取餘,進行分區,不一樣的reduce來copy本身的數據。
partition的做用是將數據分到不一樣的reduce進行計算,加快計算效果。
一、combiner最基本是實現本地key的聚合,對map輸出的key排序,value進行迭代。以下所示:
map: (K1, V1) → list(K2, V2)
combine: (K2, list(V2)) → list(K2, V2)
reduce: (K2, list(V2)) → list(K3, V3)
二、combiner還具備相似本地的reduce功能.
例如hadoop自帶的wordcount的例子和找出value的最大值的程序,combiner和reduce徹底一致。以下所示:
map: (K1, V1) → list(K2, V2)
combine: (K2, list(V2)) → list(K3, V3)
reduce: (K3, list(V3)) → list(K4, V4)
三、若是不用combiner,那麼,全部的結果都是reduce完成,效率會相對低下。使用combiner,先完成的map會在本地聚合,提高速度。
四、對於hadoop自帶的wordcount的例子,value就是一個疊加的數字,因此map一結束就能夠進行reduce的value疊加,而沒必要要等到全部的map結束再去進行reduce的value疊加。
combiner使用的合適,能夠在知足業務的狀況下提高job的速度,若是不合適,則將致使輸出的結果不正確。
5. 解釋―hadoop‖和―hadoop 生態系統‖兩個概念
解答:
6. 說明 Hadoop 2.0 的基本構成
解答:
分別說明hdfs,yarn,mapreduce
7. 相比於 HDFS1.0,HDFS 2.0 最主要的改進在哪幾方面?
解答:
8. 試使用―步驟 1,步驟 2,步驟 3…..‖說明 YARN 中運行應用程序的基本流程
解答:
9. ―MapReduce 2.0‖與―YARN‖是否等同,嘗試解釋說明
解答:
10. MapReduce 2.0 中,MRAppMaster 主要做用是什麼,MRAppMaster如何實現任務容錯的?
解答:
11. hdfs 原理,以及各個模塊的職責
解答:
12. mr 的工做原理
解答:
Map—combiner—partition—sort—copy—sort—grouping—reduce
13. map 方法是如何調用 reduce 方法的
解答:
14. shell 如何判斷文件是否存在,若是不存在該如何處理?
解答:
15. fsimage 和 edit 的區別?
解答:
16. hadoop1 和 hadoop2 的區別?
解答:
17. hdfs 中的 block 默認報錯幾份?
解答:
18. 哪一個程序一般與 nn 在一個節點啓動?並作分析
解答:
19. 列舉幾個配置文件優化?
解答:
20. datanode 首次加入 cluster 的時候,若是 log 報告不兼容文件版本,那須要 namenode 執行格式化操做,這樣處理的緣由是?
解答:
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;
}
22. 談談數據傾斜,如何發生的,並給出優化方案
解答:
23. mapreduce 基本執行過程
解答:
24. 談談 hadoop1 和 hadoop2 的區別
解答:
25. hadoop中Combiner的做用?
解答:
combiner是reduce的實現,在map端運行計算任務,減小map端的輸出數據。
做用就是優化。
可是combiner的使用場景是mapreduce的map和reduce輸入輸出同樣。
26. Mapreduce 的 map 數量 和 reduce 數量 怎麼肯定 ,怎麼配置
解答:
map的數量有數據塊決定,reduce數量隨便配置。
27. 在hadoop中文件的壓縮帶來了兩大好處:
解答:
(1)它減小了存儲文件所需的空間;
(2)加快了數據在網絡上或者從磁盤上或到磁盤上的傳輸速度;
28. mapreduce的調度模式
解答:
一個MapReduce做業的生命週期大致分爲5個階段 【1】 :
1. 做業提交與初始化
2. 任務調度與監控
3. 任務運行環境準備
4. 任務執行
5. 做業完成
咱們假設JobTracker已經啓動,那麼調度器是怎麼啓動的?JobTracker在啓動時有如下代碼:
JobTracker tracker = startTracker(new JobConf());
tracker.offerService();
其中offerService方法負責啓動JobTracker提供的各個服務,有這樣一行代碼:
taskScheduler.start();
taskScheduler即爲任務調度器。start方法是抽象類TaskScheduler提供的接口,用於啓動調度器。每一個調度器類都要繼承TaskScheduler類。回憶一下,調度器啓動時會將各個監聽器對象註冊到JobTracker,以FIFO調度器JobQueueTaskScheduler爲例:
@Override
public synchronized void start() throws IOException {
super.start();
taskTrackerManager.addJobInProgressListener(jobQueueJobInProgressListener);
eagerTaskInitializationListener.setTaskTrackerManager(taskTrackerManager);
eagerTaskInitializationListener.start();
taskTrackerManager.addJobInProgressListener(
eagerTaskInitializationListener);
}
這裏註冊了兩個監聽器,其中eagerTaskInitializationListener負責做業初始化,而jobQueueJobInProgressListener則負責做業的執行和監控。當有做業提交到JobTracker時,JobTracker會執行全部訂閱它消息的監聽器的jobAdded方法。對於eagerTaskInitializationListener來講:
@Override
public void jobAdded(JobInProgress job) {
synchronized (jobInitQueue) {
jobInitQueue.add(job);
resortInitQueue();
jobInitQueue.notifyAll();
}
}
提交的做業的JobInProgress對象被添加到做業初始化隊列jobInitQueue中,並喚醒初始化線程(若原來沒有做業能夠初始化):
class JobInitManager implements Runnable {
public void run() {
JobInProgress job = null;
while (true) {
try {
synchronized (jobInitQueue) {
while (jobInitQueue.isEmpty()) {
jobInitQueue.wait();
}
job = jobInitQueue.remove(0);
}
threadPool.execute(new InitJob(job));
} catch (InterruptedException t) {
LOG.info("JobInitManagerThread interrupted.");
break;
}
}
threadPool.shutdownNow();
}
}
這種工做方式是一種「生產者-消費者」模式:做業初始化線程是消費者,而監聽器eagerTaskInitializationListener是生產者。這裏能夠有多個消費者線程,放到一個固定資源的線程池中,線程個數經過mapred.jobinit.threads參數配置,默認爲4個。
下面咱們重點來看調度器中的另外一個監聽器。 jobQueueJobInProgressListener對象在調度器中初始化時連續執行了兩個構造器完成初始化:
public JobQueueJobInProgressListener() {
this(new TreeMap<JobSchedulingInfo,
JobInProgress>(FIFO_JOB_QUEUE_COMPARATOR));
}
/**
* For clients that want to provide their own job priorities.
* @param jobQueue A collection whose iterator returns jobs in priority order.
*/
protected JobQueueJobInProgressListener(Map<JobSchedulingInfo,
JobInProgress> jobQueue) {
this.jobQueue = Collections.synchronizedMap(jobQueue);
}
其中,第一個構造器調用重載的第二個構造器。能夠看到,調度器使用一個隊列jobQueue來保存提交的做業。這個隊列使用一個TreeMap對象實現,TreeMap的特色是底層使用紅黑樹實現,能夠按照鍵來排序,而且因爲是平衡樹,效率較高。做爲鍵的是一個JobSchedulingInfo對象,做爲值就是提交的做業對應的JobInProgress對象。另外,因爲TreeMap自己不是線程安全的,這裏使用了集合類的同步方法構造了一個線程安全的Map。使用帶有排序功能的數據結構的目的是使做業在隊列中按照優先級的大小排列,這樣每次調度器只需從隊列頭部得到做業便可。
做業的順序由優先級決定,而優先級信息包含在JobSchedulingInfo對象中:
static class JobSchedulingInfo {
private JobPriority priority;
private long startTime;
private JobID id;
...
}
該對象包含了做業的優先級、ID和開始時間等信息。在Hadoop中,做業的優先級有如下五種:VERY_HIGH、HIGH、NORMAL、LOW、VERY_LOW。這些字段是經過做業的JobStatus對象初始化的。因爲該對象做爲TreeMap的鍵,所以要實現本身的equals方法和hashCode方法:
@Override
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != JobSchedulingInfo.class) {
return false;
} else if (obj == this) {
return true;
}
else if (obj instanceof JobSchedulingInfo) {
JobSchedulingInfo that = (JobSchedulingInfo)obj;
return (this.id.equals(that.id) &&
this.startTime == that.startTime &&
this.priority == that.priority);
}
return false;
}
咱們看到,兩個JobSchedulingInfo對象相等的條件是類型一致,而且做業ID、開始時間和優先級都相等。hashCode的計算比較簡單:
@Override
public int hashCode() {
return (int)(id.hashCode() * priority.hashCode() + startTime);
}
注意,監聽器的第一個構造器有一個比較器參數,用於定義 JobSchedulingInfo的比較方式:
static final Comparator<JobSchedulingInfo> FIFO_JOB_QUEUE_COMPARATOR
= new Comparator<JobSchedulingInfo>() {
public int compare(JobSchedulingInfo o1, JobSchedulingInfo o2) {
int res = o1.getPriority().compareTo(o2.getPriority());
if (res == 0) {
if (o1.getStartTime() < o2.getStartTime()) {
res = -1;
} else {
res = (o1.getStartTime() == o2.getStartTime() ? 0 : 1);
}
}
if (res == 0) {
res = o1.getJobID().compareTo(o2.getJobID());
}
return res;
}
};
從上面看出,首先比較做業的優先級,若優先級相等則比較開始時間(FIFO),若再相等則比較做業ID。 咱們在實現本身的調度器時可能要定義本身的做業隊列,那麼做業在隊列中的順序(即 JobSchedulingInfo的比較器 )就要仔細定義,這是調度器可以正常運行基礎。
Hadoop中的做業調度採用pull方式,即TaskTracker定時向JobTracker發送心跳信息索取一個新的任務,這些信息包括數據結點上做業和任務的運行狀況,以及該TaskTracker上的資源使用狀況。JobTracker會依據以上信息更新做業隊列的狀態,並調用調度器選擇一個或多個任務以心跳響應的形式返回給TaskTracker。從上面描述能夠看出,JobTracker和taskScheduler之間的互相利用關係:前者利用後者爲TaskTracker分配任務;後者利用前者更新隊列和做業信息。接下來,咱們一步步詳述該過程。
首先,當一個心跳到達JobTracker時(實際上這是一個來自TaskTracker的遠程過程調用 heartbeat方法 ,協議接口是InterTrackerProtocol),會執行兩種動做:更新狀態和下達命令 【1】 。下達命令稍後關注。有關更新狀態的一些代碼片斷以下:
if (!processHeartbeat(status, initialContact, now)) {
if (prevHeartbeatResponse != null) {
trackerToHeartbeatResponseMap.remove(trackerName);
}
return new HeartbeatResponse(newResponseId,
new TaskTrackerAction[] {new ReinitTrackerAction()});
}
具體的心跳處理,由私有函數processHeartbeat完成。該函數中有如下兩個方法調用:
updateTaskStatuses(trackerStatus);
updateNodeHealthStatus(trackerStatus, timeStamp);
分別用來更新任務的狀態和結點的健康狀態。在第一個方法中有下面代碼片斷:
TaskInProgress tip = taskidToTIPMap.get(taskId);
// Check if the tip is known to the jobtracker. In case of a restarted
// jt, some tasks might join in later
if (tip != null || hasRestarted()) {
if (tip == null) {
tip = job.getTaskInProgress(taskId.getTaskID());
job.addRunningTaskToTIP(tip, taskId, status, false);
}
// Update the job and inform the listeners if necessary
JobStatus prevStatus = (JobStatus)job.getStatus().clone();
// Clone TaskStatus object here, because JobInProgress
// or TaskInProgress can modify this object and
// the changes should not get reflected in TaskTrackerStatus.
// An old TaskTrackerStatus is used later in countMapTasks, etc.
job.updateTaskStatus(tip, (TaskStatus)report.clone());
JobStatus newStatus = (JobStatus)job.getStatus().clone();
// Update the listeners if an incomplete job completes
if (prevStatus.getRunState() != newStatus.getRunState()) {
JobStatusChangeEvent event =
new JobStatusChangeEvent(job, EventType.RUN_STATE_CHANGED,
prevStatus, newStatus);
updateJobInProgressListeners(event);
}
} else {
LOG.info("Serious problem. While updating status, cannot find taskid "
+ report.getTaskID());
}
這裏的job對象經過從TaskTracker那裏獲得的task狀態信息中抽取出來。注意,這裏拷貝了原有做業狀態的一個副本,而後修改這個副本的相關信息,調用的是updateJobStatus方法,更新任務的狀態信息和JobInProgress的相關信息,如map和reduce任務的進度等,這裏不展開了。這些信息的更新能夠爲調度器的工做提供依據。
做業狀態的更新是經過updateJobInProgressListeners方法實現,該方法的參數是一個JobStatusChangeEvent對象,表示做業狀態變化的事件。這種事件的類型能夠是運行狀態改變、開始時間改變、優先級改變等等。用戶也能夠根據須要自定義事件類型。事件對象維護了兩個JobStatus對象,分別表示事件發生先後做業的狀態。
進入該方法後,咱們又看到了熟悉的觀察者模式:
// Update the listeners about the job
// Assuming JobTracker is locked on entry.
private void updateJobInProgressListeners(JobChangeEvent event) {
for (JobInProgressListener listener : jobInProgressListeners) {
listener.jobUpdated(event);
}
}
此次每一個監聽器要回調jobUpdated方法,表示做業有更新。對於jobQueueJobInProgressListener來講是這樣作的:
@Override
public synchronized void jobUpdated(JobChangeEvent event) {
JobInProgress job = event.getJobInProgress();
if (event instanceof JobStatusChangeEvent) {
// Check if the ordering of the job has changed
// For now priority and start-time can change the job ordering
JobStatusChangeEvent statusEvent = (JobStatusChangeEvent)event;
JobSchedulingInfo oldInfo =
new JobSchedulingInfo(statusEvent.getOldStatus());
if (statusEvent.getEventType() == EventType.PRIORITY_CHANGED
|| statusEvent.getEventType() == EventType.START_TIME_CHANGED) {
// Make a priority change
reorderJobs(job, oldInfo);
} else if (statusEvent.getEventType() == EventType.RUN_STATE_CHANGED) {
// Check if the job is complete
int runState = statusEvent.getNewStatus().getRunState();
if (runState == JobStatus.SUCCEEDED
|| runState == JobStatus.FAILED
|| runState == JobStatus.KILLED) {
jobCompleted(oldInfo);
}
}
}
}
首先,獲取做業更新 前 的狀態。而後根據事件的類型,進行相應的處理。好比,若是優先級變化了,則要從新排列隊列中做業的順序。這裏直接取出原有做業,從新插入隊列。插入後,做業會自動從新排序,體現了TreeMap的優越性。再好比,若是做業狀態變爲完成,那麼就從隊列中刪除該做業。
private void reorderJobs(JobInProgress job, JobSchedulingInfo oldInfo) {
synchronized (jobQueue) {
jobQueue.remove(oldInfo);
jobQueue.put(new JobSchedulingInfo(job), job);
}
}
下面就是調度器中最關鍵的一步了:任務選擇。此時,做業隊列中信息已經更新完畢,能夠選擇一些任務返回給TaskTracker執行了。heartbeat方法接下來會有這樣的代碼:
List<Task> tasks = getSetupAndCleanupTasks(taskTrackerStatus);
if (tasks == null ) {
tasks = taskScheduler.assignTasks(taskTrackers.get(trackerName));
}
若是不須要setup和cleanup,就說明須要選擇map或reduce任務。調用TaskScheduler的assignTasks方法完成任務選擇。因爲篇幅限制,我打算將這部份內容放到下一篇文章中,並關注heartbeat中JobTracker下達的命令過程以及JobInProgress和TaskInProgress對調度有影響的一些字段。
29. 是
30.
3.1.3 Hadoop使用
1. hdfs寫流程
流程:
1.client連接namenode存數據
2.namenode記錄一條數據位置信息(元數據),告訴client存哪。
3.client用hdfs的api將數據塊(默認是64M)存儲到datanode上。
4.datanode將數據水平備份。而且備份完將反饋client。
5.client通知namenode存儲塊完畢。
6.namenode將元數據同步到內存中。
7.另外一塊循環上面的過程。
2. hdfs讀流程
流程:
1.client連接namenode,查看元數據,找到數據的存儲位置。
2.client經過hdfs的api併發讀取數據。
3.關閉鏈接。
3. 舉一個簡單的例子說明mapreduce是怎麼來運行的 ?
解答:
Word count例子接口
============================
一個MapReduce做業(job)一般會把輸入的數據集切分爲若干獨立的數據塊,由map任務(task)以徹底並行的方式處理它們。框架會對map的輸出先進行排序,而後把結果輸入給reduce任務。一般做業的輸入和輸出都會被存儲在文件系統中。整個框架負責任務的調度和監控,以及從新執行已經失敗的任務。
一般,MapReduce框架和分佈式文件系統是運行在一組相同的節點上的,也就是說,計算節點和存儲節點一般在一塊兒。這種配置容許框架在那些已經存好數據的節點上高效地調度任務,這能夠使整個集羣的網絡帶寬被很是高效地利用。
MapReduce框架由一個單獨的master JobTracker和每一個集羣節點一個slave TaskTracker共同組成。master負責調度構成一個做業的全部任務,這些任務分佈在不一樣的slave上,master監控它們的執行,從新執行已經失敗的任務。而slave僅負責執行由master指派的任務
4. 用mapreduce來實現下面需求?如今有10個文件夾,每一個文件夾都有1000000個url.如今讓你找出top1000000url。
5. yarn流程
解答:
1) 用戶向YARN 中提交應用程序, 其中包括ApplicationMaster 程序、啓動ApplicationMaster 的命令、用戶程序等。
2) ResourceManager 爲該應用程序分配第一個Container, 並與對應的NodeManager 通訊,要求它在這個Container 中啓動應用程序的ApplicationMaster。
3) ApplicationMaster 首先向ResourceManager 註冊, 這樣用戶能夠直接經過ResourceManage 查看應用程序的運行狀態,而後它將爲各個任務申請資源,並監控它的運行狀態,直到運行結束,即重複步驟4~7。
4) ApplicationMaster 採用輪詢的方式經過RPC 協議向ResourceManager 申請和領取資源。
5) 一旦ApplicationMaster 申請到資源後,便與對應的NodeManager 通訊,要求它啓動任務。
6) NodeManager 爲任務設置好運行環境(包括環境變量、JAR 包、二進制程序等)後,將任務啓動命令寫到一個腳本中,並經過運行該腳本啓動任務。
7) 各個任務經過某個RPC 協議向ApplicationMaster 彙報本身的狀態和進度,以讓ApplicationMaster 隨時掌握各個任務的運行狀態,從而能夠在任務失敗時從新啓動任務。在應用程序運行過程當中,用戶可隨時經過RPC 向ApplicationMaster 查詢應用程序的當前運行狀態。
8) 應用程序運行完成後,ApplicationMaster 向ResourceManager 註銷並關閉本身。
6. 的
7. 的
8. 的
9. 的
10. 的
11.
12. 的
13.
3.2 Hive敘述題
3.2.1 Hive基礎
1. hive 有哪些方式保存元數據,各有哪些特色?
解答:
一、內存數據庫derby,安裝小,可是數據存在內存,不穩定
二、mysql數據庫,數據存儲模式能夠本身設置,持久化好,查看方便。
2. hive內部表和外部表的區別
解答:
內部表:加載數據到hive所在的hdfs目錄,刪除時,元數據和數據文件都刪除
外部表:不加載數據到hive所在的hdfs目錄,刪除時,只刪除表結構。
3. 生產環境中爲何建議使用外部表?
解答:
一、由於外部表不會加載數據到hive,減小數據傳輸、數據還能共享。
二、hive不會修改數據,因此無需擔憂數據的損壞
三、刪除表時,只刪除表結構、不刪除數據。
4. 大家數據庫怎麼導入hive 的,有沒有出現問題
解答:
在導入hive的時候,若是數據庫中有blob或者text字段,會報錯。有個參數limit
5. 簡述Hive中的虛擬列做用是什麼,使用它的注意事項
解答:
Hive提供了三個虛擬列:
INPUT__FILE__NAME
BLOCK__OFFSET__INSIDE__FILE
ROW__OFFSET__INSIDE__BLOCK
但ROW__OFFSET__INSIDE__BLOCK默認是不可用的,須要設置hive.exec.rowoffset爲true才能夠。能夠用來排查有問題的輸入數據。
INPUT__FILE__NAME, mapper任務的輸出文件名。
BLOCK__OFFSET__INSIDE__FILE, 當前全局文件的偏移量。對於塊壓縮文件,就是當前塊的文件偏移量,即當前塊的第一個字節在文件中的偏移量。
hive> SELECT INPUT__FILE__NAME, BLOCK__OFFSET__INSIDE__FILE, line
> FROM hive_text WHERE line LIKE '%hive%' LIMIT 2;
har://file/user/hive/warehouse/hive_text/folder=docs/
data.har/user/hive/warehouse/hive_text/folder=docs/README.txt 2243
har://file/user/hive/warehouse/hive_text/folder=docs/
data.har/user/hive/warehouse/hive_text/folder=docs/README.txt 3646
6. hive partition分區
解答:
分區表,動態分區
7. insert into 和 override write區別?
解答:
insert into:將某一張表中的數據寫到另外一張表中
override write:覆蓋以前的內容。
8. 假如一個分區的數據主部錯誤怎麼經過hivesql刪除hdfs
解答:
alter table ptable drop partition (daytime='20140911',city='bj');
元數據,數據文件都刪除,但目錄daytime= 20140911還在
9. Hive裏面用什麼代替in查詢
解答:
提示:Hive中的left semi join替換sql中的in操做
10. 的
11. 的
12. d
3.3 Hbase
3.3.1 Hbase基礎
1. 介紹一下 hbase 過濾器
解答:
2. hbase 集羣安裝注意事項
解答:
3. hbase的rowkey怎麼建立好?列族怎麼建立比較好?
解答:
hbase存儲時,數據按照Row key的字典序(byte order)排序存儲。設計key時,要充分排序存儲這個特性,將常常一塊兒讀取的行存儲放到一塊兒。(位置相關性)
一個列族在數據底層是一個文件,因此將常常一塊兒查詢的列放到一個列族中,列族儘可能少,減小文件的尋址時間。
由於hbase是列式數據庫,列非表schema的一部分,因此在設計初期只須要考慮rowkey 和 columnFamily便可,rowkey有位置相關性,因此若是數據是練習查詢的,最好對同類數據加一個前綴,而每一個columnFamily實際上在底層是一個文件,那麼文件越小,查詢越快,因此講常常一塊兒查詢的列設計到一個列簇,可是列簇不宜過多。
Rowkey長度原則
Rowkey是一個二進制碼流,Rowkey的長度被不少開發者建議說設計在10~100個字節,不過建議是越短越好,不要超過16個字節。
緣由以下:
(1)數據的持久化文件HFile中是按照KeyValue存儲的,若是Rowkey過長好比100個字節,1000萬列數據光Rowkey就要佔用100*1000萬=10億個字節,將近1G數據,這會極大影響HFile的存儲效率;
(2)MemStore將緩存部分數據到內存,若是Rowkey字段過長內存的有效利用率會下降,系統將沒法緩存更多的數據,這會下降檢索效率。所以Rowkey的字節長度越短越好。
(3)目前操做系統是都是64位系統,內存8字節對齊。控制在16個字節,8字節的整數倍利用操做系統的最佳特性。
Rowkey散列原則
若是Rowkey是按時間戳的方式遞增,不要將時間放在二進制碼的前面,建議將Rowkey的高位做爲散列字段,由程序循環生成,低位放時間字段,這樣將提升數據均衡分佈在每一個Regionserver實現負載均衡的概率。若是沒有散列字段,首字段直接是時間信息將產生全部新數據都在一個 RegionServer上堆積的熱點現象,這樣在作數據檢索的時候負載將會集中在個別RegionServer,下降查詢效率。
Rowkey惟一原則
必須在設計上保證其惟一性。
4. 簡述Hbase性能優化的思路
解答:
一、在庫表設計的時候,儘可能考慮rowkey和columnfamily的特性
二、進行hbase集羣的調優
5. 簡述Hbase filter的實現原理是什麼?結合實際項目經驗,寫出幾個使用filter的場景。
解答:
hbase的filter是經過scan設置的,因此是基於scan的查詢結果進行過濾。
1.在進行訂單開發的時候,咱們使用rowkeyfilter過濾出某個用戶的全部訂單
2.在進行雲筆記開發時,咱們使用rowkey過濾器進行redis數據的恢復。
6. ROWKEY的後綴匹配怎麼實現?列如ROWKEY是yyyyMMDD-UserID形式,如UserID爲條件查詢數據,怎麼實現。
解答:
7. HBase的檢索支持3種方式:
解答:
(1) 經過單個Rowkey訪問,即按照某個Rowkey鍵值進行get操做,這樣獲取惟一一條記錄;
(2) 經過Rowkey的range進行scan,即經過設置startRowKey和endRowKey,在這個範圍內進行掃描。這樣能夠按指定的條件獲取一批記錄;
(3) 全表掃描,即直接掃描整張表中全部行記錄。
8. 簡述HBase的瓶頸
解答:
HBase的瓶頸就是硬盤傳輸速度。HBase的操做,它能夠往數據裏面insert,也能夠update一些數據,但update的實際上也是insert,只是插入一個新的時間戳的一行。Delete數據,也是insert,只是insert一行帶有delete標記的一行。Hbase的全部操做都是追加插入操做。Hbase是一種日誌集數據庫。它的存儲方式,像是日誌文件同樣。它是批量大量的往硬盤中寫,一般都是以文件形式的讀寫。這個讀寫速度,就取決於硬盤與機器之間的傳輸有多快。而Oracle的瓶頸是硬盤尋道時間。它常常的操做時隨機讀寫。要update一個數據,先要在硬盤中找到這個block,而後把它讀入內存,在內存中的緩存中修改,過段時間再回寫回去。因爲你尋找的block不一樣,這就存在一個隨機的讀。硬盤的尋道時間主要由轉速來決定的。而尋道時間,技術基本沒有改變,這就造成了尋道時間瓶頸。
9. Hbase內部是什麼機制?
解答:
在HMaster、RegionServer內部,建立了RpcServer實例,並與Client三者之間實現了Rpc調用,HBase0.95內部引入了Google-Protobuf做爲中間數據組織方式,並在Protobuf提供的Rpc接口之上,實現了基於服務的Rpc實現,本文詳細闡述了HBase-Rpc實現細節。
HBase的RPC Protocol
在HMaster、RegionServer內部,實現了rpc 多個protocol來完成管理和應用邏輯,具體以下protocol以下:
HMaster支持的Rpc協議:
MasterMonitorProtocol,Client與Master之間的通訊,Master是RpcServer端,主要實現HBase集羣監控的目的。
MasterAdminProtocol,Client與Master之間的通訊,Master是RpcServer端,主要實現HBase表格的管理。例如TableSchema的更改,Table-Region的遷移、合併、下線(Offline)、上線(Online)以及負載平衡,以及Table的刪除、快照等相關功能。
RegionServerStatusProtoco,RegionServer與Master之間的通訊,Master是RpcServer端,負責提供RegionServer向HMaster狀態彙報的服務。
RegionServer支持的Rpc協議:
ClientProtocol,Client與RegionServer之間的通訊,RegionServer是RpcServer端,主要實現用戶的讀寫請求。例如get、multiGet、mutate、scan、bulkLoadHFile、執行Coprocessor等。
AdminProtocols,Client與RegionServer之間的通訊,RegionServer是RpcServer端,主要實現Region、服務、文件的管理。例如storefile信息、Region的操做、WAL操做、Server的開關等。
(備註:以上提到的Client能夠是用戶Api、也能夠是RegionServer或者HMaster)
HBase-RPC實現機制分析
RpcServer配置三個隊列:
1)普通隊列callQueue,絕大部分Call請求存在該隊列中:callQueue上maxQueueLength爲${ipc.server.max.callqueue.length},默認是${hbase.master.handler.count}*DEFAULT_MAX_CALLQUEUE_LENGTH_PER_HANDLER,目前0.95.1中,每一個Handler上CallQueue的最大個數默認值(DEFAULT_MAX_CALLQUEUE_LENGTH_PER_HANDLER)爲10。
2)優先級隊列: PriorityQueue。若是設置priorityHandlerCount的個數,會建立與callQueue至關容量的queue存儲Call,該優先級隊列對應的Handler的個數由rpcServer實例化時傳入。
3)拷貝隊列:replicationQueue。因爲RpcServer由HMaster和RegionServer共用,該功能僅爲RegionServer提供,queue的大小爲${ipc.server.max.callqueue.size}指定,默認爲1024*1024*1024,handler的個數爲hbase.regionserver.replication.handler.count。
RpcServer由三個模塊組成:
Listener ===Queue=== Responder
這裏以HBaseAdmin.listTables爲例, 分析一個Rpc請求的函數調用過程:
1) RpcClient建立一個BlockingRpcChannel。
2)以channel爲參數建立執行RPC請求須要的stub,此時的stub已經被封裝在具體Service下,stub下定義了可執行的rpc接口。
3)stub調用對應的接口,實際內部channel調用callBlockingMethod方法。
RpcClient內實現了protobuf提供的BlockingRpcChannel接口方法callBlockingMethod, @OverridepublicMessage callBlockingMethod(MethodDescriptor md, RpcController controller,Message param, Message returnType)throwsServiceException {returnthis.rpcClient.callBlockingMethod(md, controller, param, returnType, this.ticket,this.isa, this.rpcTimeout);}
經過以上的實現細節,最終轉換成rpcClient的調用,使用MethodDescriptor封裝了不一樣rpc函數,使用Message基類能夠接收基於Message的不一樣的Request和Response對象。
4)RpcClient建立Call對象,查找或者建立合適的Connection,並喚醒Connection。
5)Connection等待Call的Response,同時rpcClient調用函數中,會使用connection.writeRequest(Call call)將請求寫入到RpcServer網絡流中。
6)等待Call的Response,而後層層返回給更上層接口,從而完成這次RPC調用。
RPCServer收到的Rpc報文的內部組織以下:
Magic
(4Byte)
Version
(1Byte)
AuthMethod
(1Byte)
Connection
HeaderLength
(4Byte)
ConnectionHeader
Request
「HBas」
驗證RpcServer的CURRENT_VERSION
與RPC報文一致
目前支持三類:
AuthMethod.SIMPLE
AuthMethod.KERBEROS
AuthMethod.DIGEST
RPC.proto定義
RPCProtos.ConnectionHeader
message ConnectionHeader {
optional UserInformation userInfo = 1;
optional string serviceName = 2;
// Cell block codec we will use sending over optional cell blocks. Server throws exception
// if cannot deal.
optional string cellBlockCodecClass = 3 [default = "org.apache.hadoop.hbase.codec.KeyValueCodec"];
// Compressor we will use if cell block is compressed. Server will throw exception if not supported.
// Class must implement hadoop’s CompressionCodec Interface
optional string cellBlockCompressorClass = 4;
}
序列化以後的數據
整個Request存儲是通過編碼以後的byte數組,包括以下幾個部分:
RequestHeaderLength(RawVarint32)
RequestHeader
ParamSize(RawVarint32)
Param
CellScanner
RPC.proto定義:
message RequestHeader {
// Monotonically increasing callId to keep track of RPC requests and their response
optional uint32 callId = 1;
optional RPCTInfo traceInfo = 2;
optional string methodName = 3;
// If true, then a pb Message param follows.
optional bool requestParam = 4;
// If present, then an encoded data block follows.
optional CellBlockMeta cellBlockMeta = 5;
// TODO: Have client specify priority
}
序列化以後的數據
並從Header中確認是否存在Param和CellScanner,若是確認存在的狀況下,會繼續訪問。
Protobuf的基本類型Message,
Request的Param繼承了Message,
這個須要獲取的Method類型決定。
從功能上講,RpcServer上包含了三個模塊,
1)Listener。包含了多個Reader線程,經過Selector獲取ServerSocketChannel接收來自RpcClient發送來的Connection,並從中重構Call實例,添加到CallQueue隊列中。
」IPC Server listener on 60021″ daemon prio=10 tid=0x00007f7210a97800 nid=0x14c6 runnable [0x00007f720e8d0000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked <0x00000000c43cae68> (a sun.nio.ch.Util$2)
- locked <0x00000000c43cae50> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c4322ca8> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:84)
at org.apache.hadoop.hbase.ipc.RpcServer$Listener.run(RpcServer.java:646)
2)Handler。負責執行Call,調用Service的方法,而後返回Pair<Message,CellScanner>
「IPC Server handler 0 on 60021″ daemon prio=10 tid=0x00007f7210eab000 nid=0x14c7 waiting on condition [0x00007f720e7cf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000c43cad90> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:399)
at org.apache.hadoop.hbase.ipc.RpcServer$Handler.run(RpcServer.java:1804)
3) Responder。負責把Call的結果返回給RpcClient。
」IPC Server Responder」 daemon prio=10 tid=0x00007f7210a97000 nid=0x14c5 runnable [0x00007f720e9d1000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked <0x00000000c4407078> (a sun.nio.ch.Util$2)
- locked <0x00000000c4407060> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000c4345b68> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
at org.apache.hadoop.hbase.ipc.RpcServer$Responder.doRunLoop(RpcServer.java:833)
at org.apache.hadoop.hbase.ipc.RpcServer$Responder.run(RpcServer.java:816)
RpcClient爲Rpc請求創建Connection,經過Connection將Call發送RpcServer,而後RpcClient等待結果的返回。
10. 的
11. 的
12. 的
13. 的
14. 的
3.4 Zookeeper
1. 寫出你對 zookeeper 的理解
解答:
2. 的
3. 的
4. 的
3.5 Storm
1. storm 若是碰上了複雜邏輯,須要算很長的時間,你怎麼去優化
解答:
拆分複雜的業務到多個bolt中,這樣能夠利用bolt的tree將速度提高
提升並行度
2. 開發流程,容錯機制
解答:
開發流程:
寫主類(設計spout和bolt的分發機制)
寫spout收集數據
寫bolt處理數據,根據數據量和業務的複雜程度,設計並行度。
容錯機制:
採用ack和fail進行容錯,失敗的數據從新發送。
3. storm和spark-streaming:爲何用storm不一樣spark-streaming
解答:
4. 的
5. 的
6. 的
7. 的
3.6 Flume
1. flume管道內存,flume宕機了數據丟失怎麼解決
解答:
一、Flume的channel分爲不少種,能夠將數據寫入到文件
二、防止非首個agent宕機的方法數能夠作集羣或者主備
2. flume配置方式,flume集羣(問的很詳細)
解答:
Flume的配置圍繞着source、channel、sink敘述,flume的集羣是作在agent上的,而非機器上。
3. flume不採集Nginx日誌,經過Logger4j採集日誌,優缺點是什麼?
解答:
優勢:Nginx的日誌格式是固定的,可是缺乏sessionid,經過logger4j採集的日誌是帶有sessionid的,而session能夠經過redis共享,保證了集羣日誌中的同一session落到不一樣的tomcat時,sessionId仍是同樣的,並且logger4j的方式比較穩定,不會宕機。
缺點:不夠靈活,logger4j的方式和項目結合過於緊密,而flume的方式比較靈活,拔插式比較好,不會影響項目性能。
4. flume和kafka採集日誌區別,採集日誌時中間停了,怎麼記錄以前的日誌。
解答:
Flume採集日誌是經過流的方式直接將日誌收集到存儲層,而kafka試講日誌緩存在kafka集羣,待後期能夠採集到存儲層。
Flume採集中間停了,能夠採用文件的方式記錄以前的日誌,而kafka是採用offset的方式記錄以前的日誌。
5. 的
6. 的
3.7 Kafka
1. Kafka容錯機制
解答:
分區備份,存在主備partition
2. kafka數據流向
解答:
Producer à leader partition à follower partition(半數以上) àconsumer
3. kafka+spark-streaming結合丟數據怎麼解決?
解答:
spark streaming從1.2開始提供了數據的零丟失,想享受這個特性,須要知足以下條件:
數據輸入須要可靠的sources和可靠的receivers
應用metadata必須經過應用driver checkpoint
WAL(write ahead log)
可靠的sources和receivers
spark streaming能夠經過多種方式做爲數據sources(包括kafka),輸入數據經過receivers接收,經過replication存儲於spark中(爲了faultolerance,默認複製到兩個spark executors),若是數據複製完成,receivers能夠知道(例如kafka中更新offsets到zookeeper中)。這樣當receivers在接收數據過程當中crash掉,不會有數據丟失,receivers沒有複製的數據,當receiver恢復後從新接收。
metadata checkpoint
可靠的sources和receivers,能夠使數據在receivers失敗後恢復,然而在driver失敗後恢復是比較複雜的,一種方法是經過checkpoint metadata到HDFS或者S3。metadata包括:
configuration
code
一些排隊等待處理但沒有完成的RDD(僅僅是metadata,而不是data)
這樣當driver失敗時,能夠經過metadata checkpoint,重構應用程序並知道執行到那個地方。
數據可能丟失的場景
可靠的sources和receivers,以及metadata checkpoint也不能夠保證數據的不丟失,例如:
兩個executor獲得計算數據,並保存在他們的內存中
receivers知道數據已經輸入
executors開始計算數據
driver忽然失敗
driver失敗,那麼executors都會被kill掉
由於executor被kill掉,那麼他們內存中得數據都會丟失,可是這些數據再也不被處理
executor中的數據不可恢復
WAL
爲了不上面情景的出現,spark streaming 1.2引入了WAL。全部接收的數據經過receivers寫入HDFS或者S3中checkpoint目錄,這樣當driver失敗後,executor中數據丟失後,能夠經過checkpoint恢復。
At-Least-Once
儘管WAL能夠保證數據零丟失,可是不能保證exactly-once,例以下面場景:
Receivers接收完數據並保存到HDFS或S3
在更新offset前,receivers失敗了
Spark Streaming覺得數據接收成功,可是Kafka覺得數據沒有接收成功,由於offset沒有更新到zookeeper
隨後receiver恢復了
從WAL能夠讀取的數據從新消費一次,由於使用的kafka High-Level消費API,從zookeeper中保存的offsets開始消費
WAL的缺點
經過上面描述,WAL有兩個缺點:
下降了receivers的性能,由於數據還要存儲到HDFS等分佈式文件系統
對於一些resources,可能存在重複的數據,好比Kafka,在Kafka中存在一份數據,在Spark Streaming也存在一份(以WAL的形式存儲在hadoop API兼容的文件系統中)
Kafka direct API
爲了WAL的性能損失和exactly-once,spark streaming1.3中使用Kafka direct API。很是巧妙,Spark driver計算下個batch的offsets,指導executor消費對應的topics和partitions。消費Kafka消息,就像消費文件系統文件同樣。
再也不須要kafka receivers,executor直接經過Kafka API消費數據
WAL再也不須要,若是從失敗恢復,能夠從新消費
exactly-once獲得了保證,不會再從WAL中重複讀取數據
總結
主要說的是spark streaming經過各類方式來保證數據不丟失,並保證exactly-once,每一個版本都是spark streaming愈來愈穩定,愈來愈向生產環境使用發展。
4. kafka中存儲目錄data/dir.....topic1和topic2怎麼存儲的,存儲結構,data.....目錄下有多少個分區,每一個分區的存儲格式是什麼樣的?
解答:
一、topic是按照「主題名-分區」存儲的
二、分區個數由配置文件決定
三、每一個分區下最重要的兩個文件是0000000000.log和000000.index,0000000.log以默認1G大小回滾。
5. 的
6. D 的
3.8 Spark
1. mr和spark區別,怎麼理解spark-rdd
解答:
Mr是文件方式的分佈式計算框架,是將中間結果和最終結果記錄在文件中,map和reduce的數據分發也是在文件中。
spark是內存迭代式的計算框架,計算的中間結果能夠緩存內存,也能夠緩存硬盤,可是不是每一步計算都須要緩存的。
Spark-rdd是一個數據的分區記錄集合………………
2. Spark應用轉換流程
解答:
一、spark應用提交後,經歷了一系列的轉換,最後成爲task在每一個節點上執行
二、RDD的Action算子觸發Job的提交,生成RDD DAG
三、由DAGScheduler將RDD DAG轉化爲Stage DAG,每一個Stage中產生相應的Task集合
四、TaskScheduler將任務分發到Executor執行
五、每一個任務對應相應的一個數據塊,只用用戶定義的函數處理數據塊
3. Driver運行在Worker上
解答:
經過org.apache.spark.deploy.Client類執行做業,做業運行命令以下:
做業執行流程描述:
一、客戶端提交做業給Master
二、Master讓一個Worker啓動Driver,即SchedulerBackend。Worker建立一個DriverRunner線程,DriverRunner啓動SchedulerBackend進程。
三、另外Master還會讓其他Worker啓動Exeuctor,即ExecutorBackend。Worker建立一個ExecutorRunner線程,ExecutorRunner會啓動ExecutorBackend進程。
四、ExecutorBackend啓動後會向Driver的SchedulerBackend註冊。SchedulerBackend進程中包含DAGScheduler,它會根據用戶程序,生成執行計劃,並調度執行。對於每一個stage的task,都會被存放到TaskScheduler中,ExecutorBackend向SchedulerBackend彙報的時候把TaskScheduler中的task調度到ExecutorBackend執行。
五、全部stage都完成後做業結束。
4. Driver運行在客戶端
解答:
做業執行流程描述:
一、客戶端啓動後直接運行用戶程序,啓動Driver相關的工做:DAGScheduler和BlockManagerMaster等。
二、客戶端的Driver向Master註冊。
三、Master還會讓Worker啓動Exeuctor。Worker建立一個ExecutorRunner線程,ExecutorRunner會啓動ExecutorBackend進程。
四、ExecutorBackend啓動後會向Driver的SchedulerBackend註冊。Driver的DAGScheduler解析做業並生成相應的Stage,每一個Stage包含的Task經過TaskScheduler分配給Executor執行。
五、全部stage都完成後做業結束。
5. 的
6. 的
7. 的
8. 的
3.9 Sqoop
1. 命令:
sqoop import --connect jdbc:mysql://192.168.56.204:3306/sqoop --username hive --password hive --table jobinfo --target-dir /sqoop/test7 --inline-lob-limit 16777216 --fields-terminated-by '\t' -m 2
sqoop create-hive-table --connect jdbc:mysql://192.168.56.204:3306/sqoop --table jobinfo --username hive --password hive --hive-table sqtest --fields-terminated-by "\t" --lines-terminated-by "\n";
2. sqoop在導入數據到mysql中,如何讓數據不重複導入?若是存在數據問題sqoop如何處理?
解答:
Sqoop是一個用來將Hadoop和關係型數據庫中的數據相互轉移的工具,能夠將一個關係型數據庫(例如 : MySQL ,Oracle ,Postgres等)中的數據導進到Hadoop的HDFS中,也能夠將HDFS的數據導進到關係型數據庫中。
首先需如下要準備:
第一:hadoop的NameNode節點下lib文件夾中要有相應數據庫驅動的jar包和sqoop的jar包。
第二:預先在相應的數據庫建立Table,注:在HDFS的某個目錄上的數據格式要和相應的表中的字段數量一致。
因爲我這裏使用的是Oracle數據庫而且是使用Java來操做的。因此下面的代碼以及截圖都是以Java的例子:
首先標準化HDFS中文件格式,以下圖:
Java代碼以下:
Configuration conf = new Configuration();
conf.set("fs.default.name", "hdfs://192.168.115.5:9000");
conf.set("hadoop.job.ugi", "hadooper,hadoopgroup");
conf.set("mapred.job.tracker", "192.168.115.5:9001");
ArrayList<String> list = new ArrayList<String>(); // 定義一個list
list.add("--table");
list.add("A_BAAT_CLIENT"); // Oracle中的表。未來數據要導入到這個表中。
list.add("--export-dir");
list.add("/home/hadoop/traffic/capuse/near7date/activeUser/capuse_near7_activeUser_2013-02-06.log"); // hdfs上的目錄。這個目錄下的數據要導入到a_baat_client這個表中。
list.add("--connect");
list.add("jdbc:oracle:thin:@10.18.96.107:1521:life"); // Oracle的連接
list.add("--username");
list.add("TRAFFIC"); // Oracle的用戶名
list.add("--password");
list.add("TRAFFIC"); // Oracle的密碼
list.add("--input-fields-terminated-by");
list.add("|"); // 數據分隔符號
list.add("-m");
list.add("1");// 定義mapreduce的數量。
String[] arg = new String[1];
ExportTool exporter = new ExportTool();
Sqoop sqoop = new Sqoop(exporter);
sqoop.setConf(conf);
arg = list.toArray(new String[0]);
int result = Sqoop.runSqoop(sqoop, arg);
System.out.println("res:" + result); // 打印執行結果。
最後再在Main方法中運行便可,生成後表數據以下圖所示:
經過上面的操做以及代碼便可在Java中實現把HDFS數據生成對應的表數據;
不過除了能夠用Java來實現,使用基本的命令也是能夠的,命令以下:
在Hadoop bin目錄中:
sqoop export --connect jdbc:oracle:thin:@10.18.96.107:1521:life \
--table A_BAAT_CLIENT --username TRAFFIC --password TRAFFIC \
--input-fields-terminated-by '|' \
--export-dir /home/hadoop/traffic/capuse/near7date/activeUser/test.log -m 1
意思和上面Java中代碼同樣。
注意:
一、數據庫表名、用戶名、密碼使用大寫(這有可能會出現問題,由於我在測試過程當中,使用小寫時出現錯誤,出現No Columns這個經典錯誤。因此推薦大寫,固然這不是必須);
二、預先建好相應的Table;
3. 的
4. 的
5. 的
6. 的
3.10其餘
3.10.1 Redis
1. Redis,傳統數據庫,hbase,hive 每一個之間的區別
解答:
redis:分佈式緩存,強調緩存,內存中數據
傳統數據庫:注重關係
hbase:列式數據庫,沒法作關係數據庫的主外鍵,用於存儲海量數據,底層基於hdfs
hive:數據倉庫工具,底層是mapreduce。不是數據庫,不能用來作用戶的交互存儲
2. 是
3.10.2 數據庫
1. 反向索引
解答:
倒排索引(Inverted index)
適用範圍:搜索引擎,關鍵字查詢
基本原理及要點:爲什麼叫倒排索引?一種索引方法,被用來存儲在全文搜索下某個單詞在一個文檔或者一組文檔中的存儲位置的映射。
以英文爲例,下面是要被索引的文本:
T0 = 「it is what it is」
T1 = 「what is it」
T2 = 「it is a banana」
咱們就能獲得下面的反向文件索引:
「a」: {2}
「banana」: {2}
「is」: {0, 1, 2}
「it」: {0, 1, 2}
「what」: {0, 1}
檢索的條件」what」,」is」和」it」將對應集合的交集。
正向索引開發出來用來存儲每一個文檔的單詞的列表。正向索引的查詢每每知足每一個文檔有序 頻繁的全文查詢和每一個單詞在校驗文檔中的驗證這樣的查詢。在正向索引中,文檔佔據了中心的位置,每一個文檔指向了一個它所包含的索引項的序列。也就是說文檔指向了它包含的那些單詞,而反向索引則是單詞指向了包含它的文檔,很容易看到這個反向的關係。
2. 數據庫的三大範式?
解答:
數據庫範式1NF 2NF 3NF BCNF(實例)
設計範式(範式,數據庫設計範式,數據庫的設計範式)是符合某一種級別的關係模式的集合。構造數據庫必須遵循必定的規則。在關係數據庫中,這種規則就是範式。關係數據庫中的關係必須知足必定的要求,即知足不一樣的範式。目前關係數據庫有六種範式:第一範式(1NF)、第二範式(2NF)、第三範式(3NF)、第四範式(4NF)、第五範式(5NF)和第六範式(6NF)。知足最低要求的範式是第一範式(1NF)。在第一範式的基礎上進一步知足更多要求的稱爲第二範式(2NF),其他範式以次類推。通常說來,數據庫只需知足第三範式(3NF)就好了。下面咱們舉例介紹第一範式(1NF)、第二範式(2NF)和第三範式(3NF)。
在建立一個數據庫的過程當中,範化是將其轉化爲一些表的過程,這種方法能夠使從數據庫獲得的結果更加明確。這樣可能使數據庫產生重複數據,從而致使建立多餘的表。範化是在識別數據庫中的數據元素、關係,以及定義所需的表和各表中的項目這些初始工做以後的一個細化的過程。
下面是範化的一個例子 Customer Item purchased Purchase price Thomas Shirt $40 Maria Tennis shoes $35 Evelyn Shirt $40 Pajaro Trousers $25
若是上面這個表用於保存物品的價格,而你想要刪除其中的一個顧客,這時你就必須同時刪除一個價格。範化就是要解決這個問題,你能夠將這個表化爲兩個表,一個用於存儲每一個顧客和他所買物品的信息,另外一個用於存儲每件產品和其價格的信息,這樣對其中一個表作添加或刪除操做就不會影響另外一個表。
關係數據庫的幾種設計範式介紹
1 第一範式(1NF)
在任何一個關係數據庫中,第一範式(1NF)是對關係模式的基本要求,不知足第一範式(1NF)的數據庫就不是關係數據庫。
所謂第一範式(1NF)是指數據庫表的每一列都是不可分割的基本數據項,同一列中不能有多個值,即實體中的某個屬性不能有多個值或者不能有重複的屬性。若是出現重複的屬性,就可能須要定義一個新的實體,新的實體由重複的屬性構成,新實體與原實體之間爲一對多關係。在第一範式(1NF)中表的每一行只包含一個實例的信息。例如,對於圖3-2 中的員工信息表,不能將員工信息都放在一列中顯示,也不能將其中的兩列或多列在一列中顯示;員工信息表的每一行只表示一個員工的信息,一個員工的信息在表中只出現一次。簡而言之,第一範式就是無重複的列。
2 第二範式(2NF)
第二範式(2NF)是在第一範式(1NF)的基礎上創建起來的,即知足第二範式(2NF)必須先知足第一範式(1NF)。第二範式(2NF)要求數據庫表中的每一個實例或行必須能夠被唯一地區分。爲實現區分一般須要爲表加上一個列,以存儲各個實例的唯一標識。如圖3-2 員工信息表中加上了員工編號(emp_id)列,由於每一個員工的員工編號是唯一的,所以每一個員工能夠被唯一區分。這個唯一屬性列被稱爲主關鍵字或主鍵、主碼。
第二範式(2NF)要求實體的屬性徹底依賴於主關鍵字。所謂徹底依賴是指不能存在僅依賴主關鍵字一部分的屬性,若是存在,那麼這個屬性和主關鍵字的這一部分應該分離出來造成一個新的實體,新實體與原實體之間是一對多的關係。爲實現區分一般須要爲表加上一個列,以存儲各個實例的唯一標識。簡而言之,第二範式就是非主屬性非部分依賴於主關鍵字。
3 第三範式(3NF)
知足第三範式(3NF)必須先知足第二範式(2NF)。簡而言之,第三範式(3NF)要求一個數據庫表中不包含已在其它表中已包含的非主關鍵字信息。例如,存在一個部門信息表,其中每一個部門有部門編號(dept_id)、部門名稱、部門簡介等信息。那麼在圖3-2的員工信息表中列出部門編號後就不能再將部門名稱、部門簡介等與部門有關的信息再加入員工信息表中。若是不存在部門信息表,則根據第三範式(3NF)也應該構建它,不然就會有大量的數據冗餘。簡而言之,第三範式就是屬性不依賴於其它非主屬性。
數據庫設計三大範式應用實例剖析
數據庫的設計範式是數據庫設計所須要知足的規範,知足這些規範的數據庫是簡潔的、結構明晰的,同時,不會發生插入(insert)、刪除(delete)和更新(update)操做異常。反之則是亂七八糟,不只給數據庫的編程人員製造麻煩,並且面目可憎,可能存儲了大量不須要的冗餘信息。
設計範式是否是很難懂呢?非也,大學教材上給咱們一堆數學公式咱們固然看不懂,也記不住。因此咱們不少人就根本不按照範式來設計數據庫。
實質上,設計範式用很形象、很簡潔的話語就能說清楚,道明白。本文將對範式進行通俗地說明,並以筆者曾經設計的一個簡單論壇的數據庫爲例來說解怎樣將這些範式應用於實際工程。
範式說明
第一範式(1NF):數據庫表中的字段都是單一屬性的,不可再分。這個單一屬性由基本類型構成,包括整型、實數、字符型、邏輯型、日期型等。
例如,以下的數據庫表是符合第一範式的:
字段1 字段2 字段3 字段4
而這樣的數據庫表是不符合第一範式的:
字段1 字段2 字段3 字段4
字段3.1 字段3.2
很顯然,在當前的任何關係數據庫管理系統(DBMS)中,傻瓜也不可能作出不符合第一範式的數據庫,由於這些DBMS不容許你把數據庫表的一列再分紅二列或多列。所以,你想在現有的DBMS中設計出不符合第一範式的數據庫都是不可能的。
第二範式(2NF):數據庫表中不存在非關鍵字段對任一候選關鍵字段的部分函數依賴(部分函數依賴指的是存在組合關鍵字中的某些字段決定非關鍵字段的狀況),也即全部非關鍵字段都徹底依賴於任意一組候選關鍵字。
假定選課關係表爲SelectCourse(學號, 姓名, 年齡, 課程名稱, 成績, 學分),關鍵字爲組合關鍵字(學號, 課程名稱),由於存在以下決定關係:
(學號, 課程名稱) → (姓名, 年齡, 成績, 學分)
這個數據庫表不知足第二範式,由於存在以下決定關係:
(課程名稱) → (學分)
(學號) → (姓名, 年齡)
即存在組合關鍵字中的字段決定非關鍵字的狀況。
因爲不符合2NF,這個選課關係表會存在以下問題:
(1) 數據冗餘:
同一門課程由n個學生選修,"學分"就重複n-1次;同一個學生選修了m門課程,姓名和年齡就重複了m-1次。
(2) 更新異常:
若調整了某門課程的學分,數據表中全部行的"學分"值都要更新,不然會出現同一門課程學分不一樣的狀況。
(3) 插入異常:
假設要開設一門新的課程,暫時尚未人選修。這樣,因爲尚未"學號"關鍵字,課程名稱和學分也沒法記錄入數據庫。
(4) 刪除異常:
假設一批學生已經完成課程的選修,這些選修記錄就應該從數據庫表中刪除。可是,與此同時,課程名稱和學分信息也被刪除了。很顯然,這也會致使插入異常。
把選課關係表SelectCourse改成以下三個表:
學生:Student(學號, 姓名, 年齡);
課程:Course(課程名稱, 學分);
選課關係:SelectCourse(學號, 課程名稱, 成績)。
這樣的數據庫表是符合第二範式的, 消除了數據冗餘、更新異常、插入異常和刪除異常。
另外,全部單關鍵字的數據庫表都符合第二範式,由於不可能存在組合關鍵字。
第三範式(3NF):在第二範式的基礎上,數據表中若是不存在非關鍵字段對任一候選關鍵字段的傳遞函數依賴則符合第三範式。所謂傳遞函數依賴,指的是若是存在"A → B → C"的決定關係,則C傳遞函數依賴於A。所以,知足第三範式的數據庫表應該不存在以下依賴關係:
關鍵字段 → 非關鍵字段x → 非關鍵字段y
假定學生關係表爲Student(學號, 姓名, 年齡, 所在學院, 學院地點, 學院電話),關鍵字爲單一關鍵字"學號",由於存在以下決定關係:
(學號) → (姓名, 年齡, 所在學院, 學院地點, 學院電話)
這個數據庫是符合2NF的,可是不符合3NF,由於存在以下決定關係:
(學號) → (所在學院) → (學院地點, 學院電話)
即存在非關鍵字段"學院地點"、"學院電話"對關鍵字段"學號"的傳遞函數依賴。
它也會存在數據冗餘、更新異常、插入異常和刪除異常的狀況,讀者可自行分析得知。
把學生關係表分爲以下兩個表:
學生:(學號, 姓名, 年齡, 所在學院);
學院:(學院, 地點, 電話)。
這樣的數據庫表是符合第三範式的,消除了數據冗餘、更新異常、插入異常和刪除異常。
鮑依斯-科得範式(BCNF):在第三範式的基礎上,數據庫表中若是不存在任何字段對任一候選關鍵字段的傳遞函數依賴則符合第三範式。
假設倉庫管理關係表爲StorehouseManage(倉庫ID, 存儲物品ID, 管理員ID, 數量),且有一個管理員只在一個倉庫工做;一個倉庫能夠存儲多種物品。這個數據庫表中存在以下決定關係:
(倉庫ID, 存儲物品ID) →(管理員ID, 數量)
(管理員ID, 存儲物品ID) → (倉庫ID, 數量)
因此,(倉庫ID, 存儲物品ID)和(管理員ID, 存儲物品ID)都是StorehouseManage的候選關鍵字,表中的惟一非關鍵字段爲數量,它是符合第三範式的。可是,因爲存在以下決定關係:
(倉庫ID) → (管理員ID)
(管理員ID) → (倉庫ID)
即存在關鍵字段決定關鍵字段的狀況,因此其不符合BCNF範式。它會出現以下異常狀況:
(1) 刪除異常:
當倉庫被清空後,全部"存儲物品ID"和"數量"信息被刪除的同時,"倉庫ID"和"管理員ID"信息也被刪除了。
(2) 插入異常:
當倉庫沒有存儲任何物品時,沒法給倉庫分配管理員。
(3) 更新異常:
若是倉庫換了管理員,則表中全部行的管理員ID都要修改。
把倉庫管理關係表分解爲二個關係表:
倉庫管理:StorehouseManage(倉庫ID, 管理員ID);
倉庫:Storehouse(倉庫ID, 存儲物品ID, 數量)。
這樣的數據庫表是符合BCNF範式的,消除了刪除異常、插入異常和更新異常。
範式應用
咱們來逐步搞定一個論壇的數據庫,有以下信息:
(1) 用戶:用戶名,email,主頁,電話,聯繫地址
(2) 帖子:發帖標題,發帖內容,回覆標題,回覆內容
第一次咱們將數據庫設計爲僅僅存在表:
用戶名 email 主頁 電話 聯繫地址 發帖標題 發帖內容 回覆標題 回覆內容
這個數據庫表符合第一範式,可是沒有任何一組候選關鍵字能決定數據庫表的整行,惟一的關鍵字段用戶名也不能徹底決定整個元組。咱們須要增長"發帖ID"、"回覆ID"字段,即將表修改成:
用戶名 email 主頁 電話 聯繫地址 發帖ID 發帖標題 發帖內容 回覆ID 回覆標題 回覆內容
這樣數據表中的關鍵字(用戶名,發帖ID,回覆ID)能決定整行:
(用戶名,發帖ID,回覆ID) → (email,主頁,電話,聯繫地址,發帖標題,發帖內容,回覆標題,回覆內容)
可是,這樣的設計不符合第二範式,由於存在以下決定關係:
(用戶名) → (email,主頁,電話,聯繫地址)
(發帖ID) → (發帖標題,發帖內容)
(回覆ID) → (回覆標題,回覆內容)
即非關鍵字段部分函數依賴於候選關鍵字段,很明顯,這個設計會致使大量的數據冗餘和操做異常。
咱們將數據庫表分解爲(帶下劃線的爲關鍵字):
(1) 用戶信息:用戶名,email,主頁,電話,聯繫地址
(2) 帖子信息:發帖ID,標題,內容
(3) 回覆信息:回覆ID,標題,內容
(4) 發貼:用戶名,發帖ID
(5) 回覆:發帖ID,回覆ID
這樣的設計是知足第一、二、3範式和BCNF範式要求的,可是這樣的設計是否是最好的呢?
不必定。
觀察可知,第4項"發帖"中的"用戶名"和"發帖ID"之間是1:N的關係,所以咱們能夠把"發帖"合併到第2項的"帖子信息"中;第5項"回覆"中的"發帖ID"和"回覆ID"之間也是1:N的關係,所以咱們能夠把"回覆"合併到第3項的"回覆信息"中。這樣能夠必定量地減小數據冗餘,新的設計爲:
(1) 用戶信息:用戶名,email,主頁,電話,聯繫地址
(2) 帖子信息:用戶名,發帖ID,標題,內容
(3) 回覆信息:發帖ID,回覆ID,標題,內容
數據庫表1顯然知足全部範式的要求;
數據庫表2中存在非關鍵字「標題」、「內容」對關鍵字段「發帖ID」的部分函數依賴,即不知足第二範式的要求,可是這一設計並不會致使數據冗餘和操做異常;
數據庫表3中也存在非關鍵字段"標題"、"內容"對關鍵字段"回覆ID"的部分函數依賴,也不知足第二範式的要求,可是與數據庫表2類似,這一設計也不會致使數據冗餘和操做異常。
由此能夠看出,並不必定要強行知足範式的要求,對於1:N關係,當1的一邊合併到N的那邊後,N的那邊就再也不知足第二範式了,可是這種設計反而比較好!
對於M:N的關係,不能將M一邊或N一邊合併到另外一邊去,這樣會致使不符合範式要求,同時致使操做異常和數據冗餘。
對於1:1的關係,咱們能夠將左邊的1或者右邊的1合併到另外一邊去,設計致使不符合範式要求,可是並不會致使操做異常和數據冗餘。
3.
4. 是
第4部分 解答題
第4部分
4.1 Hadoop解答題
4.1.1 MapReduce編程題
1. 當前日誌採樣格式爲,請用你最熟悉的語言編寫一個 mapreduce,並計算第四列每一個元素出現的個數。
1. a,b,c,d
2. b,b,f,e
3. a,a,c,f
2. 給定 a、b 兩個文件,各存放 50 億個 url,每一個 url 各佔 64 字節,內存限制是 4G,讓你找出 a、b 文件共同的 url?
解答:
方案 1:將大文件分紅可以被內存加載的小文件。
能夠估計每一個文件安的大小爲 50G×64=320G,遠遠大於內存限制的 4G。因此不可能將其徹底加載到內存中處理。考慮採起分而治之的方法。
s 遍歷文件 a,對每一個 url 求取 ,而後根據所取得的值將 url 分別存儲到 1000 個小文件(記爲 )中。
這樣每一個小文件的大約爲 300M。
s 遍歷文件 b,採起和 a 相同的方式將 url 分別存儲到 1000 各小文件(記爲 )。這樣處理後,全部可能相同的 url 都在對應的小文件( )中,不對應的小文件不可能有相同的 url。而後咱們只要求出 1000 對小文件中相同的 url 便可。
s 求每對小文件中相同的 url 時,能夠把其中一個小文件的 url 存儲到 hash_set 中。而後遍歷另外一個小文件的每一個 url,看其是否在剛纔構建的 hash_set 中,若是是,那麼就是共同的 url,存到文件裏面就能夠了。
方案 2:內存映射成 BIT 最小存儲單元。
若是容許有必定的錯誤率,能夠使用 Bloom filter,4G 內存大概能夠表示 340 億 bit。將其中一個文件中的url使用Bloom filter映射爲這340億bit,而後挨個讀取另一個文件的url,檢查是否與Bloom filter,若是是,那麼該 url 應該是共同的 url(注意會有必定的錯誤率)。
3. 有 10 個文件,每一個文件 1G,每一個文件的每一行存放的都是用戶的 query,每一個文件的 query 均可能重複。要求你按照query 的頻度排序。
解答:
方案 1:
s 順序讀取 10 個文件,按照 hash(query)%10 的結果將 query 寫入到另外 10 個文件(記爲 )中。這樣新生成的文件每一個的大小大約也 1G(假設 hash 函數是隨機的)。
s 找一臺內存在 2G 左右的機器,依次對 用 hash_map(query, query_count)來統計每一個 query 出現的次數。利用快速/堆/歸併排序按照出現次數進行排序。將排序好的 query 和對應的 query_cout 輸出到文件中。這樣獲得了 10 個排好序的文件(記爲 )。
s 對 這 10 個文件進行歸併排序(內排序與外排序相結合)。
方案 2:
通常 query 的總量是有限的,只是重複的次數比較多而已,可能對於全部的 query,一次性就能夠加入到內存了。這樣,咱們就能夠採用 trie 樹/hash_map 等直接來統計每一個 query 出現的次數,而後按出現
次數作快速/堆/歸併排序就能夠了。
方案 3:
與方案 1 相似,但在作完 hash,分紅多個文件後,能夠交給多個文件來處理,採用分佈式的架構來處
理(好比 MapReduce),最後再進行合併。
//通常在大文件中找出出現頻率高的,先把大文件映射成小文件,模 1000,在小文件中找到高頻的
4. 有一個 1G 大小的一個文件,裏面每一行是一個詞,詞的大小不超過 16 字節,內存限制大小是 1M。返回頻數最高的 100 個詞。
解答:
方案 1:順序讀文件中,對於每一個詞 x,取 ,而後按照該值存到 5000 個小文件(記爲 )中。這樣每一個文件大概是 200k 左右。若是其中的有的文件超過了 1M 大小,還能夠按照相似的方法繼續往下分,知道分解獲得的小文件的大小都不超過 1M。 對每一個小文件,統計每一個文件中出現的詞以及相應的頻率(能夠採用 trie 樹/hash_map 等),並取出出現頻率最大的 100 個詞(能夠用含 100 個結 點的最小堆),並把 100詞及相應的頻率存入文件,這樣又獲得了 5000 個文件。下一步就是把這 5000 個文件進行歸併(相似與歸併排序)的過程了。
方案2:
1. 將文件逐行讀寫到另外一個文件中,並將每行單詞全變成小寫
2. 十六次循環執行,將每行單詞按照a-z寫到不一樣文件裏
3. 最後相同的單詞都寫在了通一個文件裏
4. 再將文件讀寫到各自另外一個文件裏,內容是「單詞 個數」
5. 定義一個treemap,大小是100,依次插入大的,移除小的
6. 最後得出結果
5. 海量日誌數據,提取出某日訪問百度次數最多的那個 IP。
解答:
1. 先根據日期在日誌文件中提取出ip,根據ip哈希進行分寫N個文件。
2. 採用mapreduce的word cont
方案 1:首先是這一天,而且是訪問百度的日誌中的 IP 取出來,逐個寫入到一個大文件中。注意到 IP是 32 位的,最多有 個 IP。一樣能夠採用映射的方法,好比模 1000,把整個大文件映射爲 1000 個小文件,再找出每一個小文中出現頻率最大的 IP(能夠採用 hash_map 進行頻率統計,而後再找出頻率最大的幾個)及相應的頻率。而後再在這 1000 個最大的 IP 中,找出那個頻率最大的 IP,即爲所求。
6. 在 2.5 億個整數中找出不重複的整數,內存不足以容納這 2.5 億個整數。
解答:
方案 1:採用 2-Bitmap(每一個數分配 2bit,00 表示不存在,01 表示出現一次,10 表示屢次,11 無心義)進 行,共需內存 內存,還能夠接受。而後掃描這 2.5 億個整數,查看 Bitmap 中相對應位,若是是00 變 01,01 變 10,10 保持不變。所描完過後,查看 bitmap,把對應位是 01 的整數輸出便可。
方案 2:也可採用上題相似的方法,進行劃分小文件的方法。而後在小文件中找出不重複的整數,並排序。而後再進行歸併,注意去除重複的元素。
方案3:
1. 將2.5億個整數重寫到一個文件裏,內個整數佔一行。
2. 進行對半排序重寫到新的文件裏,這樣最後2.5億個整數在文件裏即是有序的了
3. 讀取文本,將不重複的寫到一個新的文件裏便可。
7. 海量數據分佈在 100 臺電腦中,想個辦法高校統計出這批數據的 TOP10。
解答:
方案 1:(方法不正確,取出來得不必定是top10)
s 在每臺電腦上求出 TOP10,能夠採用包含 10 個元素的堆完成(TOP10 小,用最大堆,TOP10 大,用最小堆)。好比求 TOP10 大,咱們首先取前 10 個元素調整成最小堆,若是發現,而後掃描後面的數據,並與堆頂元素比較,若是比堆頂元素大,那麼用該元素替換堆頂,而後再調整爲最小堆。最後堆中的元 素就是 TOP10 大。
s 求出每臺電腦上的 TOP10 後,而後把這 100 臺電腦上的 TOP10 組合起來,共 1000 個數據,再利用上面相似的方法求出 TOP10 就能夠了。
8. 怎麼在海量數據中找出重複次數最多的一個?
解答:
方案 1:(同上,方法錯誤)
先作 hash,而後求模映射爲小文件,求出每一個小文件中重複次數最多的一個,並記錄重複次數。而後找出上一步求出的數據中重複次數最多的一個就是所求(具體參考前面的題)。
正確的方法,先排除
9. 上千萬或上億數據(有重複),統計其中出現次數最多的前 N 個數據。
解答:
10. 1000 萬字符串,其中有些是重複的,須要把重複的所有去掉,保留沒有重複的字符串。請怎麼設計和實現?
解答:
11. 一個文本文件,大約有一萬行,每行一個詞,要求統計出其中最頻繁出現的前 10 個詞,請給出思想,給出時間複雜度分析。
解答:
方案 1:這題是考慮時間效率。用 trie 樹統計每一個詞出現的次數,時間複雜度是 O(n*le)(le 表示單詞的平準長 度)。而後是找出出現最頻繁的前 10 個詞,能夠用堆來實現,前面的題中已經講到了,時間複雜度是 O(n*lg10)。因此總的時間複雜度,是 O(n*le)與 O(n*lg10)中較大的哪個。
12. 一個文本文件,找出前 10 個常常出現的詞,但此次文件比較長,說是上億行或十億行,總之沒法一次讀入內存,問最優解。
解答:
13. 100w 個數中找出最大的 100 個數。
解答:
14.
15. D
16. D
17. D
第5部分 處理海量數據問題之六把密匙
第5部分
5.1 密匙1、分而治之/Hash映射 + Hash統計 + 堆/快速/歸併排序
一、海量日誌數據,提取出某日訪問百度次數最多的那個IP。
既然是海量數據處理,那麼可想而知,給咱們的數據那就必定是海量的。針對這個數據的海量,咱們如何着手呢?對的,無非就是分而治之/hash映射 + hash統計 + 堆/快速/歸併排序,說白了,就是先映射,然後統計,最後排序:
1. 分而治之/hash映射:針對數據太大,內存受限,只能是:把大文件化成(取模映射)小文件,即16字方針:大而化小,各個擊破,縮小規模,逐個解決
2. hash統計:當大文件轉化了小文件,那麼咱們即可以採用常規的hash_map(ip,value)來進行頻率統計。
3. 堆/快速排序:統計完了以後,便進行排序(可採起堆排序),獲得次數最多的IP。
具體而論,則是: 「首先是這一天,而且是訪問百度的日誌中的IP取出來,逐個寫入到一個大文件中。注意到IP是32位的,最多有個2^32個IP。一樣能夠採用映射的方 法,好比模1000,把整個大文件映射爲1000個小文件,再找出每一個小文中出現頻率最大的IP(能夠採用hash_map進行頻率統計,而後再找出頻率 最大的幾個)及相應的頻率。而後再在這1000個最大的IP中,找出那個頻率最大的IP,即爲所求。」--十道海量數據處理面試題與十個方法大總結。
注:Hash取模是一種等價映射,不會存在同一個元素分散到不一樣小文件中去的狀況,即這裏採用的是mod1000算法,那麼相同的IP在hash後,只可能落在同一個文件中,不可能被分散的。
那到底什麼是hash映射呢?我換個角度舉個淺顯直白的例子,如本文的URL是:http://blog.csdn.net/v_july_v/article/details/7382693,當我把這個URL發表在微博上,便被映射成了:http://t.cn/zOixljh,於此,咱們發現URL自己的長度被縮短了,但這兩個URL對應的文章的是同一篇即本文。OK,有興趣的,還能夠再瞭解下一致性hash算法,見此文第五部分:http://blog.csdn.net/v_july_v/article/details/6879101。
二、搜索引擎會經過日誌文件把用戶每次檢索使用的全部檢索串都記錄下來,每一個查詢串的長度爲1-255字節。
假設目前有一千萬個記錄(這些查詢串的重複度比較高,雖然總數是1千萬,但若是除去重複後,不超過3百萬個。一個查詢串的重複度越高,說明查詢它的用戶越多,也就是越熱門),請你統計最熱門的10個查詢串,要求使用的內存不能超過1G。
由上面第1題,咱們知道,數據大則劃爲小的,但若是數據規模比較小,能一次性裝入內存呢?好比這第2題,雖然有一千萬個Query,可是因爲重複度比較 高,所以事實上只有300萬的Query,每一個Query255Byte,所以咱們能夠考慮把他們都放進內存中去,而如今只是須要一個合適的數據結構,在 這裏,Hash Table絕對是咱們優先的選擇。因此咱們摒棄分而治之/hash映射的方法,直接上hash統計,而後排序。So,
1. hash 統計:先對這批海量數據預處理(維護一個Key爲Query字串,Value爲該Query出現次數的HashTable,即 hash_map(Query,Value),每次讀取一個Query,若是該字串不在Table中,那麼加入該字串,而且將Value值設爲1;若是該 字串在Table中,那麼將該字串的計數加一便可。最終咱們在O(N)的時間複雜度內用Hash表完成了統計;
2. 堆排序:第二步、藉助堆 這個數據結構,找出Top K,時間複雜度爲N‘logK。即藉助堆結構,咱們能夠在log量級的時間內查找和調整/移動。所以,維護一個K(該題目中是10)大小的小根堆,而後遍 歷300萬的Query,分別和根元素進行對比因此,咱們最終的時間複雜度是:O(N) + N'*O(logK),(N爲1000萬,N’爲300萬)。
別忘了這篇文章中所述的堆排序思路:「維 護k個元素的最小堆,即用容量爲k的最小堆存儲最早遍歷到的k個數,並假設它們便是最大的k個數,建堆費時O(k),並調整堆(費時O(logk))後, 有k1>k2>...kmin(kmin設爲小頂堆中最小元素)。繼續遍歷數列,每次遍歷一個元素x,與堆頂元素比較,若 x>kmin,則更新堆(用時logk),不然不更新堆。這樣下來,總費時O(k*logk+(n-k)*logk)=O(n*logk)。此方法 得益於在堆中,查找等各項操做時間複雜度均爲logk。」--第三章續、Top K算法問題的實現。
固然,你也能夠採用trie樹,關鍵字域存該查詢串出現的次數,沒有出現爲0。最後用10個元素的最小推來對出現頻率進行排序。
三、有一個1G大小的一個文件,裏面每一行是一個詞,詞的大小不超過16字節,內存限制大小是1M。返回頻數最高的100個詞。
由上面那兩個例題,分而治之 + hash統計 + 堆/快速排序這個套路,咱們已經開始有了屢試不爽的感受。下面,再拿幾道再多多驗證下。請看此第3題:又是文件很大,又是內存受限,咋辦?還能怎麼辦呢?無非仍是:
1. 分 而治之/hash映射:順序讀文件中,對於每一個詞x,取hash(x)%5000,而後按照該值存到5000個小文件(記爲 x0,x1,...x4999)中。這樣每一個文件大概是200k左右。若是其中的有的文件超過了1M大小,還能夠按照相似的方法繼續往下分,直到分解獲得 的小文件的大小都不超過1M。
2. hash統計:對每一個小文件,採用trie樹/hash_map等統計每一個文件中出現的詞以及相應的頻率。
3. 堆/歸併排序:取出出現頻率最大的100個詞(能夠用含100個結點的最小堆),並把100個詞及相應的頻率存入文件,這樣又獲得了5000個文件。最後就是把這5000個文件進行歸併(相似於歸併排序)的過程了。
四、海量數據分佈在100臺電腦中,想個辦法高效統計出這批數據的TOP10。
此題與上面第3題相似,
1. 堆排序:在每臺電腦上求出TOP10,能夠採用包含10個元素的堆完成(TOP10小,用最大堆,TOP10大,用最小堆)。好比求TOP10大,咱們首先取前10個元素調整成最小堆,若是發現,而後掃描後面的數據,並與堆頂元素比較,若是比堆頂元素大,那麼用該元素替換堆頂,而後再調整爲最小堆。最後堆中的元素就是TOP10大。
2. 求出每臺電腦上的TOP10後,而後把這100臺電腦上的TOP10組合起來,共1000個數據,再利用上面相似的方法求出TOP10就能夠了。
上述第4題的此解法,經讀者反應有問題,如舉個例子如好比求2個文件中的top2,照你這種算法,若是第一個文件裏有
a 49次
b 50次
c 2次
d 1次
第二個文件裏有
a 9次
b 1次
c 11次
d 10次
雖然第 一個文件裏出來top2是b(50次),a(49次),第二個文件裏出來top2是c(11次),d(10次),而後2個top2:b(50次)a(49 次)與c(11次)d(10次)歸併,則算出全部的文件的top2是b(50 次),a(49 次),但其實是a(58 次),b(51 次)。是否真是如此呢?若真如此,那做何解決呢?
正如老夢所述:
首先,先把全部的數據遍歷一遍作一次hash(保證相同的數據條目劃分到同一臺電腦上進行運算),而後根據hash結果從新分佈到100臺電腦中,接下來的算法按照以前的便可。
最後因爲a可能出如今不一樣的電腦,各有必定的次數,再對每一個相同條目進行求和(因爲上一步驟中hash以後,也方便每臺電腦只須要對本身分到的條目內進行求和,不涉及到別的電腦,規模縮小)。
五、有10個文件,每一個文件1G,每一個文件的每一行存放的都是用戶的query,每一個文件的query均可能重複。要求你按照query的頻度排序。
直接上:
1. hash映射:順序讀取10個文件,按照hash(query)%10的結果將query寫入到另外10個文件(記爲)中。這樣新生成的文件每一個的大小大約也1G(假設hash函數是隨機的)。
2. hash統計:找一臺內存在2G左右的機器,依次對用hash_map(query, query_count)來統計每一個query出現的次數。注:hash_map(query,query_count)是用來統計每一個query的出現次數,不是存儲他們的值,出現一次,則count+1。
3. 堆/快速/歸併排序:利用快速/堆/歸併排序按照出現次數進行排序。將排序好的query和對應的query_cout輸出到文件中。這樣獲得了10個排好序的文件(記爲)。對這10個文件進行歸併排序(內排序與外排序相結合)。
除此以外,此題還有如下兩個方法:
方案2:通常query的總量是有限的,只是重複的次數比較多而已,可能對於全部的query,一次性就能夠加入到內存了。這樣,咱們就能夠採用trie樹/hash_map等直接來統計每一個query出現的次數,而後按出現次數作快速/堆/歸併排序就能夠了。
方案3:與方案1相似,但在作完hash,分紅多個文件後,能夠交給多個文件來處理,採用分佈式的架構來處理(好比MapReduce),最後再進行合併。
六、 給定a、b兩個文件,各存放50億個url,每一個url各佔64字節,內存限制是4G,讓你找出a、b文件共同的url?
能夠估計每一個文件安的大小爲5G×64=320G,遠遠大於內存限制的4G。因此不可能將其徹底加載到內存中處理。考慮採起分而治之的方法。
1. 分而治之/hash映射:遍歷文件a,對每一個url求取 ,而後根據所取得的值將url分別存儲到1000個小文件(記爲 )中。這樣每一個小文件的大約爲300M。遍歷文件b,採起和a相同的方式將url分別存儲到1000小文件中(記爲 )。這樣處理後,全部可能相同的url都在對應的小文件( )中,不對應的小文件不可能有相同的url。而後咱們只要求出1000對小文件中相同的url便可。
2. hash統計:求每對小文件中相同的url時,能夠把其中一個小文件的url存儲到hash_set中。而後遍歷另外一個小文件的每一個url,看其是否在剛纔構建的hash_set中,若是是,那麼就是共同的url,存到文件裏面就能夠了。
OK,此第一種方法:分而治之/hash映射 + hash統計 + 堆/快速/歸併排序,再看最後三道題,以下:
七、怎麼在海量數據中找出重複次數最多的一個?
方案1:先作hash,而後求模映射爲小文件,求出每一個小文件中重複次數最多的一個,並記錄重複次數。而後找出上一步求出的數據中重複次數最多的一個就是所求(具體參考前面的題)。
八、上千萬或上億數據(有重複),統計其中出現次數最多的錢N個數據。
方案1:上千萬或上億的數據,如今的機器的內存應該能存下。因此考慮採用hash_map/搜索二叉樹/紅黑樹等來進行統計次數。而後就是取出前N個出現次數最多的數據了,能夠用第2題提到的堆機制完成。
九、一個文本文件,大約有一萬行,每行一個詞,要求統計出其中最頻繁出現的前10個詞,請給出思想,給出時間複雜度分析。
方案1:這題是考慮時間效率。用trie樹統計每一個詞出現的次數,時間複雜度是O(n*le)(le表示單詞的平準長度)。而後是找出出現最頻繁的前 10個詞,能夠用堆來實現,前面的題中已經講到了,時間複雜度是O(n*lg10)。因此總的時間複雜度,是O(n*le)與O(n*lg10)中較大的 哪個。
接下來,我們來看第二種方法,雙層捅劃分。
5.2 密匙2、雙層桶劃分
雙層桶劃分----其實本質上仍是分而治之的思想,重在「分」的技巧上!
適用範圍:第k大,中位數,不重複或重複的數字
基本原理及要點:由於元素範圍很大,不能利用直接尋址表,因此經過屢次劃分,逐步肯定範圍,而後最後在一個能夠接受的範圍內進行。能夠經過屢次縮小,雙層只是一個例子。
擴展:
問題實例:
十、2.5億個整數中找出不重複的整數的個數,內存空間不足以容納這2.5億個整數。
有點像鴿巢原理,整數個數爲2^32,也就是,咱們能夠將這2^32個數,劃分爲2^8個區域(好比用單個文件表明一個區域),而後將數據分離到不一樣的區域,而後不一樣的區域在利用bitmap就能夠直接解決了。也就是說只要有足夠的磁盤空間,就能夠很方便的解決。
十一、5億個int找它們的中位數。
這個例子比上面那個更明顯。首先咱們將int劃分爲2^16個區域,而後讀取數據統計落到各個區域裏的數的個數,以後咱們根據統計結果就能夠判斷中位數 落到那個區域,同時知道這個區域中的第幾大數恰好是中位數。而後第二次掃描咱們只統計落在這個區域中的那些數就能夠了。
實際上,若是不是 int是int64,咱們能夠通過3次這樣的劃分便可下降到能夠接受的程度。便可以先將int64分紅2^24個區域,而後肯定區域的第幾大數,在將該區 域分紅2^20個子區域,而後肯定是子區域的第幾大數,而後子區域裏的數的個數只有2^20,就能夠直接利用direct addr table進行統計了。
5.3 密匙三:Bloom filter/Bitmap
Bloom filter
關於什麼是Bloom filter,請參看此文:海量數據處理之Bloom Filter詳解。
適用範圍:能夠用來實現數據字典,進行數據的判重,或者集合求交集
基本原理及要點:
對於原理來講很簡單,位數組+k個獨立hash函數。將hash函數對應的值的位數組置1,查找時若是發現全部hash函數對應位都是1說明存在,很明 顯這個過程並不保證查找的結果是100%正確的。同時也不支持刪除一個已經插入的關鍵字,由於該關鍵字對應的位會牽動到其餘的關鍵字。因此一個簡單的改進 就是 counting Bloom filter,用一個counter數組代替位數組,就能夠支持刪除了。
還有一個比較重要的問題,如何 根據輸入元素個數n,肯定位數組m的大小及hash函數個數。當hash函數個數k=(ln2)*(m/n)時錯誤率最小。在錯誤率不大於E的狀況下,m 至少要等於n*lg(1/E)才能表示任意n個元素的集合。但m還應該更大些,由於還要保證bit數組裏至少一半爲0,則m應該>=nlg(1 /E)*lge 大概就是nlg(1/E)1.44倍(lg表示以2爲底的對數)。
舉個例子咱們假設錯誤率爲0.01,則此時m應大概是n的13倍。這樣k大概是8個。
注意這裏m與n的單位不一樣,m是bit爲單位,而n則是以元素個數爲單位(準確的說是不一樣元素的個數)。一般單個元素的長度都是有不少bit的。因此使用bloom filter內存上一般都是節省的。
擴展:
Bloom filter將集合中的元素映射到位數組中,用k(k爲哈希函數個數)個映射位是否全1表示元素在不在這個集合中。Counting bloom filter(CBF)將位數組中的每一位擴展爲一個counter,從而支持了元素的刪除操做。Spectral Bloom Filter(SBF)將其與集合元素的出現次數關聯。SBF採用counter中的最小值來近似表示元素的出現頻率。
十二、給你A,B兩個文件,各存放50億條URL,每條URL佔用64字節,內存限制是4G,讓你找出A,B文件共同的URL。若是是三個乃至n個文件呢?
根據這個問題咱們來計算下內存的佔用,4G=2^32大概是40億*8大概是340億,n=50億,若是按出錯率0.01算須要的大概是650億個 bit。如今可用的是340億,相差並很少,這樣可能會使出錯率上升些。另外若是這些urlip是一一對應的,就能夠轉換成ip,則大大簡單了。
同時,上文的第5題:給定a、b兩個文件,各存放50億個url,每一個url各佔64字節,內存限制是4G,讓你找出a、b文件共同的url?若是容許有 必定的錯誤率,能夠使用Bloom filter,4G內存大概能夠表示340億bit。將其中一個文件中的url使用Bloom filter映射爲這340億bit,而後挨個讀取另一個文件的url,檢查是否與Bloom filter,若是是,那麼該url應該是共同的url(注意會有必定的錯誤率)。
Bitmap
至於什麼是Bitmap,請看此文:http://blog.csdn.net/v_july_v/article/details/6685962。下面關於Bitmap的應用,直接上題,以下第九、10道:
1三、在2.5億個整數中找出不重複的整數,注,內存不足以容納這2.5億個整數。
方案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:也可採用與第1題相似的方法,進行劃分小文件的方法。而後在小文件中找出不重複的整數,並排序。而後再進行歸併,注意去除重複的元素。
1四、騰訊面試題:給40億個不重複的unsigned int的整數,沒排過序的,而後再給一個數,如何快速判斷這個數是否在那40億個數當中?
方案1:frome oo,用位圖/Bitmap的方法,申請512M的內存,一個bit位表明一個unsigned int值。讀入40億個數,設置相應的bit位,讀入要查詢的數,查看相應bit位是否爲1,爲1表示存在,爲0表示不存在。
5.4 密匙4、Trie樹/數據庫/倒排索引
Trie樹
適用範圍:數據量大,重複多,可是數據種類小能夠放入內存
基本原理及要點:實現方式,節點孩子的表示方式
擴展:壓縮實現。
問題實例:
1. 有10個文件,每一個文件1G,每一個文件的每一行都存放的是用戶的query,每一個文件的query均可能重複。要你按照query的頻度排序。
2. 1000萬字符串,其中有些是相同的(重複),須要把重複的所有去掉,保留沒有重複的字符串。請問怎麼設計和實現?
3. 尋找熱門查詢:查詢串的重複度比較高,雖然總數是1千萬,但若是除去重複後,不超過3百萬個,每一個不超過255字節。
4. 上面的第8題:一個文本文件,大約有一萬行,每行一個詞,要求統計出其中最頻繁出現的前10個詞。其解決方法是:用trie樹統計每一個詞出現的次數,時間複雜度是O(n*le)(le表示單詞的平準長度),而後是找出出現最頻繁的前10個詞。
更多有關Trie樹的介紹,請參見此文:從Trie樹(字典樹)談到後綴樹。
數據庫索引
適用範圍:大數據量的增刪改查
基本原理及要點:利用數據的設計實現方法,對海量數據的增刪改查進行處理。
關於數據庫索引及其優化,更多可參見此文:http://www.cnblogs.com/pkuoliver/archive/2011/08/17/mass-data-topic-7-index-and-optimize.html。同時,關於MySQL索引背後的數據結構及算法原理,這裏還有一篇很好的文章:http://www.codinglabs.org/html/theory-of-mysql-index.html。
倒排索引(Inverted index)
適用範圍:搜索引擎,關鍵字查詢
基本原理及要點:爲什麼叫倒排索引?一種索引方法,被用來存儲在全文搜索下某個單詞在一個文檔或者一組文檔中的存儲位置的映射。
以英文爲例,下面是要被索引的文本:
T0 = "it is what it is"
T1 = "what is it"
T2 = "it is a banana"
咱們就能獲得下面的反向文件索引:
"a": {2}
"banana": {2}
"is": {0, 1, 2}
"it": {0, 1, 2}
"what": {0, 1}
檢索的條件"what","is"和"it"將對應集合的交集。
正向索引開發出來用來存儲每一個文檔的單詞的列表。正向索引的查詢每每知足每一個文檔有序頻繁的全文查詢和每一個單詞在校驗文檔中的驗證這樣的查詢。在正向索 引中,文檔佔據了中心的位置,每一個文檔指向了一個它所包含的索引項的序列。也就是說文檔指向了它包含的那些單詞,而反向索引則是單詞指向了包含它的文檔, 很容易看到這個反向的關係。
擴展:
問題實例:文檔檢索系統,查詢那些文件包含了某單詞,好比常見的學術論文的關鍵字搜索。
關於倒排索引的應用,更多請參見:第二十3、四章:楊氏矩陣查找,倒排索引關鍵詞Hash不重複編碼實踐,及第二十六章:基於給定的文檔生成倒排索引的編碼與實踐。
5.5 密匙5、外排序
適用範圍:大數據的排序,去重
基本原理及要點:外排序的歸併方法,置換選擇敗者樹原理,最優歸併樹
擴展:
問題實例:
1).有一個1G大小的一個文件,裏面每一行是一個詞,詞的大小不超過16個字節,內存限制大小是1M。返回頻數最高的100個詞。
這個數據具備很明顯的特色,詞的大小爲16個字節,可是內存只有1M作hash明顯不夠,因此能夠用來排序。內存能夠當輸入緩衝區使用。
關於多路歸併算法及外排序的具體應用場景,請參見此文:第十章、如何給10^7個數據量的磁盤文件排序。
5.6 密匙6、分佈式處理之Mapreduce
適用範圍:數據量大,可是數據種類小能夠放入內存
基本原理及要點:將數據交給不一樣的機器去處理,數據劃分,結果歸約。
擴展:
問題實例:
1. The canonical example application of MapReduce is a process to count the appearances of each different word in a set of documents:
2. 海量數據分佈在100臺電腦中,想個辦法高效統計出這批數據的TOP10。
3. 一共有N個機器,每一個機器上有N個數。每一個機器最多存O(N)個數並對它們操做。如何找到N^2個數的中數(median)?
更多具體闡述請參見:從Hadhoop框架與MapReduce模式中談海量數據處理,及MapReduce技術的初步瞭解與學習。
的
18.
19. 的
第6部分 設計題
5.7 日誌收集分析系統
1. 日誌分佈在各個業務系統中,咱們須要對當天的日誌進行實時彙總統計,同時又能離線查詢歷史的彙總數據(PV、UV、IP)
解答:
一、經過flume將不一樣系統的日誌收集到kafka中
二、經過storm實時的處理PV、UV、IP
三、經過kafka的consumer將日誌生產到hbase中。
四、經過離線的mapreduce或者hive,處理hbase中的數據
2. Hive語言實現word count
解答:
1.建表
2.分組(group by)統計wordcount
select word,count(1) from table1 group by word;
3. 實時數據統計會用到哪些技術,他們各自的應用場景及區別是什麼?
解答:
flume:日誌收集系統,主要用於系統日誌的收集
kafka:消息隊列,進行消息的緩存和系統的解耦
storm:實時計算框架,進行流式的計算。
4. 的
5. 的
6. 的
5.8 MapReduce
1. 有兩個文本文件,文件中的數據按行存放,請編寫MapReduce程序,找到兩個文件中彼此不相同的行(寫出思路便可)
解答:
寫個mapreduce鏈 用依賴關係,一共三個mapreduce,第一個處理第一個文件,第二個處理第二個文件,第三個處理前兩個的輸出結果,第一個mapreduce將文件去重,第二個mapreduce也將文件去重,第三個作wordcount,wordcount爲1的結果就是不一樣的
2. 共同朋友
1. A B CD E F
2. B A CD E
3. C A B E
4. D B E
5. E A BC D
6. F A
第一個字母表示本人,其餘事他的朋友,找出有共同朋友的人,和共同的朋友是誰
解答:
思路:例如A,他的朋友是B\C\D\E\F\,那麼BC的共同朋友就是A。因此將BC做爲key,將A做爲value,在map端輸出便可!其餘的朋友循環處理。
import java.io.IOException;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
10. import org.apache.hadoop.mapreduce.Mapper;
11. import org.apache.hadoop.mapreduce.Reducer;
12. import org.apache.hadoop.mapreduce.Mapper.Context;
13. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
14. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
15. import org.apache.hadoop.util.GenericOptionsParser;
public class FindFriend {
public static class ChangeMapper extends Mapper<Object, Text, Text,
Text>{
@Override
public void map(Object key, Text value, Context context) throws
IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
Text owner = new Text();
Set<String> set = new TreeSet<String>();
owner.set(itr.nextToken());
while (itr.hasMoreTokens()) {
set.add(itr.nextToken());
}
String[] friends = new String[set.size()];
friends = set.toArray(friends);
for(int i=0;i<friends.length;i++){
for(int j=i+1;j<friends.length;j++){
String outputkey = friends[i]+friends[j];
context.write(new Text(outputkey),owner);
}
}
}
}
public static class FindReducer extends Reducer<Text,Text,Text,Text>
{
public void reduce(Text key, Iterable<Text> values,
Context context) throws IOException,
InterruptedException {
String commonfriends ="";
for (Text val : values) {
if(commonfriends == ""){
commonfriends = val.toString();
}else{
commonfriends =
commonfriends+":"+val.toString();
}
}
context.write(key, new
Text(commonfriends));
}
}
public static void main(String[] args) throws IOException,
InterruptedException, ClassNotFoundException {
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length < 2) {
System.err.println("args error");
System.exit(2);
}
Job job = new Job(conf, "word count");
job.setJarByClass(FindFriend.class);
job.setMapperClass(ChangeMapper.class);
job.setCombinerClass(FindReducer.class);
job.setReducerClass(FindReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
for (int i = 0; i < otherArgs.length - 1; ++i) {
FileInputFormat.addInputPath(job, new Path(otherArgs[i]));
}
FileOutputFormat.setOutputPath(job,
new Path(otherArgs[otherArgs.length - 1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
結果:
1. AB E:C:D
2. AC E:B
3. AD B:E
4. AE C:B:D
5. BC A:E
6. BD A:E
7. BE C:D:A
8. BF A
9. CD E:A:B
10. CE A:B
11. CF A
12. DE B:A
13. DF A
14. EF A
3. 的
4. 的
5. 的
6. 的
5.9 優化
1. 若是要存儲海量的小文件(大小都是幾百K-幾M)請簡述本身的設計方案
解答:
1.將小文件打成har文件存儲
2.將小文件序列化到hdfs中
2.
3. 的
第7部分 涉及Java基礎部分
1. ArrayList、Vector、LinkedList的區別及其優缺點?HashMap、HashTable的區別及優缺點?
解答:
ArrayList 和Vector是採用數組方式存儲數據的,是根據索引來訪問元素的,均可以根據須要自動擴展內部數據長度,以便增長和插入元素,都容許直接序號索引元素,可是插入數據要涉及到數組元素移動等內存操做,因此索引數據快插入數據慢,他們最大的區別就是synchronized同步的使用。
LinkedList使用雙向鏈表實現存儲,按序號索引數據須要進行向前或向後遍歷,可是插入數據時只須要記錄本項的先後項便可,因此插入數度較快!
若是隻是查找特定位置的元素或只在集合的末端增長、移除元素,那麼使用Vector或ArrayList均可以。若是是對其它指定位置的插入、刪除操做,最好選擇LinkedList
HashMap、HashTable的區別及其優缺點:
HashTable 中的方法是同步的 HashMap的方法在缺省狀況下是非同步的 所以在多線程環境下須要作額外的同步機制。
HashTable不容許有null值 key和value都不容許,而HashMap容許有null值 key和value都容許 所以HashMap 使用containKey()來判斷是否存在某個鍵。
HashTable 使用Enumeration ,而HashMap使用iterator。
Hashtable是Dictionary的子類,HashMap是Map接口的一個實現類。
2. 的
3. 的
第8部分 十道海量數據處理面試題
第6部分
第7部分
第8部分
8.1 海量日誌數據,提取出某日訪問百度次數最多的那個 IP 。
此題,在我以前的一篇文章算法裏頭有所提到,當時給出的方案是:IP 的數目仍是有限的,最多 2^32個,因此能夠考慮使用 hash 將 ip 直接存入內存,而後進行統計。再詳細介紹下此方案:首先是這一天,而且是訪問百度的日誌中的 IP 取出來,逐個寫入到一個大文件中。注意到 IP 是 32 位的,最多有個 2^32 個 IP。一樣能夠採用映射的方法,好比模 1000,把整個大文件映射爲 1000 個小文件,再找出每一個小文中出現頻率最大的 IP(能夠採用 hash_map 進行頻率統計,而後再找出頻率最大的幾個)及相應的頻率。而後再在這 1000 個最大的 IP 中,找出那個頻率最大的 IP,即爲所求。
8.2 2 、搜 索引擎會經過日誌文件把用戶每次檢索使用的全部檢索串都記錄下來,每一個查詢串的長度爲1-255 字節。假設目前有一千萬個記錄(這些查詢串的重複度比較高,雖然總數是 1 千萬,但若是除去重複後,不超過 3 百萬個。一個查詢串的重複度越高,說明查詢它的用戶越多,也就是越熱門。),請你統計最熱門的10 個查詢串,要求使用的內存不能超過 1G。
典型的 Top K 算法,仍是在這篇文章裏頭有所闡述。文中,給出的最終算法是:第一步、先對這批海量數據預處理,在 O(N)的時間內用 Hash 表完成排序;而後,第二步、藉助堆這個數據結構,找出 TopK,時間複雜度爲 N‗logK。即,藉助堆結構,咱們能夠在 log 量級的時間內查找和調整/移動。所以,維護一個 K(該題目中是 10)大小的小根堆,而後遍歷 300 萬的 Query,分別和根元素進行對比因此,咱們最終的時間複雜度是:O(N) + N'*O(logK),(N 爲 1000 萬,N‘爲 300 萬)。ok,更多,詳情,請參考原文。或者:採用 trie 樹,關鍵字域存該查詢串出現的次數,沒有出現爲 0。最後用 10 個元素的最小推來對出現頻率進行排序。
8.3 有一個 1G 過 大小的一個文件,裏面每一行是一個詞,詞的大小不超過 16 字節,內存限制大小是
1M 。返回頻數最高的 100 個詞。方案:順序讀文件中,對於每一個詞 x,取 hash(x)%5000,而後按照該值存到 5000 個小文件(記爲
www.aboutyun.com
x0,x1,...x4999)中。這樣每一個文件大概是 200k 左右。若是其中的有的文件超過了 1M 大小,還能夠按照相似的方法繼續往下分,直到分解獲得的小文件的大小都不超過 1M。 對每一個小文件,統計每一個文件中出現的詞以及相應的頻率(能夠採用 trie 樹/hash_map等),並取出出現頻率最大的 100 個詞(能夠用含 100 個結點的最小堆),並把 100 個詞及相應的頻率存入文件,這樣又獲得了 5000個文件。下一步就是把這 5000 個文件進行歸併(相似與歸併排序)的過程了。
8.4 4 有 10 個文件 件,每一個文件 1G ,每一個文件的每一行存放的都是用戶的 query ,每一個文件的 query照 均可能重複。
要求你按照 query 的頻度排序。仍是典型的 TOP K 算法,解決方案以下:
方案 1:順序讀取 10 個文件,按照 hash(query)%10 的結果將 query 寫入到另外 10 個文件(記爲)中。這樣新生成的文件每一個的大小大約也 1G(假設 hash 函數是隨機的)。找一臺內存在 2G 左右的機器,依次對用 hash_map(query, query_count)來統計每一個 query 出現的次數。利用快速/堆/歸併排序按照出現次數進行排序。將排序好的query 和對應的 query_cout 輸出到文件中。這樣獲得了 10 個排好序的文件(記爲)。對這 10 個文件進行歸併排序(內排序與外排序相結合)。
方案 2:通常 query 的總量是有限的,只是重複的次數比較多而已,可能對於全部的 query,一次性就能夠加入到內存了。這樣,咱們就能夠採用trie 樹/hash_map 等直接來統計每一個 query 出現的次數,而後按出現次數作快速/堆/歸併排序就能夠了。
方案 3:與方案 1 相似,但在作完 hash,分紅多個文件後,能夠交給多個文件來處理,採用分佈式的架構來處理(好比 MapReduce),最後再進行合併。
8.5 五、 給定 a、、b 兩個文件,各存放50 億個 url ,每一個 url 各佔 64 字節,內存限制是 4G ,讓你找出 a 、b 文件共同的 url ?
方案 1:能夠估計每一個文件安的大小爲 5G×64=320G,遠遠大於內存限制的 4G。因此不可能將其徹底
加載到內存中處理。考慮採起分而治之的方法。
遍歷文件 a,對每一個 url 求取 hash(url)%1000,而後根據所取得的值將 url 分別存儲到 1000 個小文件
(記爲 a0,a1,...,a999)中。這樣每一個小文件的大約爲 300M。
遍歷文件 b,採起和 a 相同的方式將 url 分別存儲到 1000 小文件(記爲 b0,b1,...,b999)。這樣處理後,
全部可能相同的 url 都在對應的小文件(a0vsb0,a1vsb1,...,a999vsb999)中,不對應的小文件不可能有相
www.aboutyun.com
同的 url。而後咱們只要求出 1000 對小文件中相同的 url 便可。
求每對小文件中相同的 url 時,能夠把其中一個小文件的 url 存儲到 hash_set 中。而後遍歷另外一個小
文件的每一個 url,看其是否在剛纔構建的 hash_set 中,若是是,那麼就是共同的url,存到文件裏面就能夠
了。
方案 2:若是容許有必定的錯誤率,能夠使用 Bloom filter,4G 內存大概能夠表示 340 億 bit。將其中
一個文件中的url使用Bloom filter映射爲這340億bit,而後挨個讀取另一個文件的url,檢查是否與Bloom
filter,若是是,那麼該 url 應該是共同的 url(注意會有必定的錯誤率)。
Bloom filter 往後會在本 BLOG 內詳細闡述。
8.6 在 2.5 億個整數中找出不重複的整數,注,內存不足以容納這 2.5 億個整數。
方案 1:採用 2-Bitmap(每一個數分配 2bit,00 表示不存在,01 表示出現一次,10 表示屢次,11 無心
義)進行,共需內存內存,還能夠接受。而後掃描這2.5 億個整數,查看 Bitmap 中相對應位,若是是 00
變 01,01 變 10,10 保持不變。所描完過後,查看 bitmap,把對應位是 01 的整數輸出便可。
方案 2:也可採用與第 1 題相似的方法,進行劃分小文件的方法。而後在小文件中找出不重複的整數,
並排序。而後再進行歸併,注意去除重複的元素。
8.7 騰訊面試題:給 40 億個不重複的 unsigned int 的整數,沒排過序的,而後再給一個數,如何快那速判斷這個數是否在那 40 億個數當中?
與上第 6 題相似,個人第一反應時快速排序+二分查找。如下是其它更好的方法: 方案 1:oo,申請
512M 的內存,一個 bit 位表明一個 unsigned int 值。讀入 40 億個數,設置相應的 bit 位,讀入要查詢的數,
查看相應 bit 位是否爲 1,爲 1 表示存在,爲 0 表示不存在。
dizengrong: 方案 2:這個問題在《編程珠璣》裏有很好的描述,你們能夠參考下面的思路,探討一
下:又由於 2^32 爲 40 億多,因此給定一個數可能在,也可能不在其中;這裏咱們把 40 億個數中的每一
個用 32 位的二進制來表示假設這 40 億個數開始放在一個文件中。
而後將這 40 億個數分紅兩類: 1.最高位爲 0 2.最高位爲 1 並將這兩類分別寫入到兩個文件中,其中一
個文件中數的個數<=20 億,而另外一個>=20 億(這至關於折半了);與要查找的數的最高位比較並接着進
入相應的文件再查找
再而後把這個文件爲又分紅兩類: 1.次最高位爲 0 2.次最高位爲 1
並將這兩類分別寫入到兩個文件中,其中一個文件中數的個數<=10 億,而另外一個>=10 億(這至關於
折半了); 與要查找的數的次最高位比較並接着進入相應的文件再查找。 ....... 以此類推,就能夠找到了,
並且時間複雜度爲 O(logn),方案 2 完。
附:這裏,再簡單介紹下,位圖方法: 使用位圖法判斷整形數組是否存在重複判斷集合中存在重複
是常見編程任務之一,當集合中數據量比較大時咱們一般但願少進行幾回掃描,這時雙重循環法就不可取
了。
位圖法比較適合於這種狀況,它的作法是按照集合中最大元素max建立一個長度爲max+1的新數組,
而後再次掃描原數組,遇到幾就給新數組的第幾位置上1,如遇到 5 就給新數組的第六個元素置 1,這樣下
次再遇到 5 想置位時發現新數組的第六個元素已是 1 了,這說明此次的數據確定和之前的數據存在着重
復。這種給新數組初始化時置零其後置一的作法相似於位圖的處理方法故稱位圖法。它的運算次數最壞的
狀況爲 2N。若是已知數組的最大值即能事先給新數組定長的話效率還能提升一倍。
8.8 8 、怎麼在海量數據中找出重複次數最多的一個?
方案 1:先作 hash,而後求模映射爲小文件,求出每一個小文件中重複次數最多的一個,並記錄重複次數。
而後找出上一步求出的數據中重複次數最多的一個就是所求(具體參考前面的題)。
8.9 9 、上千萬或上億數據(有重複),統計其中出現次數最多的錢 N 個數據。
方案 1:上千萬或上億的數據,如今的機器的內存應該能存下。因此考慮採用 hash_map/搜索二叉樹/紅黑樹等來進行統計次數。而後就是取出前 N 個出現次數最多的數據了,能夠用第 2 題提到的堆機制完成。
8.1010 、一個文本文件,大約有一萬行,每行一個詞,要求統計出其中最頻繁出現的前10 個詞,請給出
思想,給出時間複雜度分析。
方案 1:
這題是考慮時間效率。用 trie 樹統計每一個詞出現的次數,時間複雜度是O(n*le)(le 表示單詞的平準長度)。而後是找出出現最頻繁的前 10 個詞,能夠用堆來實現,前面的題中已經講到了,時間複雜度是 O(n*lg10)。因此總的時間複雜度,是O(n*le)與 O(n*lg10)中較大的哪個。附、100w 個數中找出最大的 100 個數。
方案1:
在前面的題中,咱們已經提到了,用一個含100個元素的最小堆完成。複雜度爲O(100w*lg100)。
方案 2:
採用快速排序的思想,每次分割以後只考慮比軸大的一部分,知道比軸大的一部分在比 100多的時候,採用傳統排序算法排序,取前 100 個。複雜度爲 O(100w*100)。
方案 3:
採用局部淘汰法。選取前 100 個元素,並排序,記爲序列 L。而後一次掃描剩餘的元素 x,與排好序的 100 個元素中最小的元素比,若是比這個最小的要大,那麼把這個最小的元素刪除,並把 x 利用插入排序的思想,插入到序列 L 中。依次循環,知道掃描了全部的元素。複雜度爲 O(100w*100)。
第9部分 遺留
3十一、在線安裝ssh的命令以及文件解壓的命令?
3十二、把公鑰都追加到受權文件的命令?該命令是否在root用戶下執行?
31三、HadoopHA集羣中,各個服務的啓動和關閉的順序?
31四、HDFS中的block塊默認保存幾份?默認大小多少?
31五、NameNode中的meta數據是存放在NameNode自身,仍是DataNode等其餘節點?DatNOde節點自身是否有Meta數據存在?
31六、下列那個程序一般與NameNode在一個節點啓動?
31七、下面那個程序負責HDFS數據存儲?
31八、 在HadoopHA集羣中,簡述Zookeeper的主要做用,以及啓動和查看狀態的命令?
31九、HBase在進行模型設計時重點在什麼地方?一張表中國定義多少個Column Family最合適?爲何?
320、如何提升HBase客戶端的讀寫性能?請舉例說明。
32一、基於HadoopHA集羣進行MapReduce開發時,Configuration如何設置hbase.zookeeper,quorum屬性的值?
32二、 在hadoop開發過程當中使用過哪些算法?其應用場景是什麼?
32三、MapReduce程序如何發佈?若是MapReduce中涉及到了第三方的jar包,該如何處理?
32四、在實際工做中使用過哪些集羣的運維工具,請分別闡述其做用。
32五、hadoop中combiner的做用?
32六、IO的原理,IO模型有幾種?
32七、Windows用什麼樣的模型,Linux用什麼樣的模型?
32八、一臺機器如何應對那麼多的請求訪問,高併發到底怎麼實現,一個請求怎麼產生的,
在服務端怎麼處理的,最後怎麼返回給用戶的,整個的環節操做系統是怎麼控制的?
32九、hdfs的client端,複製到第三個副本時宕機,hdfs怎麼恢復保證下次寫第三副本?block塊信息是先寫dataNode仍是先寫nameNode?
330、快排現場寫程序實現?
33一、jvm的內存是怎麼分配原理?
33二、毒酒問題---1000桶酒,其中1桶有毒。而一旦吃了,毒性會在1周後發做。問最少須要多少隻老鼠可在一週內找出毒酒?
33三、用棧實現隊列?
33四、鏈表倒序實現?
33五、多線程模型怎樣(生產,消費者)?平時併發多線程都用哪些實現方式?
33六、synchonized是同步悲觀鎖嗎?互斥?怎麼寫同步提升效率?
33七、4億個數字,找出哪些重複的,要用最小的比較次數,寫程序實現。
33八、java是傳值仍是傳址?
33九、 java處理多線程,另外一線程一直等待?
340、一個網絡商城1天大概產生多少G的日誌?
34一、大概有多少條日誌記錄(在不清洗的狀況下)?
34二、日訪問量大概有多少個?
34三、註冊數大概多少?
34四、咱們的日誌是否是除了apache的訪問日誌是否是還有其餘的日誌?
34五、假設咱們有其餘的日誌是否是能夠對這個日誌有其餘的業務分析?這些業務分析都有什麼?
34六、問:大家的服務器有多少臺?
34七、問:大家服務器的內存多大?
34八、問:大家的服務器怎麼分佈的?(這裏說地理位置分佈,最好也從機架方面也談談)
34九、問:你日常在公司都幹些什麼(一些建議)
350、hbase怎麼預分區?
35一、hbase怎麼給web前臺提供接口來訪問(HTABLE能夠提供對HTABLE的訪問,可是怎麼查詢同一條記錄的多個版本數據)?
35二、.htable API有沒有線程安全問題,在程序中是單例仍是多例?
35三、咱們的hbase大概在公司業務中(主要是網上商城)大概都幾個表,幾個表簇,大概都存什麼樣的數據?
35四、hbase的併發問題?
Storm問題:
35五、metaq消息隊列 zookeeper集羣 storm集羣(包括zeromq,jzmq,和storm自己)就能夠完成對商城推薦系統功能嗎?還有沒有其餘的中間件?
35六、storm怎麼完成對單詞的計數?(我的看完storm一直都認爲他是流處理,好像沒有積攢數據的能力,都是處理完以後直接分發給下一個組件)
35七、storm其餘的一些面試常常問的問題?
二十3、面試題(18道):
35八、大家的集羣規模?
開發集羣:10臺(8臺可用)8核cpu
35九、大家的數據是用什麼導入到數據庫的?導入到什麼數據庫?
處理以前的導入:經過hadoop命令導入到hdfs文件系統
處理完成以後的導出:利用hive處理完成以後的數據,經過sqoop導出到mysql數據庫中,以供報表層使用。
360、大家業務數據量多大?有多少行數據?(面試了三家,都問這個問題)
開發時使用的是部分數據,不是全量數據,有將近一億行(八、9千萬,具體不詳,通常開發中也沒人會特別關心這個問題)
36一、大家處理數據是直接讀數據庫的數據仍是讀文本數據?
將日誌數據導入到hdfs以後進行處理
36二、大家寫hive的hql語句,大概有多少條?
不清楚,我本身寫的時候也沒有作過統計
36三、大家提交的job任務大概有多少個?這些job執行完大概用多少時間?(面試了三家,都問這個問題)
沒統計過,加上測試的,會與不少
36四、hive跟hbase的區別是?
36五、你在項目中主要的工做任務是?
利用hive分析數據
36六、你在項目中遇到了哪些難題,是怎麼解決的?
某些任務執行時間過長,且失敗率太高,檢查日誌後發現沒有執行完就失敗,緣由出在hadoop的job的timeout太短(相對於集羣的能力來講),設置長一點便可
36七、你本身寫過udf函數麼?寫了哪些?
這個我沒有寫過
36八、你的項目提交到job的時候數據量有多大?(面試了三家,都問這個問題)
不清楚是要問什麼
36九、reduce後輸出的數據量有多大?
370、一個網絡商城1天大概產生多少G的日誌? 4tb
37一、大概有多少條日誌記錄(在不清洗的狀況下)? 7-8百萬條
37二、日訪問量大概有多少個?百萬
37三、註冊數大概多少?不清楚幾十萬吧
37四、咱們的日誌是否是除了apache的訪問日誌是否是還有其餘的日誌?關注信息
37五、假設咱們有其餘的日誌是否是能夠對這個日誌有其餘的業務分析?這些業務分析都有什麼?
二十4、面試題(1道):
37六、有一千萬條短信,有重複,以文本文件的形式保存,一行一條,有重複。
請用5分鐘時間,找出重複出現最多的前10條。
分析:
常規方法是先排序,在遍歷一次,找出重複最多的前10條。可是排序的算法複雜度最低爲nlgn。
能夠設計一個hash_table,hash_map<string, int>,依次讀取一千萬條短信,加載到hash_table表中,而且統計重複的次數,與此同時維護一張最多10條的短信表。
這樣遍歷一次就能找出最多的前10條,算法複雜度爲O(n)。
二十5、面試題(5道):
37七、job的運行流程(提交一個job的流程)?
37八、Hadoop生態圈中各類框架的運用場景?
37九、hive中的壓縮格式RCFile、TextFile、SequenceFile各有什麼區別?
以上3種格式同樣大的文件哪一個佔用空間大小.還有Hadoop中的一個HA壓縮。
380、假如:Flume收集到的數據不少個小文件,我須要寫MR處理時將這些文件合併
(是在MR中進行優化,不讓一個小文件一個MapReduce)
他們公司主要作的是中國電信的流量計費爲主,專門寫MR。
38三、解釋「hadoop」和「hadoop生態系統」兩個概念。
38四、說明Hadoop 2.0的基本構成。
38五、相比於HDFS1.0, HDFS 2.0最主要的改進在哪幾方面?
38六、試使用「步驟1,步驟2,步驟3…..」說明YARN中運行應用程序的基本流程。
38七、「MapReduce 2.0」與「YARN」是否等同,嘗試解釋說明。
38八、MapReduce 2.0中,MRAppMaster主要做用是什麼,MRAppMaster如何實現任務容錯的?
38九、爲何會產生yarn,它解決了什麼問題,有什麼優點?
39七、Hadoop體系結構(HDFS與MapReduce的體系結構)、Hadoop相比傳統數據存儲方式(好比mysql)的優點?
39八、Hadoop集羣的搭建步驟、Hadoop集羣搭建過程當中碰到了哪些常見問題(好比datanode沒有起來)、Hadoop集羣管理(如何動態增長和卸載節點、safe mode是什麼、經常使用的命令kill等)?
39九、HDFS的namenode與secondarynamenode的工做原理(重點是日誌拉取和合並過程)、hadoop 1.x的HDFS的HA方案(namenode掛掉的狀況如何處理、datanode掛掉的狀況如何處理)?
400、HDFS的經常使用shell命令有哪些?分別對應哪些Client Java API?:顯示文件列表、建立目錄、文件上傳與下載、文件內容查看、刪除文件
40一、HDFS的文件上傳與下載底層工做原理(或HDFS部分源碼分析):FileSystem的create()和open()方法源碼分析?
40二、MapReduce計算模型、MapReduce基礎知識點(MapReduce新舊API的使用、在linux命令行運行MapReduce程序、自定義Hadoop數據類型)?
40三、MapReduce執行流程:「天龍八步」,計數器、自定義分區、自定義排序、自定義分組、如何對value進行排序:次排序+自定義分組、歸約?
40四、MapReduce的shuffle工做原理、MapReduce工做原理(MapReduce源碼、InputStream源碼、waitForCompletion()源碼)、jobtracker如何建立map任務和reduce任務是面試的重點。
40五、MapReduce進階知識:Hadoop的幾種文件格式、常見輸入輸出格式化類、多輸入多輸出機制、MapReduce的常見算法(各類join原理和優缺點、次排序和總排序)?
40六、MapReduce性能優化(shuffle調優、壓縮算法、更換調度器、設置InputSplit大小減小map任務數量、map和reduce的slot如何設置、數據傾斜原理和如何解決)?
40七、HBase的體系結構和搭建步驟、shell命令與Java API、HBase做爲MapReduce的輸入輸出源、高級JavaAPI、工做原理(重點是combine和split原理)、行鍵設計原則、性能優化?
40八、Hive的工做原理、兩種元數據存放方式、幾種表之間的區別、數據導入的幾種方式、幾種文件格式、UDF函數、性能調優(重點是join的時候如何放置大小表)?
40九、Zookeeper、Flume、Pig、Sqoop的基本概念和使用方式,ZooKeeper被問到過其如何維護高可用(若是某個節點掛掉了它的處理機制)?
4十、Hadoop2:體系結構、HDFS HA、YARN?
4十一、關係型數據庫和非關係型數據庫的區別?
提示:
關係型數據庫經過外鍵關聯來創建表與表之間的關係,非關係型數據庫一般指數據以對象的形式存儲在數據庫中,而對象之間的關係經過每一個對象自身的屬性來決定。
對數據庫高併發讀寫、高可擴展性和高可用性的需求,對海量數據的高效率存儲和訪問的需求,存儲的結構不同,非關係數據庫是列式存儲,在存儲結構上更加自由。
4十二、hive的兩張表關聯,使用mapreduce是怎麼寫的?
提示:打標記笛卡爾乘積
41三、hive相對於Oracle來講有那些優勢?
提示:
hive是數據倉庫,oracle是數據庫,hive可以存儲海量數據,hive還有更重要的做用就是數據分析,最主要的是免費。
41四、如今咱們要對Oracle和HBase中的某些表進行更新,你是怎麼操做?
提示:
disable '表名'
alter '代表', NAME => '列名', VERSIONS=>3
enable '表名'
41五、HBase接收數據,若是短期導入數量過多的話就會被鎖,該怎麼辦? 集羣數16臺 ,高可用性的環境。
參考:
經過調用HTable.setAutoFlush(false)方法能夠將HTable寫客戶端的自動flush關閉,這樣能夠批量寫入數據到HBase,而不是有一條put就執行一次更新,只有當put填滿客戶端寫緩存時,才實際向HBase服務端發起寫請求。默認狀況下auto flush是開啓的。
41六、說說大家作的hadoop項目流程?
41七、大家公司的服務器架構是怎麼樣的(分別說下web跟hadoop)?
41八、假若有1000W用戶同時訪問同一個頁面,怎麼處理?
提示:優化代碼、靜態化頁面、增長緩存機制、數據庫集羣、庫表散列。。。
41九、怎樣將mysql的數據導入到hbase中?不能使用sqoop,速度太慢了
提示:
A、一種能夠加快批量寫入速度的方法是經過預先建立一些空的regions,這樣當數據寫入HBase時,會按照region分區狀況,在集羣內作數據的負載均衡。
B、hbase裏面有這樣一個hfileoutputformat類,他的實現能夠將數據轉換成hfile格式,經過new 一個這個類,進行相關配置,這樣會在hdfs下面產生一個文件,這個時候利用hbase提供的jruby的loadtable.rb腳本就能夠進行批量導入。
420、在hadoop組中你主要負責那部分?
提示:負責編寫mapreduce程序,各個部分都要參加
42一、怎麼知道hbase表裏哪些作索引?哪些沒作索引?
提示:
有且僅有一個:rowkey,因此hbase的快速查找創建在rowkey的基礎的,而不能像通常的關係型數據庫那樣創建多個索引來達到多條件查找的效果。
42二、hdfs的原理以及各個模塊的職責
42三、mapreduce的工做原理
42四、map方法是如何調用reduce方法的
42五、fsimage和edit的區別?
提示:fsimage:是存儲元數據的鏡像文件,而edit只是保存的操做日誌。
42六、hadoop1和hadoop2的區別?
提示:
(1) hdfs的namenode和mapreduce的jobtracker都是單點。
(2) namenode所在的服務器的內存不夠用時,那麼集羣就不能工做了。
(3)mapreduce集羣的資源利用率比較低。
單NN的架構使得HDFS在集羣擴展性和性能上都有潛在的問題,在集羣規模變大後,NN成爲了性能的瓶頸。Hadoop 2.0裏的HDFS Federation就是爲了解決這兩個問題而開發的。擴大NN容量,共享DN數據,且方便客戶端訪問。
42七、hdfs中的block默認報錯幾份?
提示:3份
42八、哪一個程序一般與nn在一個節點啓動?並作分析
提示:jobtrack,將二者放在一塊兒,減小網絡訪問,IO訪問的時間,提升了效率。
42九、列舉幾個配置文件優化?
430、寫出你對zookeeper的理解
提示:大部分分佈式應用須要一個主控、協調器或控制器來管理物理分佈的子進程(如資源、任務分配等)。目前,大部分應用須要開發私有的協調程序,缺少一個通用的機制協調程序的反覆編寫浪費,且難以造成通用、伸縮性好的協調器。
ZooKeeper:提供通用的分佈式鎖服務,用以協調分佈式應用。
43一、datanode首次加入cluster的時候,若是log報告不兼容文件版本,那須要namenode執行格式化操做,這樣處理的緣由是?
提示:
這樣處理是不合理的,由於那麼namenode格式化操做,是對文件系統進行格式化,namenode格式化時清空dfs/name下空兩個目錄下的全部文件,以後,會在目錄dfs.name.dir下建立文件。
文本不兼容,有可能時namenode 與 datanode 的 數據裏的namespaceID、clusterID不一致,找到兩個ID位置,修改成同樣便可解決。
43二、談談數據傾斜,如何發生的,並給出優化方案。
緣由:
(1)key分佈不均勻
(2)業務數據自己的特性
(3)建表時考慮不周
(4)某些SQL語句自己就有數據傾斜
map處理數據量的差別取決於上一個stage的reduce輸出,因此如何將數據均勻的分配到各個reduce中,就是解決數據傾斜的根本所在。
優化:參數調節;
43三、介紹一下HBase過濾器
43四、mapreduce基本執行過程
43五、談談hadoop1和hadoop2的區別
43六、談談HBase集羣安裝注意事項?
提示:
須要注意的地方是 ZooKeeper的配置。這與 hbase-env.sh 文件相關,文件中HBASE_MANAGES_ZK 環境變量用來設置是使用hbase默認自帶的 Zookeeper仍是使用獨立的ZooKeeper。HBASE_MANAGES_ZK=false時使用獨立的,爲true時使用默認自帶的。