大數(shù)據(jù)Hadoop原理介紹+安裝+實(shí)戰(zhàn)操作(HDFS+YARN+MapReduce)

一伸头、Hadoop概述

Hadoop是Apache軟件基金會(huì)下一個(gè)開(kāi)源分布式計(jì)算平臺(tái)航邢,以HDFS(Hadoop Distributed File System)星立、MapReduce(Hadoop2.0加入了YARN累盗,Yarn是資源調(diào)度框架卒稳,能夠細(xì)粒度的管理和調(diào)度任務(wù)猾愿,還能夠支持其他的計(jì)算框架鹦聪,比如spark)為核心的Hadoop為用戶提供了系統(tǒng)底層細(xì)節(jié)透明的分布式基礎(chǔ)架構(gòu)。hdfs的高容錯(cuò)性蒂秘、高伸縮性泽本、高效性等優(yōu)點(diǎn)讓用戶可以將Hadoop部署在低廉的硬件上,形成分布式系統(tǒng)姻僧。目前最新版本已經(jīng)是3.x了规丽,官方文檔。也可以參考我之前的文章:Hadoop生態(tài)系統(tǒng)介紹


二撇贺、HDFS詳解

1)HDFS概述

HDFS(Hadoop Distributed File System)是Hadoop項(xiàng)目的核心子項(xiàng)目赌莺,是分布式計(jì)算中數(shù)據(jù)存儲(chǔ)管理的基礎(chǔ),是基于流數(shù)據(jù)模式訪問(wèn)和處理超大文件的需求而開(kāi)發(fā)的松嘶,可以運(yùn)行于廉價(jià)的商用服務(wù)器上艘狭。它所具有的\color{red}{ 高容錯(cuò)、高可靠性、高可擴(kuò)展性巢音、高獲得性遵倦、高吞吐率}等特征為海量數(shù)據(jù)提供了不怕故障的存儲(chǔ),為超大數(shù)據(jù)集(Large Data Set)的應(yīng)用處理帶來(lái)了很多便利官撼。HDFS 源于 Google 在2003年10月份發(fā)表的GFS(Google File System) 論文梧躺。 它其實(shí)就是 GFS(Google File System) 的一個(gè)克隆版本。

1.png

HDFS的設(shè)計(jì)特點(diǎn)

之所以選擇 HDFS 存儲(chǔ)數(shù)據(jù)傲绣,因?yàn)?HDFS 具有以下優(yōu)點(diǎn):

  • 高容錯(cuò)性:數(shù)據(jù)自動(dòng)保存多個(gè)副本燥狰。它通過(guò)增加副本的形式,提高容錯(cuò)性斜筐。某一個(gè)副本丟失以后龙致,它可以自動(dòng)恢復(fù),這是由 HDFS 內(nèi)部機(jī)制實(shí)現(xiàn)的顷链,我們不必關(guān)心目代。
  • 適合批處理:它是通過(guò)移動(dòng)計(jì)算而不是移動(dòng)數(shù)據(jù)。它會(huì)把數(shù)據(jù)位置暴露給計(jì)算框架嗤练。
  • 適合大數(shù)據(jù)處理:處理數(shù)據(jù)達(dá)到 GB榛了、TB、甚至PB級(jí)別的數(shù)據(jù)煞抬。能夠處理百萬(wàn)規(guī)模以上的文件數(shù)量霜大,數(shù)量相當(dāng)之大。能夠處理10K節(jié)點(diǎn)的規(guī)模革答。
  • 流式文件訪問(wèn):一次寫(xiě)入战坤,多次讀取。文件一旦寫(xiě)入不能修改残拐,只能追加途茫。它能保證數(shù)據(jù)的一致性。
  • 可構(gòu)建在廉價(jià)機(jī)器上:它通過(guò)多副本機(jī)制溪食,提高可靠性囊卜。它提供了容錯(cuò)和恢復(fù)機(jī)制。比如某一個(gè)副本丟失错沃,可以通過(guò)其它副本來(lái)恢復(fù)栅组。

當(dāng)然 HDFS 也有它的劣勢(shì),并不適合所有的場(chǎng)合:

  • 低延時(shí)數(shù)據(jù)訪問(wèn):它適合高吞吐率的場(chǎng)景枢析,就是在某一時(shí)間內(nèi)寫(xiě)入大量的數(shù)據(jù)玉掸。但是它在低延時(shí)的情況下是不行的,比如毫秒級(jí)以內(nèi)讀取數(shù)據(jù)登疗,這樣它是很難做到的排截。

  • 小文件存儲(chǔ):存儲(chǔ)大量小文件(這里的小文件是指小于HDFS系統(tǒng)的Block大小的文件(Hadoop 3.x默認(rèn)128M)的話,它會(huì)占用 NameNode大量的內(nèi)存來(lái)存儲(chǔ)文件辐益、目錄和塊信息断傲。這樣是不可取的,因?yàn)镹ameNode的內(nèi)存總是有限的智政。小文件存儲(chǔ)的尋道時(shí)間會(huì)超過(guò)讀取時(shí)間认罩,它違反了HDFS的設(shè)計(jì)目標(biāo)。

  • 并發(fā)寫(xiě)入续捂、文件隨機(jī)修改:一個(gè)文件只能有一個(gè)寫(xiě)垦垂,不允許多個(gè)線程同時(shí)寫(xiě)。僅支持?jǐn)?shù)據(jù) append(追加)牙瓢,不支持文件的隨機(jī)修改劫拗。

2)HDFS組成

2.png

HDFS 采用Master/Slave的架構(gòu)來(lái)存儲(chǔ)數(shù)據(jù),這種架構(gòu)主要由四個(gè)部分組成矾克,分別為HDFS Client页慷、NameNode、DataNode和Secondary NameNode胁附。下面我們分別介紹這四個(gè)組成部分 :

1酒繁、Client

Client就是客戶端

  • 文件切分。文件上傳 HDFS 的時(shí)候控妻,Client 將文件切分成 一個(gè)一個(gè)的- Block州袒,然后進(jìn)行存儲(chǔ)。
  • 與 NameNode 交互弓候,獲取文件的位置信息郎哭。
  • 與 DataNode 交互,讀取或者寫(xiě)入數(shù)據(jù)菇存。
  • Client 提供一些命令來(lái)管理 HDFS彰居,比如啟動(dòng)或者關(guān)閉HDFS。
  • Client 可以通過(guò)一些命令來(lái)訪問(wèn) HDFS撰筷。

2陈惰、NameNode(NN)

NameNode就是 master,它是一個(gè)主管毕籽、管理者抬闯。

3、DataNode(DN)

DataNode就是Slave关筒。NameNode 下達(dá)命令溶握,DataNode 執(zhí)行實(shí)際的操作。

  • 存儲(chǔ)實(shí)際的數(shù)據(jù)塊蒸播。
  • 執(zhí)行數(shù)據(jù)塊的讀/寫(xiě)操作睡榆。

4萍肆、Secondary NameNode(2NN)

Secondary NameNode并非 NameNode 的熱備。當(dāng)NameNode 掛掉的時(shí)候胀屿,它并不能馬上替換 NameNode 并提供服務(wù)塘揣。

  • Secondary NameNode僅僅是NameNode的一個(gè)工具,這個(gè)工具幫助NameNode管理元數(shù)據(jù)信息宿崭。
  • 定期合并 fsimage和fsedits亲铡,并推送給NameNode。
  • 在緊急情況下葡兑,可輔助恢復(fù) NameNode奖蔓。

3)HDFS具體工作原理

3.png

1、兩個(gè)核心的數(shù)據(jù)結(jié)構(gòu): Fslmage和EditLog

  • FsImage負(fù)責(zé)維護(hù)文件系統(tǒng)樹(shù)和樹(shù)中所有文件和文件夾的元數(shù)據(jù)讹堤。
    ———維護(hù)文件結(jié)構(gòu)和文件元信息的鏡像
  • EditLog操作日志文件中記錄了所有針對(duì)文件的創(chuàng)建吆鹤,刪除,重命名操作洲守。
    ———記錄對(duì)文件的操作

PS:
1.NN的元數(shù)據(jù)為了讀寫(xiě)速度塊是寫(xiě)在內(nèi)存里的檀头,F(xiàn)sImage只是它的一個(gè)鏡像保存文件
2.當(dāng)每輸入一個(gè)增刪改操作,EditLog都會(huì)單獨(dú)生成一個(gè)文件岖沛,最后EL會(huì)生成多個(gè)文件
3.2NN不是NN的備份(但可以做備份)暑始,它的主要工作是幫助NN合并edits log,減少NN啟動(dòng)時(shí)間婴削。
4.拓?fù)渚嚯x:根據(jù)節(jié)點(diǎn)網(wǎng)絡(luò)構(gòu)成的樹(shù)形結(jié)構(gòu)計(jì)算最短路徑
5.機(jī)架感知:根據(jù)拓?fù)渚嚯x得到的節(jié)點(diǎn)擺放位置

2廊镜、工作流程

  • 第一步: 當(dāng)客戶端對(duì)元數(shù)據(jù)進(jìn)行增刪改請(qǐng)求時(shí),由于hadoop安全性要求比較高唉俗,它會(huì)先將操作寫(xiě)入到editlog文件里嗤朴,先持久化
  • 第二步: 然后將具體增刪改操作虫溜,將FSimage和edit寫(xiě)入內(nèi)存里進(jìn)行具體的操作雹姊,先寫(xiě)文件,即使宕機(jī)了也可以恢復(fù)數(shù)據(jù)衡楞,不然先內(nèi)存數(shù)據(jù)就會(huì)消失吱雏,此時(shí)2NN發(fā)現(xiàn)時(shí)間到了,或者edit數(shù)據(jù)滿了或者剛開(kāi)機(jī)時(shí)瘾境,就會(huì)請(qǐng)求執(zhí)行輔助操作歧杏,NN收到后將edit瞬間復(fù)制一份,這個(gè)時(shí)候客戶端傳過(guò)來(lái)的數(shù)據(jù)繼續(xù)寫(xiě)到edit里迷守。
  • 第三步:我們把復(fù)制的edit和fsimage拷貝到2NN(SecondaryNameNode)里犬绒,操作寫(xiě)在2NN的內(nèi)存里合并,合并后將文件返回給NN做為新的Fsimage兑凿。所以一旦NN宕機(jī)2NN比NN差一個(gè)edit部分凯力,無(wú)法完全恢復(fù)原先狀態(tài)茵瘾,只能說(shuō)輔助恢復(fù)。

3咐鹤、HDFS讀文件流程

4.png

【第一步】Client調(diào)用FileSystem.open()方法

  • FileSystem通過(guò)RPC與NN通信拗秘,NN返回該文件的部分或全部block列表(含有block拷貝的DN地址)。
  • 選取舉栗客戶端最近的DN建立連接慷暂,讀取block,返回FSDataInputStream晨雳。

【第二步】Client調(diào)用輸入流的read()方法

  • 當(dāng)讀到block結(jié)尾時(shí)行瑞,F(xiàn)SDataInputStream關(guān)閉與當(dāng)前DN的連接,并未讀取下一個(gè)block尋找最近DN餐禁。
  • 讀取完一個(gè)block都會(huì)進(jìn)行checksum驗(yàn)證血久,如果讀取DN時(shí)出現(xiàn)錯(cuò)誤,客戶端會(huì)通知NN帮非,然后再?gòu)南乱粋€(gè)擁有該block拷貝的DN繼續(xù)讀氧吐。
  • 如果block列表讀完后,文件還未結(jié)束末盔,F(xiàn)ileSystem會(huì)繼續(xù)從NN獲取下一批block列表筑舅。

【第三步】關(guān)閉FSDataInputStream

4、HDFS文件寫(xiě)入流程

5.png

【第一步】Client調(diào)用FileSystem的create()方法

  • FileSystem向NN發(fā)出請(qǐng)求陨舱,在NN的namespace里面創(chuàng)建一個(gè)新的文件翠拣,但是并不關(guān)聯(lián)任何塊。
  • NN檢查文件是否已經(jīng)存在游盲、操作權(quán)限误墓。如果檢查通過(guò),NN記錄新文件信息益缎,并在某一個(gè)DN上創(chuàng)建數(shù)據(jù)塊谜慌。
  • 返回FSDataOutputStream,將Client引導(dǎo)至該數(shù)據(jù)塊執(zhí)行寫(xiě)入操作莺奔。

【第二步】Client調(diào)用輸出流的write()方法

  • HDFS默認(rèn)將每個(gè)數(shù)據(jù)塊放置3份欣范。FSDataOutputStream將數(shù)據(jù)首先寫(xiě)到第一節(jié)點(diǎn),第一節(jié)點(diǎn)將數(shù)據(jù)包傳送并寫(xiě)入第二節(jié)點(diǎn)令哟,第二節(jié)點(diǎn) --> 第三節(jié)點(diǎn)熙卡。

【第三步】Client調(diào)用流的close()方法

  • flush緩沖區(qū)的數(shù)據(jù)包,block完成復(fù)制份數(shù)后励饵,NN返回成功消息驳癌。

三、Yarn詳解

1)Yarn概述

Apache Yarn(Yet Another Resource Negotiator的縮寫(xiě))是hadoop集群資源管理器系統(tǒng)役听,Yarn從hadoop 2引入颓鲜,最初是為了改善MapReduce的實(shí)現(xiàn)表窘,但是它具有通用性,同樣執(zhí)行其他分布式計(jì)算模式甜滨。

Yarn特點(diǎn):

  • 支持非mapreduce應(yīng)用的需求
  • 可擴(kuò)展性
  • 提高資源是用率
  • 用戶敏捷性
  • 可以通過(guò)搭建為高可用

2)YARN架構(gòu)組件

Yarn從整體上還是屬于master/slave模型乐严,主要依賴(lài)于三個(gè)組件來(lái)實(shí)現(xiàn)功能,第一個(gè)就是ResourceManager衣摩,是集群資源的仲裁者昂验,它包括兩部分:一個(gè)是可插拔式的調(diào)度Scheduler,一個(gè)是ApplicationManager艾扮,用于管理集群中的用戶作業(yè)扛稽。第二個(gè)是每個(gè)節(jié)點(diǎn)上的NodeManager云头,管理該節(jié)點(diǎn)上的用戶作業(yè)和工作流以舒,也會(huì)不斷發(fā)送自己Container使用情況給ResourceManager柑土。第三個(gè)組件是ApplicationMaster,用戶作業(yè)生命周期的管理者它的主要功能就是向ResourceManager(全局的)申請(qǐng)計(jì)算資源(Containers)并且和NodeManager交互來(lái)執(zhí)行和監(jiān)控具體的task酌予。架構(gòu)圖如下:

6.png

1磺箕、ResourceManager(RM)

RM是一個(gè)全局的資源管理器,管理整個(gè)集群的計(jì)算資源抛虫,并將這些資源分配給應(yīng)用程序松靡。包括:

  • 與客戶端交互,處理來(lái)自客戶端的請(qǐng)求
  • 啟動(dòng)和管理ApplicationMaster建椰,并在它運(yùn)行失敗時(shí)重新啟動(dòng)它
  • 管理NodeManager 击困,接收來(lái)自NodeManager 的資源匯報(bào)信息,并向NodeManager下達(dá)管理指令
  • 資源管理與調(diào)度广凸,接收來(lái)自ApplicationMaster 的資源申請(qǐng)請(qǐng)求阅茶,并為之分配資源

RM關(guān)鍵配置參數(shù):

  • 最小容器內(nèi)存: yarn.scheduler.minimum-allocation-mb
  • 容器內(nèi)存增量: yarn.scheduler.increment-allocation-mb
  • 最大容器內(nèi)存: yarn.scheduler.maximum-allocation-mb
  • 最小容器虛擬 CPU 內(nèi)核數(shù)量: yarn.scheduler.minimum-allocation-mb
  • 容器虛擬 CPU 內(nèi)核增量: yarn.scheduler.increment-allocation-vcores
  • 最大容器虛擬 CPU 內(nèi)核數(shù)量: yarn.scheduler.maximum-allocation-mb
  • ResourceManager Web 應(yīng)用程序 HTTP 端口: yarn.resourcemanager.webapp.address

2、ApplicationMaster(AM)

應(yīng)用程序級(jí)別的谅海,管理運(yùn)行在YARN上的應(yīng)用程序脸哀。包括:

  • 用戶提交的每個(gè)應(yīng)用程序均包含一個(gè)AM,它可以運(yùn)行在RM以外的機(jī)器上扭吁。
  • 負(fù)責(zé)與RM調(diào)度器協(xié)商以獲取資源(用Container表示)
  • 將得到的資源進(jìn)一步分配給內(nèi)部的任務(wù)(資源的二次分配)
  • 與NM通信以啟動(dòng)/停止任務(wù)撞蜂。
  • 監(jiān)控所有任務(wù)運(yùn)行狀態(tài),并在任務(wù)運(yùn)行失敗時(shí)重新為任務(wù)申請(qǐng)資源以重啟任務(wù)

AM關(guān)鍵配置參數(shù):

  • ApplicationMaster 最大嘗試次數(shù): yarn.resourcemanager.am.max-attempts
  • ApplicationMaster 監(jiān)控過(guò)期: yarn.am.liveness-monitor.expiry-interval-ms

3侥袜、NodeManager(NM)

YARN中每個(gè)節(jié)點(diǎn)上的代理蝌诡,它管理Hadoop集群中單個(gè)計(jì)算節(jié)點(diǎn)。包括:

  • 啟動(dòng)和監(jiān)視節(jié)點(diǎn)上的計(jì)算容器(Container)
  • 以心跳的形式向RM匯報(bào)本節(jié)點(diǎn)上的資源使用情況和各個(gè)Container的運(yùn)行狀態(tài)(CPU和內(nèi)存等資源)
  • 接收并處理來(lái)自AM的Container啟動(dòng)/停止等各種請(qǐng)求

NM關(guān)鍵配置參數(shù):

  • 節(jié)點(diǎn)內(nèi)存: yarn.nodemanager.resource.memory-mb
  • 節(jié)點(diǎn)虛擬 CPU 內(nèi)核: yarn.nodemanager.resource.cpu-vcores
  • NodeManager Web 應(yīng)用程序 HTTP 端口: yarn.nodemanager.webapp.address

4枫吧、Container

Container是YARN中資源的抽象浦旱,它封裝了某個(gè)節(jié)點(diǎn)上的多維度資源,如內(nèi)存九杂、CPU颁湖、磁盤(pán)宣蠕、網(wǎng)絡(luò)等。Container由AM向RM申請(qǐng)的甥捺,由RM中的資源調(diào)度器異步分配給AM抢蚀。Container的運(yùn)行是由AM向資源所在的NM發(fā)起。

一個(gè)應(yīng)用程序所需的Container分為兩大類(lèi):

  • 運(yùn)行AM的Container:這是由RM(向內(nèi)部的資源調(diào)度器)申請(qǐng)和啟動(dòng)的镰禾,用戶提交應(yīng)用程序時(shí)皿曲,可指定唯一的AM所需的資源;
  • 運(yùn)行各類(lèi)任務(wù)的Container:這是由AM向RM申請(qǐng)的吴侦,并由AM與NM通信以啟動(dòng)之屋休。

以上兩類(lèi)Container可能在任意節(jié)點(diǎn)上,它們的位置通常而言是隨機(jī)的妈倔,即AM可能與它管理的任務(wù)運(yùn)行在一個(gè)節(jié)點(diǎn)上博投。

3)YARN運(yùn)行流程

Application在Yarn中的執(zhí)行過(guò)程如下圖所示:


7.png
  1. 客戶端程序向ResourceManager提交應(yīng)用并請(qǐng)求一個(gè)ApplicationMaster實(shí)例绸贡,ResourceManager在應(yīng)答中給出一個(gè)applicationID以及有助于客戶端請(qǐng)求資源的資源容量信息盯蝴。

  2. ResourceManager找到可以運(yùn)行一個(gè)Container的NodeManager,并在這個(gè)Container中啟動(dòng)ApplicationMaster實(shí)例

    • Application Submission Context發(fā)出響應(yīng)听怕,其中包含有:ApplicationID捧挺,用戶名,隊(duì)列以及其他啟動(dòng)ApplicationMaster的信息尿瞭,Container Launch Context(CLC)也會(huì)發(fā)給ResourceManager闽烙,CLC提供了資源的需求,作業(yè)文件声搁,安全令牌以及在節(jié)點(diǎn)啟動(dòng)ApplicationMaster所需要的其他信息黑竞。
    • 當(dāng)ResourceManager接收到客戶端提交的上下文,就會(huì)給ApplicationMaster調(diào)度一個(gè)可用的container(通常稱(chēng)為container0)疏旨。然后ResourceManager就會(huì)聯(lián)系NodeManager啟動(dòng)ApplicationMaster很魂,并建立ApplicationMaster的RPC端口和用于跟蹤的URL,用來(lái)監(jiān)控應(yīng)用程序的狀態(tài)檐涝。
  3. ApplicationMaster向ResourceManager進(jìn)行注冊(cè)遏匆,注冊(cè)之后客戶端就可以查詢ResourceManager獲得自己ApplicationMaster的詳細(xì)信息,以后就可以和自己的ApplicationMaster直接交互了谁榜。在注冊(cè)響應(yīng)中幅聘,ResourceManager會(huì)發(fā)送關(guān)于集群最大和最小容量信息,

  4. 在平常的操作過(guò)程中窃植,ApplicationMaster根據(jù)resource-request協(xié)議向ResourceManager發(fā)送resource-request請(qǐng)求帝蒿,ResourceManager會(huì)根據(jù)調(diào)度策略盡可能最優(yōu)的為ApplicationMaster分配container資源,作為資源請(qǐng)求的應(yīng)答發(fā)個(gè)ApplicationMaster

  5. 當(dāng)Container被成功分配之后巷怜,ApplicationMaster通過(guò)向NodeManager發(fā)送container-launch-specification信息來(lái)啟動(dòng)Container陵叽, container-launch-specification信息包含了能夠讓Container和ApplicationMaster交流所需要的資料狞尔,一旦container啟動(dòng)成功之后,ApplicationMaster就可以檢查他們的狀態(tài)巩掺,Resourcemanager不在參與程序的執(zhí)行偏序,只處理調(diào)度和監(jiān)控其他資源,Resourcemanager可以命令NodeManager殺死container胖替,

  6. 應(yīng)用程序的代碼在啟動(dòng)的Container中運(yùn)行研儒,并把運(yùn)行的進(jìn)度、狀態(tài)等信息通過(guò)application-specific協(xié)議發(fā)送給ApplicationMaster独令,隨著作業(yè)的執(zhí)行端朵,ApplicationMaster將心跳和進(jìn)度信息發(fā)給ResourceManager,在這些心跳信息中燃箭,ApplicationMaster還可以請(qǐng)求和釋放一些container冲呢。

  7. 在應(yīng)用程序運(yùn)行期間,提交應(yīng)用的客戶端主動(dòng)和ApplicationMaster交流獲得應(yīng)用的運(yùn)行狀態(tài)招狸、進(jìn)度更新等信息敬拓,交流的協(xié)議也是application-specific協(xié)議

  8. 一但應(yīng)用程序執(zhí)行完成并且所有相關(guān)工作也已經(jīng)完成,ApplicationMaster向ResourceManager取消注冊(cè)然后關(guān)閉裙戏,用到所有的Container也歸還給系統(tǒng)乘凸,當(dāng)container被殺死或者回收,Resourcemanager都會(huì)通知NodeManager聚合日志并清理container專(zhuān)用的文件累榜。

4)YARN三種資源調(diào)度器

1营勤、FIFO調(diào)度器(FIFO Scheduler)

FIFO調(diào)度器的優(yōu)點(diǎn)是簡(jiǎn)單易懂不需要任何配置,但是不適合共享集群壹罚。大型應(yīng)用會(huì)占用集群中的所有資源葛作,所以每個(gè)應(yīng)用必須等待直到輪到自己運(yùn)行。在一個(gè)共享集群中猖凛,更適合使用容量調(diào)度器或公平調(diào)度器赂蠢。這兩種調(diào)度器都允許長(zhǎng)時(shí)間運(yùn)行的作業(yè)能及時(shí)完成,同時(shí)也允許正在進(jìn)行較小臨時(shí)查詢的用戶能夠在合理時(shí)間內(nèi)得到返回結(jié)果形病。

8.png

2客年、容量調(diào)度器(Capacity Scheduler)

容量調(diào)度器允許多個(gè)組織共享一個(gè)Hadoop集群,每個(gè)組織可以分配到全部集群資源的一部分漠吻。每個(gè)組織被配置一個(gè)專(zhuān)門(mén)的隊(duì)列量瓜,每個(gè)隊(duì)列被配置為可以使用一定的集群資源。隊(duì)列可以進(jìn)一步按層次劃分途乃,這樣每個(gè)組織內(nèi)的不同用戶能夠共享該組織隊(duì)列所分配的資源绍傲。在一個(gè)隊(duì)列內(nèi),使用FIFO調(diào)度策略對(duì)應(yīng)用進(jìn)行調(diào)度。

  • 單個(gè)作業(yè)使用的資源不會(huì)超過(guò)其隊(duì)列容量烫饼。然而如果隊(duì)列中有多個(gè)作業(yè)猎塞,并且隊(duì)列資源不夠了呢?這時(shí)如果仍有可用的空閑資源那么容量調(diào)度器可能會(huì)將空余的資源分配給隊(duì)列中的作業(yè)杠纵,哪怕這會(huì)超出隊(duì)列容量荠耽。這被稱(chēng)為彈性隊(duì)列(queue elasticity)。
9.png

3比藻、資源調(diào)度器- Fair

公平調(diào)度是一種對(duì)于全局資源铝量,對(duì)于所有應(yīng)用作業(yè)來(lái)說(shuō),都均勻分配的資源分配方法银亲。默認(rèn)情況慢叨,公平調(diào)度器FairScheduler基于內(nèi)存來(lái)安排公平調(diào)度策略。也可以配置為同時(shí)基于內(nèi)存和CPU來(lái)進(jìn)行調(diào)度(Dominant Resource Fairness)务蝠。在一個(gè)隊(duì)列內(nèi)拍谐,可以使用FIFO、FAIR馏段、DRF調(diào)度策略對(duì)應(yīng)用進(jìn)行調(diào)度轩拨。FairScheduler允許保障性的分配最小資源到隊(duì)列。

  • 【注意】在下圖 Fair 調(diào)度器中毅弧,從第二個(gè)任務(wù)提交到獲得資源會(huì)有一定的延遲气嫁,因?yàn)樗枰却谝粋€(gè)任務(wù)釋放占用的 Container当窗。小任務(wù)執(zhí)行完成之后也會(huì)釋放自己占用的資源够坐,大任務(wù)又獲得了全部的系統(tǒng)資源。最終效果就是 Fair 調(diào)度器即得到了高的資源利用率又能保證小任務(wù)及時(shí)完成崖面。
10.png

四元咙、MapReduce詳解

1)MapReduce概述

MapReduce是一種編程模型(沒(méi)有集群的概念,會(huì)把任務(wù)提交到y(tǒng)arn集群上跑)巫员,用于大規(guī)模數(shù)據(jù)集(大于1TB)的并行運(yùn)算庶香。概念"Map(映射)"和"Reduce(歸約)",是它們的主要思想简识,都是從函數(shù)式編程語(yǔ)言里借來(lái)的赶掖,還有從矢量編程語(yǔ)言里借來(lái)的特性。它極大地方便了編程人員在不會(huì)分布式并行編程的情況下七扰,將自己的程序運(yùn)行在分布式系統(tǒng)上奢赂。 當(dāng)前的軟件實(shí)現(xiàn)是指定一個(gè)Map(映射)函數(shù),用來(lái)把一組鍵值對(duì)映射成一組新的鍵值對(duì)颈走,指定并發(fā)的Reduce(歸約)函數(shù)膳灶,用來(lái)保證所有映射的鍵值對(duì)中的每一個(gè)共享相同的鍵組。(MapReduce在企業(yè)里幾乎不再使用了,稍微了解即可)

2)MapReduce運(yùn)行流程

作業(yè)的運(yùn)行過(guò)程主要包括如下幾個(gè)步驟:

1轧钓、作業(yè)的提交
2序厉、作業(yè)的初始化
3、作業(yè)任務(wù)的分配
4毕箍、作業(yè)任務(wù)的執(zhí)行
5弛房、作業(yè)執(zhí)行狀態(tài)更新
6、作業(yè)完成

具體作業(yè)執(zhí)行過(guò)程的流程圖如下圖所示:


11.png

1而柑、作業(yè)的提交

在MR的代碼中調(diào)用waitForCompletion()方法庭再,里面封裝了Job.submit()方法,而Job.submit()方法里面會(huì)創(chuàng)建一個(gè)JobSubmmiter對(duì)象牺堰。當(dāng)我們?cè)趙aitForCompletion(true)時(shí)拄轻,則waitForCompletion方法會(huì)每秒輪詢作業(yè)的執(zhí)行進(jìn)度,如果發(fā)現(xiàn)與上次查詢到的狀態(tài)有差別伟葫,則將詳情打印到控制臺(tái)恨搓。如果作業(yè)執(zhí)行成功,就顯示作業(yè)計(jì)數(shù)器筏养,否則將導(dǎo)致作業(yè)失敗的記錄輸出到控制臺(tái)斧抱。

其中JobSubmmiter實(shí)現(xiàn)的大概過(guò)程如下:

  1. 向資源管理器resourcemanager提交申請(qǐng),用于一個(gè)mapreduce作業(yè)ID渐溶,如圖步驟2所示
  2. 檢查作業(yè)的輸出配置辉浦,判斷目錄是否已經(jīng)存在等信息
  3. 計(jì)算作業(yè)的輸入分片的大小
  4. 將運(yùn)行作業(yè)的jar,配置文件茎辐,輸入分片的計(jì)算資源復(fù)制到一個(gè)以作業(yè)ID命名的hdfs臨時(shí)目錄下宪郊,作業(yè)jar的復(fù)本比較多,默認(rèn)為10個(gè)(通過(guò)參數(shù)mapreduce.client.submit.file.replication控制)拖陆,
  5. 通過(guò)資源管理器的submitApplication方法提交作業(yè)

2弛槐、作業(yè)的初始化

  1. 當(dāng)資源管理器通過(guò)方法submitApplication方法被調(diào)用后,便將請(qǐng)求傳給了yarn的調(diào)度器依啰,然后調(diào)度器在一個(gè)節(jié)點(diǎn)管理器上分配一個(gè)容器(container0)用來(lái)啟動(dòng)application master(主類(lèi)是MRAppMaster)進(jìn)程乎串。該進(jìn)程一旦啟動(dòng)就會(huì)向resourcemanager注冊(cè)并報(bào)告自己的信息,application master并且可以監(jiān)控map和reduce的運(yùn)行狀態(tài)速警。因此application master對(duì)作業(yè)的初始化是通過(guò)創(chuàng)建多個(gè)薄記對(duì)象以保持對(duì)作業(yè)進(jìn)度的跟蹤叹誉。

  2. application master接收作業(yè)提交時(shí)的hdfs臨時(shí)共享目錄中的資源文件,jar闷旧,分片信息长豁,配置信息等。并對(duì)每一個(gè)分片創(chuàng)建一個(gè)map對(duì)象鸠匀,以及通過(guò)mapreduce.job.reduces參數(shù)(作業(yè)通過(guò)setNumReduceTasks()方法設(shè)定)確定reduce的數(shù)量蕉斜。

  3. application master會(huì)判斷是否使用uber(作業(yè)與application master在同一個(gè)jvm運(yùn)行,也就是maptask和reducetask運(yùn)行在同一個(gè)節(jié)點(diǎn)上)模式運(yùn)行作業(yè),uber模式運(yùn)行條件:map數(shù)量小于10個(gè)宅此,1個(gè)reduce机错,且輸入數(shù)據(jù)小于一個(gè)hdfs塊

可以通過(guò)參數(shù):

mapreduce.job.ubertask.enable   #是否啟用uber模式
mapreduce.job.ubertask.maxmaps   #ubertask的最大map數(shù)
mapreduce.job.ubertask.maxreduces #ubertask的最大reduce數(shù)
mapreduce.job.ubertask.maxbytes #ubertask最大作業(yè)大小
  1. application master調(diào)用setupJob方法設(shè)置OutputCommiter,FileOutputCommiter為默認(rèn)值父腕,表示建立做的最終輸出目錄和任務(wù)輸出的臨時(shí)工作空間

3弱匪、作業(yè)任務(wù)的分配

  1. 在application master判斷作業(yè)不符合uber模式的情況下,那么application master則會(huì)向資源管理器為map和reduce任務(wù)申請(qǐng)資源容器璧亮。

  2. 首先就是為map任務(wù)發(fā)出資源申請(qǐng)請(qǐng)求萧诫,直到有5%的map任務(wù)完成時(shí),才會(huì)為reduce任務(wù)所需資源申請(qǐng)發(fā)出請(qǐng)求枝嘶。

  3. 在任務(wù)的分配過(guò)程中帘饶,reduce任務(wù)可以在任何的datanode節(jié)點(diǎn)運(yùn)行,但是map任務(wù)執(zhí)行的時(shí)候需要考慮到數(shù)據(jù)本地化的機(jī)制群扶,在給任務(wù)指定資源的時(shí)候每個(gè)map和reduce默認(rèn)為1G內(nèi)存及刻,可以通過(guò)如下參數(shù)配置:

mapreduce.map.memory.mb
mapreduce.map.cpu.vcores
mapreduce.reduce.memory.mb
mapreduce.reduce.cpu.vcores

4、作業(yè)任務(wù)的執(zhí)行

application master提交申請(qǐng)后竞阐,資源管理器為其按需分配資源缴饭,這時(shí),application master就與節(jié)點(diǎn)管理器通信來(lái)啟動(dòng)容器颗搂。該任務(wù)由主類(lèi)YarnChild的一個(gè)java應(yīng)用程序執(zhí)行。在運(yùn)行任務(wù)之前纺且,首先將所需的資源進(jìn)行本地化,包括作業(yè)的配置朗伶,jar文件等点晴。接下來(lái)就是運(yùn)行map和reduce任務(wù)。YarnChild在單獨(dú)的JVM中運(yùn)行。

5、作業(yè)任務(wù)的狀態(tài)更新

每個(gè)作業(yè)和它的每個(gè)任務(wù)都有一個(gè)狀態(tài):作業(yè)或者任務(wù)的狀態(tài)(運(yùn)行中,成功掏膏,失敗等)颖变,map和reduce的進(jìn)度衔峰,作業(yè)計(jì)數(shù)器的值出牧,狀態(tài)消息或描述當(dāng)作業(yè)處于正在運(yùn)行中的時(shí)候豹缀,客戶端可以直接與application master通信鱼响,每秒(可以通過(guò)參數(shù)mapreduce.client.progressmonitor.pollinterval設(shè)置)輪詢作業(yè)的執(zhí)行狀態(tài),進(jìn)度等信息唬滑。

6、作業(yè)的完成

  • 當(dāng)application master收到最后一個(gè)任務(wù)已完成的通知,便把作業(yè)的狀態(tài)設(shè)置為成功。
  • 在job輪詢作業(yè)狀態(tài)時(shí),知道任務(wù)已經(jīng)完成咏连,然后打印消息告知用戶垄懂,并從waitForCompletion()方法返回漫谷。
  • 當(dāng)作業(yè)完成時(shí),application master和container會(huì)清理中間數(shù)據(jù)結(jié)果等臨時(shí)問(wèn)題。OutputCommiter的commitJob()方法被調(diào)用蜘渣,作業(yè)信息由作業(yè)歷史服務(wù)存檔,以便用戶日后查詢捂龄。

3)MapReduce中的shuffle過(guò)程

mapreduce確保每個(gè)reduce的輸入都是按照鍵值排序的释涛,系統(tǒng)執(zhí)行排序,將map的輸入作為reduce的輸入過(guò)程稱(chēng)之為shuffle過(guò)程倦沧。shuffle也是我們優(yōu)化的重點(diǎn)部分唇撬。shuffle流程圖如下圖所示:

12.png

1喝噪、map端

  • 在生成map之前悍及,會(huì)計(jì)算文件分片的大小

  • 然后會(huì)根據(jù)分片的大小計(jì)算map的個(gè)數(shù)曙搬,對(duì)每一個(gè)分片都會(huì)產(chǎn)生一個(gè)map作業(yè)筷狼,或者是一個(gè)文件(小于分片大小*1.1)生成一個(gè)map作業(yè)巧骚,然后通過(guò)自定的map方法進(jìn)行自定義的邏輯計(jì)算,計(jì)算完畢后會(huì)寫(xiě)到本地磁盤(pán)。

    1. 在這里不是直接寫(xiě)入磁盤(pán)贱呐,為了保證IO效率金矛,采用了先寫(xiě)入內(nèi)存的環(huán)形緩沖區(qū)饼酿,并做一次預(yù)排序(快速排序)。緩沖區(qū)的大小默認(rèn)為100MB(可通過(guò)修改配置項(xiàng)mpareduce.task.io.sort.mb進(jìn)行修改),當(dāng)寫(xiě)入內(nèi)存緩沖區(qū)的大小到達(dá)一定比例時(shí)叁巨,\color{red}{默認(rèn)為80%(可通過(guò)mapreduce.map.sort.spill.percent配置項(xiàng)修改)},將啟動(dòng)一個(gè)溢寫(xiě)線程將內(nèi)存緩沖區(qū)的內(nèi)容溢寫(xiě)到磁盤(pán)(spill to disk)斑匪,這個(gè)溢寫(xiě)線程是獨(dú)立的,不影響map向緩沖區(qū)寫(xiě)結(jié)果的線程俘种,在溢寫(xiě)到磁盤(pán)的過(guò)程中秤标,map繼續(xù)輸入到緩沖中绝淡,如果期間緩沖區(qū)被填滿宙刘,則map寫(xiě)會(huì)被阻塞到溢寫(xiě)磁盤(pán)過(guò)程完成。溢寫(xiě)是通過(guò)輪詢的方式將緩沖區(qū)中的內(nèi)存寫(xiě)入到本地mapreduce.cluster.local.dir目錄下牢酵。在溢寫(xiě)到磁盤(pán)之前悬包,我們會(huì)知道reduce的數(shù)量,然后會(huì)根據(jù)reduce的數(shù)量劃分分區(qū)馍乙,默認(rèn)根據(jù)hashpartition對(duì)溢寫(xiě)的數(shù)據(jù)寫(xiě)入到相對(duì)應(yīng)的分區(qū)布近。在每個(gè)分區(qū)中,后臺(tái)線程會(huì)根據(jù)key進(jìn)行排序丝格,所以溢寫(xiě)到磁盤(pán)的文件是分區(qū)且排序的撑瞧。如果有combiner函數(shù),它在排序后的輸出運(yùn)行显蝌,使得map輸出更緊湊预伺。減少寫(xiě)到磁盤(pán)的數(shù)據(jù)和傳輸給reduce的數(shù)據(jù)。

    2. 每次環(huán)形換沖區(qū)的內(nèi)存達(dá)到閾值時(shí)曼尊,就會(huì)溢寫(xiě)到一個(gè)新的文件酬诀,因此當(dāng)一個(gè)map溢寫(xiě)完之后,本地會(huì)存在多個(gè)分區(qū)切排序的文件骆撇。在map完成之前會(huì)把這些文件合并成一個(gè)分區(qū)且排序(歸并排序)的文件瞒御,可以通過(guò)參數(shù)mapreduce.task.io.sort.factor控制每次可以合并多少個(gè)文件。

    3. 在map溢寫(xiě)磁盤(pán)的過(guò)程中神郊,對(duì)數(shù)據(jù)進(jìn)行壓縮可以提交速度的傳輸肴裙,減少磁盤(pán)io,減少存儲(chǔ)涌乳。默認(rèn)情況下不壓縮蜻懦,使用參數(shù)mapreduce.map.output.compress控制,壓縮算法使用mapreduce.map.output.compress.codec參數(shù)控制爷怀。

2阻肩、reduce端

  • map任務(wù)完成后,監(jiān)控作業(yè)狀態(tài)的application master便知道m(xù)ap的執(zhí)行情況,并啟動(dòng)reduce任務(wù)烤惊,application master并且知道m(xù)ap輸出和主機(jī)之間的對(duì)應(yīng)映射關(guān)系乔煞,reduce輪詢application master便知道主機(jī)所要復(fù)制的數(shù)據(jù)。
  • 一個(gè)Map任務(wù)的輸出柒室,可能被多個(gè)Reduce任務(wù)抓取渡贾。每個(gè)Reduce任務(wù)可能需要多個(gè)Map任務(wù)的輸出作為其特殊的輸入文件,而每個(gè)Map任務(wù)的完成時(shí)間可能不同雄右,當(dāng)有一個(gè)Map任務(wù)完成時(shí)空骚,Reduce任務(wù)就開(kāi)始運(yùn)行。Reduce任務(wù)根據(jù)分區(qū)號(hào)在多個(gè)Map輸出中抓壤奕浴(fetch)對(duì)應(yīng)分區(qū)的數(shù)據(jù)囤屹,這個(gè)過(guò)程也就是Shuffle的copy過(guò)程。逢渔。reduce有少量的復(fù)制線程肋坚,因此能夠并行的復(fù)制map的輸出,默認(rèn)為5個(gè)線程肃廓≈茄幔可以通過(guò)參數(shù)mapreduce.reduce.shuffle.parallelcopies控制。
  • 這個(gè)復(fù)制過(guò)程和map寫(xiě)入磁盤(pán)過(guò)程類(lèi)似盲赊,也有閥值和內(nèi)存大小铣鹏,閥值一樣可以在配置文件里配置,而內(nèi)存大小是直接使用reduce的tasktracker的內(nèi)存大小哀蘑,復(fù)制時(shí)候reduce還會(huì)進(jìn)行排序操作和合并文件操作诚卸。
  • 如果map輸出很小,則會(huì)被復(fù)制到Reducer所在節(jié)點(diǎn)的內(nèi)存緩沖區(qū),緩沖區(qū)的大小可以通過(guò)mapred-site.xml文件中的mapreduce.reduce.shuffle.input.buffer.percent指定。一旦Reducer所在節(jié)點(diǎn)的內(nèi)存緩沖區(qū)達(dá)到閥值牌借,或者緩沖區(qū)中的文件數(shù)達(dá)到閥值缭付,則合并溢寫(xiě)到磁盤(pán)。
  • 如果map輸出較大,則直接被復(fù)制到Reducer所在節(jié)點(diǎn)的磁盤(pán)中。隨著Reducer所在節(jié)點(diǎn)的磁盤(pán)中溢寫(xiě)文件增多,后臺(tái)線程會(huì)將它們合并為更大且有序的文件恭朗。當(dāng)完成復(fù)制map輸出,進(jìn)入sort階段依疼。這個(gè)階段通過(guò)歸并排序逐步將多個(gè)map輸出小文件合并成大文件痰腮。最后幾個(gè)通過(guò)歸并合并成的大文件作為reduce的輸出

五、安裝Hadoop(HDFS+YARN)

1)環(huán)境準(zhǔn)備

這里準(zhǔn)備三臺(tái)VM虛擬機(jī)

OS hostname ip 運(yùn)行角色
Centos8.x hadoop-node1 192.168.0.113 namenode律罢,datanode 膀值,resourcemanager棍丐,nodemanager
Centos8.x hadoop-node2 192.168.0.114 secondarynamedata,datanode沧踏,nodemanager
Centos8.x hadoop-node3 192.168.0.115 datanode歌逢,nodemanager

2)下載最新的Hadoop安裝包

下載地址:https://dlcdn.apache.org/hadoop/common/

13.png

14.png

這里下載源碼包安裝,默認(rèn)的編譯好的文件不支持snappy壓縮翘狱,因此我們需要自己重新編譯秘案。

$ mkdir -p /opt/bigdata/hadoop && cd /opt/bigdata/hadoop
$ wget https://dlcdn.apache.org/hadoop/common/stable/hadoop-3.3.1-src.tar.gz
# 解壓
$ tar -zvxf hadoop-3.3.1-src.tar.gz

為什么需要重新編譯Hadoop源碼?

匹配不同操作系統(tǒng)本地庫(kù)環(huán)境潦匈,Hadoop某些操作比如壓縮阱高,IO需要調(diào)用系統(tǒng)本地庫(kù)(.so|.dll)

重構(gòu)源碼

源碼包目錄下有個(gè)\color{red}{ BUILDING.txt},因?yàn)槲疫@里的操作系統(tǒng)是Centos8茬缩,所以選擇Centos8的操作步驟赤惊,小伙伴們找到自己對(duì)應(yīng)系統(tǒng)的操作步驟執(zhí)行即可。

$ grep -n -A40 'Building on CentOS 8' BUILDING.txt
15.png
Building on CentOS 8

----------------------------------------------------------------------------------


* Install development tools such as GCC, autotools, OpenJDK and Maven.
  $ sudo dnf group install --with-optional 'Development Tools'
  $ sudo dnf install java-1.8.0-openjdk-devel maven

* Install Protocol Buffers v3.7.1.
  $ git clone https://github.com/protocolbuffers/protobuf
  $ cd protobuf
  $ git checkout v3.7.1
  $ autoreconf -i
  $ ./configure --prefix=/usr/local
  $ make
  $ sudo make install
  $ cd ..

* Install libraries provided by CentOS 8.
  $ sudo dnf install libtirpc-devel zlib-devel lz4-devel bzip2-devel openssl-devel cyrus-sasl-devel libpmem-devel

* Install optional dependencies (snappy-devel).
  $ sudo dnf --enablerepo=PowerTools snappy-devel

* Install optional dependencies (libzstd-devel).
  $ sudo dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
  $ sudo dnf --enablerepo=epel install libzstd-devel

* Install optional dependencies (isa-l).
  $ sudo dnf --enablerepo=PowerTools install nasm
  $ git clone https://github.com/intel/isa-l
  $ cd isa-l/
  $ ./autogen.sh
  $ ./configure
  $ make
  $ sudo make install

----------------------------------------------------------------------------------

將進(jìn)入Hadoop源碼路徑寒屯,執(zhí)行maven命令進(jìn)行Hadoop編譯

$ cd /opt/bigdata/hadoop/hadoop-3.3.1-src
# 編譯
$ mvn package -Pdist,native,docs -DskipTests -Dtar

\color{red}{【問(wèn)題】Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M1:enforce}

[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 19:49 min
[INFO] Finished at: 2021-12-14T09:36:29+08:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M1:enforce (enforce-banned-dependencies) on project hadoop-client-check-test-invariants: Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed. -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR] mvn <goals> -rf :hadoop-client-check-test-invariants

【解決】

  • 方案一:跳過(guò)enforcer的強(qiáng)制約束荐捻,在構(gòu)建的命令加上跳過(guò)的指令,如:-Denforcer.skip=true
  • 方案二:設(shè)置規(guī)則校驗(yàn)失敗不影響構(gòu)建流程寡夹,在構(gòu)建的命令上加指令,如: -Denforcer.fail=false

具體原因目前還不明確厂置,先使用上面兩個(gè)方案中的方案一跳過(guò)菩掏,有興趣的小伙伴,可以打開(kāi)DEBUG模式(-X)查看具體報(bào)錯(cuò)

$ mvn package -Pdist,native,docs,src -DskipTests -Dtar -Denforcer.skip=true

所以編譯命令

# 當(dāng)然還有其它選項(xiàng)
$ grep -n -A1 '$ mvn package' BUILDING.txt
16.png
$ mvn package -Pdist -DskipTests -Dtar -Dmaven.javadoc.skip=true
$ mvn package -Pdist,native,docs -DskipTests -Dtar
$ mvn package -Psrc -DskipTests
$ mvn package -Pdist,native,docs,src -DskipTests -Dtar
$ mvn package -Pdist,native -DskipTests -Dmaven.javadoc.skip \
  -Dopenssl.prefix=/usr/local/opt/openssl
17.png

至此~Hadoop源碼編譯完成昵济,
編譯后的文件位于源碼路徑下 hadoop-dist/target/


18.png

將編譯好的二進(jìn)制包c(diǎn)opy出來(lái)

$ cp hadoop-dist/target/hadoop-3.3.1.tar.gz /opt/bigdata/hadoop/
$ cd /opt/bigdata/hadoop/
$ ll
19.png

這里也把編譯好的包放在百度云上智绸,如果小伙伴不想自己編譯,可以直接用我這里的:

鏈接:https://pan.baidu.com/s/1hmdHY20zSLGyKw1OAVCg7Q
提取碼:8888

3)進(jìn)行服務(wù)器及Hadoop的初始化配置

1访忿、修改主機(jī)名

# 192.168.0.113機(jī)器上執(zhí)行
$ hostnamectl set-hostname hadoop-node1
# 192.168.0.114機(jī)器上執(zhí)行
$ hostnamectl set-hostname hadoop-node2
# 192.168.0.115機(jī)器上執(zhí)行
$ hostnamectl set-hostname hadoop-node3

2瞧栗、修改主機(jī)名和IP的映射關(guān)系(所有節(jié)點(diǎn)都執(zhí)行)

$ echo "192.168.0.113 hadoop-node1" >> /etc/hosts
$ echo "192.168.0.114 hadoop-node2" >> /etc/hosts
$ echo "192.168.0.115 hadoop-node3" >> /etc/hosts

3、關(guān)閉防火墻和selinux(所有節(jié)點(diǎn)都執(zhí)行)

$ systemctl stop firewalld
$ systemctl disable firewalld

# 臨時(shí)關(guān)閉(不用重啟機(jī)器):
$ setenforce 0                  ##設(shè)置SELinux 成為permissive模式

# 永久關(guān)閉修改/etc/selinux/config 文件
將SELINUX=enforcing改為SELINUX=disabled

4海铆、時(shí)間同步(所有節(jié)點(diǎn)都執(zhí)行)

$ dnf install chrony -y
$ systemctl start chronyd
$ systemctl enable chronyd

/etc/chrony.conf配置文件內(nèi)容

# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
#pool 2.centos.pool.ntp.org iburst (這一行注釋掉迹恐,增加以下兩行)
server ntp.aliyun.com iburst
server cn.ntp.org.cn iburst

重新加載配置并測(cè)試

$ systemctl restart chronyd.service
$ chronyc sources -v

5、配置ssh免密(在hadoop-node1上執(zhí)行)

# 1卧斟、在hadoop-node1上執(zhí)行如下命令生成公私密鑰:
$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_dsa
# 2殴边、然后將master公鑰id_dsa復(fù)制到hadoop-node1|hadoop-node2|hadoop-node3進(jìn)行公鑰認(rèn)證。
$ ssh-copy-id -i /root/.ssh/id_dsa.pub hadoop-node1
$ ssh-copy-id -i /root/.ssh/id_dsa.pub hadoop-node2
$ ssh-copy-id -i /root/.ssh/id_dsa.pub hadoop-node3
$ ssh hadoop-node1
$ exit
$ ssh hadoop-node2
$ exit
$ ssh hadoop-node3
$ exit
20.png

6珍语、安裝統(tǒng)一工作目錄(所有節(jié)點(diǎn)都執(zhí)行)

# 軟件安裝路徑
$ mkdir -p /opt/bigdata/hadoop/server
# 數(shù)據(jù)存儲(chǔ)路徑
$ mkdir -p /opt/bigdata/hadoop/data
# 安裝包存放路徑
$ mkdir -p /opt/bigdata/hadoop/software

7锤岸、安裝JDK(所有節(jié)點(diǎn)都執(zhí)行)
官網(wǎng)下載:https://www.oracle.com/java/technologies/downloads/
百度下載

鏈接:https://pan.baidu.com/s/1-rgW-Z-syv24vU15bmMg1w
提取碼:8888

$ cd /opt/bigdata/hadoop/software
$ tar -zxvf jdk-8u212-linux-x64.tar.gz -C /opt/bigdata/hadoop/server/
# 在文件加入環(huán)境變量/etc/profile
export JAVA_HOME=/opt/bigdata/hadoop/server/jdk1.8.0_212
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
# source加載
$ source /etc/profile
# 查看jdk版本
$ java -version
21.png

4)開(kāi)始安裝Hadoop

1、解壓上面我編譯好的安裝包

$ cd /opt/bigdata/hadoop/software
$ tar -zxvf hadoop-3.3.1.tar.gz -C /opt/bigdata/hadoop/server/
$ cd /opt/bigdata/hadoop/server/
$ cd hadoop-3.3.1/
$ ls -lh
22.png

2板乙、安裝包目錄說(shuō)明

目錄 說(shuō)明
bin hadoop最基本的\color{red}{管理腳本}和使用腳本的目錄是偷,這些腳本是sbin目錄下管理腳本的基礎(chǔ)實(shí)現(xiàn),用戶可以直接使用這些腳本管理和使用hadoop
etc hadoop\color{red}{配置文件}所在的目錄
include 對(duì)外提供的編程庫(kù)頭文件(具體動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù)在lib目錄中),這些文件均是用c++定義蛋铆,通常用于c++程序訪問(wèn)HDFS或者編寫(xiě)MapReduce程序饿幅。
lib 該目錄包含了hadoop對(duì)外提供的編程動(dòng)態(tài)庫(kù)和靜態(tài)庫(kù),與include目錄中的頭文件結(jié)合使用戒职。
libexec 各個(gè)服務(wù)隊(duì)用的shell配置文件所在的免疫力栗恩,可用于配置日志輸出,啟動(dòng)參數(shù)(比如JVM參數(shù))等基本信息洪燥。
sbin hadoop管理腳本所在的目錄磕秤,主要包含HDFS和YARN中各類(lèi)服務(wù)的\color{red}{啟動(dòng)、關(guān)閉腳本}捧韵。
share hadoop 各個(gè)模塊編譯后的jar包所在的目錄市咆。\color{red}{官方示例}也在其中

3、修改配置文件

配置文件目錄:/opt/bigdata/hadoop/server/hadoop-3.3.1/etc/hadoop
官方文檔:https://hadoop.apache.org/docs/r3.3.1/

  • 修改hadoop-env.sh
# 在hadoop-env.sh文件末尾追加
export JAVA_HOME=/opt/bigdata/hadoop/server/jdk1.8.0_212
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
  • 修改core-site.xml #核心模塊配置

在<configuration></configuration>中間添加如下內(nèi)容

<!-- 設(shè)置默認(rèn)使用的文件系統(tǒng) Hadoop支持file再来、HDFS蒙兰、GFS、ali|Amazon云等文件系統(tǒng) -->
<property>
  <name>fs.defaultFS</name>
  <value>hdfs://hadoop-node1:8082</value>
</property>

<!-- 設(shè)置Hadoop本地保存數(shù)據(jù)路徑 -->
<property>
  <name>hadoop.tmp.dir</name>
  <value>/opt/bigdata/hadoop/data/hadoop-3.3.1</value>
</property>

<!-- 設(shè)置HDFS web UI用戶身份 -->
<property>
  <name>hadoop.http.staticuser.user</name>
  <value>root</value>
</property>

<!-- 聚合hive 用戶代理設(shè)置 -->
<property>
  <name>hadoop.proxyuser.hosts</name>
  <value>*</value>
</property>

<!-- 用戶代理設(shè)置 -->
<property>
  <name>hadoop.proxyuser.root.groups</name>
  <value>*</value>
</property>

<!-- 文件系統(tǒng)垃圾桶保存時(shí)間 -->
<property>
  <name>fs.trash.interval</name>
  <value>1440</value>
</property>
  • hdfs-site.xml #hdfs文件系統(tǒng)模塊配置

在<configuration></configuration>中間添加如下內(nèi)容

<!-- 設(shè)置SNN進(jìn)程運(yùn)行機(jī)器位置信息 -->
<property>
  <name>dfs.namenode.secondary.http-address</name>
  <value>hadoop-node2:9868</value>
</property>

<!-- 必須將dfs.webhdfs.enabled屬性設(shè)置為true芒篷,否則就不能使用webhdfs的LISTSTATUS搜变、LISTFILESTATUS等需要列出文件、文件夾狀態(tài)的命令针炉,因?yàn)檫@些信息都是由namenode來(lái)保存的挠他。 -->
<property>
  <name>dfs.webhdfs.enabled</name>
  <value>true</value>
</property>
  • 修改mapred.xml #MapReduce模塊配置

在<configuration></configuration>中間添加如下內(nèi)容

<!-- 設(shè)置MR程序默認(rèn)運(yùn)行模式,yarn集群模式篡帕,local本地模式 -->
<property>
  <name>mapreduce.framework.name</name>
  <value>yarn</value>
</property>

<!-- MR程序歷史服務(wù)地址 -->
<property>
  <name>mapreduce.jobhistory.address</name>
  <value>hadoop-node1:10020</value>
</property>

<!-- MR程序歷史服務(wù)web端地址 -->
<property>
  <name>mapreduce.jobhistory.webapp.address</name>
  <value>hadoop-node1:19888</value>
</property>

<!-- yarn環(huán)境變量 -->
<property>
  <name>yarn.app.mapreduce.am.env</name>
  <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>

<!-- map環(huán)境變量 -->
<property>
  <name>mapreduce.map.env</name>
  <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>

<!-- reduce環(huán)境變量 -->
<property>
  <name>mapreduce.reduce.env</name>
  <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value>
</property>
  • 修改yarn-site.xml #yarn模塊配置

在<configuration></configuration>中間添加如下內(nèi)容

<!-- 設(shè)置YARN集群主角色運(yùn)行集群位置 -->
<property>
  <name>yarn.resourcemanager.hostname</name>
  <value>hadoop-node1</value>
</property>

<property>
  <name>yarn.nodemanager.aux-services</name>
  <value>mapreduce_shuffle</value>
</property>

<!-- 是否將對(duì)容器實(shí)施物理內(nèi)存限制 -->
<property>
  <name>yarn.nodemanager.pmem-check-enabled</name>
  <value>false</value>
</property>

<!-- 是否將對(duì)容器實(shí)施虛擬內(nèi)存限制 -->
<property>
  <name>yarn.nodemanager.vmem-check-enabled</name>
  <value>false</value>
</property>

<!-- 開(kāi)啟日志聚集 -->
<property>
  <name>yarn.log-aggregation-enable</name>
  <value>true</value>
</property>

<!-- 設(shè)置yarn歷史服務(wù)器地址 -->
<property>
  <name>yarn.log.server.url</name>
  <value>http://hadoop-node1:19888/jobhistory/logs</value>
</property>

<!-- 設(shè)置yarn歷史日志保存時(shí)間 7天 -->
<property>
  <name>yarn.log-aggregation.retain-seconds</name>
  <value>604880</value>
</property>
  • 修改workers
    將下面內(nèi)容覆蓋文件殖侵,默認(rèn)只有l(wèi)ocalhost
hadoop-node1
hadoop-node2
hadoop-node3
23.png

4、分發(fā)同步hadoop安裝包到另外幾臺(tái)機(jī)器

$ cd /opt/bigdata/hadoop/server/
$ scp -r hadoop-3.3.1 hadoop-node2:/opt/bigdata/hadoop/server/
$ scp -r hadoop-3.3.1 hadoop-node3:/opt/bigdata/hadoop/server/

5镰烧、將hadoop添加到環(huán)境變量(所有節(jié)點(diǎn))

$ vi /etc/profile

export HADOOP_HOME=/opt/bigdata/hadoop/server/hadoop-3.3.1
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH

# 加載
$ source /etc/profile

6拢军、Hadoop集群?jiǎn)?dòng)(hadoop-node1上執(zhí)行)

1)(首次啟動(dòng))格式化namenode(\color{red}{只能執(zhí)行一次}
  • 首次啟動(dòng)HDFS時(shí),必須對(duì)其進(jìn)行格式化操作
  • format本質(zhì)上初始化工作怔鳖,進(jìn)行HDFS清理和準(zhǔn)備工作
$ hdfs namenode -format
24.png
2)手動(dòng)逐個(gè)進(jìn)程啟停

每臺(tái)機(jī)器每次手動(dòng)啟動(dòng)關(guān)閉一個(gè)角色進(jìn)程茉唉,可以精確控制每個(gè)進(jìn)程啟停,避免群起群停

1败砂、HDFS集群?jiǎn)?dòng)

$ hdfs --daemon start|stop namenode|datanode|secondarynamenode

2赌渣、YARN集群?jiǎn)?dòng)

$ yarn --daemon start|stop resourcemanager|nodemanager
3)通過(guò)shell腳本一鍵啟動(dòng)

在hadoop-node1上,使用軟件自帶的shell腳本一鍵啟動(dòng)昌犹。前提:配置好機(jī)器之間的SSH免密登錄和works文件

  • HDFS集群?jiǎn)⑼?/li>
$ start-dfs.sh
$ stop-dfs.sh #這里不執(zhí)行
25.png

檢查java進(jìn)程

$ jps
26.png
  • YARN集群?jiǎn)⑼?/li>
$ start-yarn.sh
$ stop-yarn.sh # 這里不執(zhí)行
# 查看java進(jìn)程
$ jps
27.png

通過(guò)日志檢查坚芜,日志路徑:/opt/bigdata/hadoop/server/hadoop-3.3.1/logs

$ cd /opt/bigdata/hadoop/server/hadoop-3.3.1/logs
$ ll
28.png
  • Hadoop集群?jiǎn)⑼#℉DFS+YARN)
$ start-all.sh
$ stop-all.sh
4)通過(guò)web頁(yè)面訪問(wèn)

【注意】在window C:\Windows\System32\drivers\etc\hosts文件配置域名映射,hosts文件中增加如下內(nèi)容:

192.168.0.113 hadoop-node1
192.168.0.114 hadoop-node2
192.168.0.115 hadoop-node3

1斜姥、HDFS集群

地址:http://namenode_host:9870

這里地址為:http://192.168.0.113:9870

29.png

2鸿竖、YARN集群

地址:http://resourcemanager_host:8088

這里地址為:http://192.168.0.113:8088

30.png

到此為止沧竟,hadoop和yarn集群就已經(jīng)部署完了~


六、Hadoop實(shí)戰(zhàn)操作

1)HDFS實(shí)戰(zhàn)操作

  • 命令介紹
# 訪問(wèn)本地文件系統(tǒng)
$ hadoop fs -ls file:///
# 默認(rèn)不帶協(xié)議就是訪問(wèn)hdfs文件系統(tǒng)
$ hadoop fs -ls /
  • 查看配置
$ cd /opt/bigdata/hadoop/server/hadoop-3.3.1/etc/hadoop
$ grep -C5 'fs.defaultFS' core-site.xml
31.png
# 這里加上hdfs協(xié)議與不帶協(xié)議等價(jià)
$ hadoop fs -ls hdfs://hadoop-node1:8082/
32.png

\color{red}{【溫馨提示】所以默認(rèn)不帶協(xié)議就是訪問(wèn)HDFS文件系統(tǒng)}

  • 老版本的使用方式
$ hdfs dfs -ls /
$ hdfs dfs -ls hdfs://hadoop-node1:8082/
33.png

1缚忧、創(chuàng)建和刪除文件

# 查看
$ hadoop fs -ls /
# 創(chuàng)建目錄
$ hadoop fs -mkdir /test20211214
$ hadoop fs -ls /
# 創(chuàng)建文件
$ hadoop fs -touchz /test20211214/001.txt
$ hadoop fs -ls /test20211214
34.png

2悟泵、web端查看

35.png

36.png

# 刪除文件
$ hadoop fs -rm /test20211214/001.txt
# 刪除目錄
$ hadoop fs -rm -r /test20211214

3、推送文件到hdfs

$ touch test001.txt
$ hadoop fs -put test001.txt /
$ hadoop fs -ls /
37.png

4闪水、從hdfs上拉取文件

# 把test001.txt拉取下來(lái)糕非,并改名為a.txt
$ hadoop fs -get /test001.txt a.txt
38.png

2)MapReduce+YARN實(shí)戰(zhàn)操作

1、執(zhí)行Hadoop官方自帶的MapReduce案例球榆,評(píng)估圓周率Π的值

$ cd /opt/bigdata/hadoop/server/hadoop-3.3.1/share/hadoop/mapreduce
$ hadoop jar hadoop-mapreduce-examples-3.3.1.jar pi 2 4
39.png

2朽肥、統(tǒng)計(jì)單詞
創(chuàng)建hello.txt,文件內(nèi)容如下:

hello hadoop yarn world
hello yarn hadoop
hello world

在hdfs創(chuàng)建存放文件目錄

$ hadoop fs -mkdir -p /wordcount/input
# 把文件上傳到hdfs
$ hadoop fs -put hello.txt /wordcount/input/
40.png

執(zhí)行

$ cd /opt/bigdata/hadoop/server/hadoop-3.3.1/share/hadoop/mapreduce
$ hadoop jar hadoop-mapreduce-examples-3.3.1.jar wordcount /wordcount/input /wordcount/output
41.png

42.png

3)Yarn的常用命令

使用語(yǔ)法:yarn application [options] #打印報(bào)告持钉,申請(qǐng)和殺死任務(wù)

-appStates <States>         #與-list一起使用衡招,可根據(jù)輸入的逗號(hào)分隔的應(yīng)用程序狀態(tài)列表來(lái)過(guò)濾應(yīng)用程序。有效的應(yīng)用程序狀態(tài)可以是以下之一:ALL每强,NEW始腾,NEW_SAVING,SUBMITTED空执,ACCEPTED浪箭,RUNNING,F(xiàn)INISHED脆烟,F(xiàn)AILED山林,KILLED
-appTypes <Types>           #與-list一起使用,可以根據(jù)輸入的逗號(hào)分隔的應(yīng)用程序類(lèi)型列表來(lái)過(guò)濾應(yīng)用程序邢羔。
-list                       #列出RM中的應(yīng)用程序。支持使用-appTypes來(lái)根據(jù)應(yīng)用程序類(lèi)型過(guò)濾應(yīng)用程序桑孩,并支持使用-appStates來(lái)根據(jù)應(yīng)用程序狀態(tài)過(guò)濾應(yīng)用程序拜鹤。
-kill <ApplicationId>       #終止應(yīng)用程序。
-status <ApplicationId>     #打印應(yīng)用程序的狀態(tài)流椒。

簡(jiǎn)單示例

# 列出在運(yùn)行的應(yīng)用程序
$ yarn application --list
# 列出FINISHED的應(yīng)用程序
$ yarn application -appStates FINISHED --list  
43.png

更多操作命令敏簿,可以自行查看幫助

$ yarn -help

[root@hadoop-node1 hadoop]# yarn -help
Usage: yarn [OPTIONS] SUBCOMMAND [SUBCOMMAND OPTIONS]
 or    yarn [OPTIONS] CLASSNAME [CLASSNAME OPTIONS]
  where CLASSNAME is a user-provided Java class

  OPTIONS is none or any of:

--buildpaths                       attempt to add class files from build tree
--config dir                       Hadoop config directory
--daemon (start|status|stop)       operate on a daemon
--debug                            turn on shell script debug mode
--help                             usage information
--hostnames list[,of,host,names]   hosts to use in worker mode
--hosts filename                   list of hosts to use in worker mode
--loglevel level                   set the log4j level for this command
--workers                          turn on worker mode

  SUBCOMMAND is one of:


    Admin Commands:

daemonlog            get/set the log level for each daemon
node                 prints node report(s)
rmadmin              admin tools
scmadmin             SharedCacheManager admin tools

    Client Commands:

app|application      prints application(s) report/kill application/manage long running application
applicationattempt   prints applicationattempt(s) report
classpath            prints the class path needed to get the hadoop jar and the required libraries
cluster              prints cluster information
container            prints container(s) report
envvars              display computed Hadoop environment variables
fs2cs                converts Fair Scheduler configuration to Capacity Scheduler (EXPERIMENTAL)
jar <jar>            run a jar file
logs                 dump container logs
nodeattributes       node attributes cli client
queue                prints queue information
schedulerconf        Updates scheduler configuration
timelinereader       run the timeline reader server
top                  view cluster information
version              print the version

    Daemon Commands:

nodemanager          run a nodemanager on each worker
proxyserver          run the web app proxy server
registrydns          run the registry DNS server
resourcemanager      run the ResourceManager
router               run the Router daemon
sharedcachemanager   run the SharedCacheManager daemon
timelineserver       run the timeline server

SUBCOMMAND may print help when invoked w/o parameters or with -h.


這里只是簡(jiǎn)單的dmeo案例演示操作,后面會(huì)有企業(yè)級(jí)的案例+實(shí)戰(zhàn)操作分享宣虾,請(qǐng)耐心等待……

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末惯裕,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绣硝,更是在濱河造成了極大的恐慌蜻势,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹉胖,死亡現(xiàn)場(chǎng)離奇詭異握玛,居然都是意外死亡够傍,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)挠铲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)冕屯,“玉大人,你說(shuō)我怎么就攤上這事拂苹“财福” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵瓢棒,是天一觀的道長(zhǎng)浴韭。 經(jīng)常有香客問(wèn)我,道長(zhǎng)音羞,這世上最難降的妖魔是什么囱桨? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮嗅绰,結(jié)果婚禮上舍肠,老公的妹妹穿的比我還像新娘。我一直安慰自己窘面,他們只是感情好翠语,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著财边,像睡著了一般肌括。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上酣难,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天谍夭,我揣著相機(jī)與錄音,去河邊找鬼憨募。 笑死紧索,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的菜谣。 我是一名探鬼主播珠漂,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼尾膊!你這毒婦竟也來(lái)了媳危?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤冈敛,失蹤者是張志新(化名)和其女友劉穎待笑,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體莺债,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滋觉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年签夭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片椎侠。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡第租,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出我纪,到底是詐尸還是另有隱情慎宾,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布浅悉,位于F島的核電站趟据,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏术健。R本人自食惡果不足惜汹碱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荞估。 院中可真熱鬧咳促,春花似錦、人聲如沸勘伺。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)飞醉。三九已至冲茸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缅帘,已是汗流浹背轴术。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留钦无,地道東北人膳音。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像铃诬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子苍凛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容