Hadoop核心HDFS分布式文件系統(tǒng)詳解

轉載自微信公眾號: 五分鐘學大數(shù)據(jù)

1. HDFS概述

Hadoop 分布式系統(tǒng)框架中,首要的基礎功能就是文件系統(tǒng)炼吴,在 Hadoop 中使用 FileSystem 這個抽象類來表示我們的文件系統(tǒng),這個抽象類下面有很多子實現(xiàn)類疫衩,究竟使用哪一種硅蹦,需要看我們具體的實現(xiàn)類,在我們實際工作中闷煤,用到的最多的就是HDFS(分布式文件系統(tǒng))以及LocalFileSystem(本地文件系統(tǒng))了童芹。

在現(xiàn)代的企業(yè)環(huán)境中,單機容量往往無法存儲大量數(shù)據(jù)鲤拿,需要跨機器存儲假褪。統(tǒng)一管理分布在集群上的文件系統(tǒng)稱為分布式文件系統(tǒng)

HDFS(Hadoop Distributed File System)是 Hadoop 項目的一個子項目近顷。是 Hadoop 的核心組件之一生音, Hadoop 非常適于存儲大型數(shù)據(jù) (比如 TB 和 PB)约谈,其就是使用 HDFS 作為存儲系統(tǒng). HDFS 使用多臺計算機存儲文件苞氮,并且提供統(tǒng)一的訪問接口鹿寨,像是訪問一個普通文件系統(tǒng)一樣使用分布式文件系統(tǒng)荆姆。

HDFS文件系統(tǒng)

2. HDFS架構

HDFS架構

HDFS是一個主/從(Mater/Slave)體系結構执桌,由三部分組成:NameNodeDataNode 以及 SecondaryNamenode

  • NameNode 負責管理整個文件系統(tǒng)的元數(shù)據(jù)桅狠,以及每一個路徑(文件)所對應的數(shù)據(jù)塊信息奸笤。

  • DataNode 負責管理用戶的文件數(shù)據(jù)塊痕檬,每一個數(shù)據(jù)塊都可以在多個 DataNode 上存儲多個副本冤寿,默認為3個歹苦。

  • Secondary NameNode 用來監(jiān)控 HDFS 狀態(tài)的輔助后臺程序,每隔一段時間獲取 HDFS 元數(shù)據(jù)的快照督怜。最主要作用是輔助 NameNode 管理元數(shù)據(jù)信息殴瘦。

圖片

3. HDFS的特性

首先,它是一個文件系統(tǒng)号杠,用于存儲文件蚪腋,通過統(tǒng)一的命名空間目錄樹來定位文件;

其次姨蟋,它是分布式的屉凯,由很多服務器聯(lián)合起來實現(xiàn)其功能,集群中的服務器有各自的角色眼溶。

  • 1. master/slave 架構(主從架構)

HDFS 采用 master/slave 架構悠砚。一般一個 HDFS 集群是有一個 Namenode 和一定數(shù)目的 Datanode 組成。Namenode 是 HDFS 集群主節(jié)點堂飞,Datanode 是 HDFS 集群從節(jié)點灌旧,兩種角色各司其職绑咱,共同協(xié)調(diào)完成分布式的文件存儲服務。

  • 2. 分塊存儲

HDFS 中的文件在物理上是分塊存儲(block)的枢泰,塊的大小可以通過配置參數(shù)來規(guī)定描融,默認大小在 hadoop2.x 版本中是 128M。

  • 3. 名字空間(NameSpace)

HDFS 支持傳統(tǒng)的層次型文件組織結構衡蚂。用戶或者應用程序可以創(chuàng)建目錄窿克,然后將文件保存在這些目錄里。文件系統(tǒng)名字空間的層次結構和大多數(shù)現(xiàn)有的文件系統(tǒng)類似:用戶可以創(chuàng)建讳窟、刪除让歼、移動或重命名文件敞恋。
Namenode 負責維護文件系統(tǒng)的名字空間丽啡,任何對文件系統(tǒng)名字空間或屬性的修改都將被 Namenode 記錄下來。
HDFS 會給客戶端提供一個統(tǒng)一的抽象目錄樹硬猫,客戶端通過路徑來訪問文件补箍,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data

  • 4. NameNode 元數(shù)據(jù)管理

我們把目錄結構及文件分塊位置信息叫做元數(shù)據(jù)啸蜜。NameNode 負責維護整個 HDFS 文件系統(tǒng)的目錄樹結構坑雅,以及每一個文件所對應的 block 塊信息(block 的 id,及所在的 DataNode 服務器)衬横。

  • 5. DataNode 數(shù)據(jù)存儲

文件的各個 block 的具體存儲管理由 DataNode 節(jié)點承擔裹粤。每一個 block 都可以在多個 DataNode 上。DataNode 需要定時向 NameNode 匯報自己持有的 block 信息蜂林。存儲多個副本(副本數(shù)量也可以通過參數(shù)設置 dfs.replication遥诉,默認是 3)

  • 6. 副本機制

為了容錯,文件的所有 block 都會有副本噪叙。每個文件的 block 大小和副本系數(shù)都是可配置的矮锈。應用程序可以指定某個文件的副本數(shù)目。副本系數(shù)可以在文件創(chuàng)建的時候指定睁蕾,也可以在之后改變苞笨。

  • 7. 一次寫入,多次讀出

HDFS 是設計成適應一次寫入子眶,多次讀出的場景瀑凝,且不支持文件的修改。
正因為如此臭杰,HDFS 適合用來做大數(shù)據(jù)分析的底層存儲服務粤咪,并不適合用來做網(wǎng)盤等應用,因為修改不方便硅卢,延遲大射窒,網(wǎng)絡開銷大藏杖,成本太高。

4. HDFS 的命令行使用

如果沒有配置 hadoop 的環(huán)境變量脉顿,則在 hadoop 的安裝目錄下的bin目錄中執(zhí)行以下命令蝌麸,如已配置 hadoop 環(huán)境變量,則可在任意目錄下執(zhí)行

help

格式:  hdfs dfs -help 操作命令
作用: 查看某一個操作命令的參數(shù)信息

ls

格式:hdfs dfs -ls  URI
作用:類似于Linux的ls命令艾疟,顯示文件列表

lsr

格式  :   hdfs  dfs -lsr URI
作用  : 在整個目錄下遞歸執(zhí)行l(wèi)s, 與UNIX中的ls-R類似

mkdir

格式 :hdfs  dfs  -mkdir [-p] <paths>
作用 :   以<paths>中的URI作為參數(shù)来吩,創(chuàng)建目錄。使用-p參數(shù)可以遞歸創(chuàng)建目錄

put

格式   :hdfs dfs -put <localsrc >  ... <dst>
作用 :  將單個的源文件src或者多個源文件srcs從本地文件系統(tǒng)拷貝到目標文件系統(tǒng)中(<dst>對應的路徑)蔽莱。
也可以從標準輸入中讀取輸入弟疆,寫入目標文件系統(tǒng)中
hdfs dfs -put  /rooot/bigdata.txt  /dir1

moveFromLocal

格式:hdfs  dfs -moveFromLocal  <localsrc>   <dst>
作用:  和put命令類似,但是源文件localsrc拷貝之后自身被刪除
hdfs  dfs -moveFromLocal  /root/bigdata.txt  /

copyFromLocal

格式:  hdfs dfs -copyFromLocal <localsrc> ... <dst>
作用: 從本地文件系統(tǒng)中拷貝文件到hdfs路徑去

appendToFile

格式: hdfs dfs -appendToFile <localsrc> ... <dst>
作用: 追加一個或者多個文件到hdfs指定文件中.也可以從命令行讀取輸入.
 hdfs dfs -appendToFile  a.xml b.xml  /big.xml

moveToLocal

# 在 hadoop 2.6.4 版本測試還未未實現(xiàn)此方法格式:
hadoop  dfs  -moveToLocal [-crc] <src> <dst>
作用:將本地文件剪切到 HDFS

get

格式   hdfs dfs  -get [-ignorecrc ]  [-crc]  <src> <localdst>
作用:將文件拷貝到本地文件系統(tǒng)盗冷。
CRC 校驗失敗的文件通過-ignorecrc選項拷貝怠苔。 
文件和CRC校驗可以通過-CRC選項拷貝
hdfs dfs  -get   /bigdata.txt  /export/servers

getmerge

格式: hdfs dfs -getmerge <src> <localdst>
作用: 合并下載多個文件,比如hdfs的目錄 /aaa/下有多個文件:log.1, log.2,log.3,...

copyToLocal

格式:  hdfs dfs -copyToLocal <src> ... <localdst>
作用:  從hdfs拷貝到本地

mv

格式  :hdfs  dfs -mv URI   <dest>
作用: 將hdfs上的文件從原路徑移動到目標路徑(移動之后文件刪除)仪糖,該命令不能跨文件系統(tǒng)
hdfs  dfs  -mv  /dir1/bigdata.txt   /dir2

rm

格式:hdfs dfs -rm [-r] 【-skipTrash】 URI 【URI 柑司。。锅劝≡艹郏】
作用: 刪除參數(shù)指定的文件,參數(shù)可以有多個故爵。  
此命令只刪除文件和非空目錄玻粪。
如果指定-skipTrash選項,那么在回收站可用的情況下诬垂,該選項將跳過回收站而直接刪除文件劲室;
否則,在回收站可用時剥纷,在HDFS Shell 中執(zhí)行此命令痹籍,會將文件暫時放到回收站中。
hdfs  dfs  -rm  -r  /dir1

cp

格式: hdfs  dfs  -cp URI [URI ...] <dest>
作用: 將文件拷貝到目標路徑中晦鞋。
如果<dest>  為目錄的話蹲缠,可以將多個文件拷貝到該目錄下。
-f選項將覆蓋目標悠垛,如果它已經(jīng)存在线定。
-p選項將保留文件屬性(時間戳、所有權确买、許可斤讥、ACL、XAttr)。
hdfs dfs -cp /dir1/a.txt  /dir2/bigdata.txt

cat

hdfs dfs  -cat  URI [uri  ...]
作用:將參數(shù)所指示的文件內(nèi)容輸出到stdout
hdfs dfs  -cat /bigdata.txt

tail

格式: hdfs dfs -tail path
作用: 顯示一個文件的末尾

text

格式:hdfs dfs -text path
作用: 以字符形式打印一個文件的內(nèi)容

chmod

格式:hdfs  dfs  -chmod  [-R]  URI[URI  ...] 
作用:改變文件權限芭商。
如果使用  -R 選項派草,則對整個目錄有效遞歸執(zhí)行。
使用這一命令的用戶必須是文件的所屬用戶铛楣,或者超級用戶近迁。
hdfs dfs -chmod -R 777 /bigdata.txt

chown

格式:  hdfs  dfs  -chmod  [-R]  URI[URI ...] 
作用:改變文件的所屬用戶和用戶組。
如果使用  -R 選項簸州,則對整個目錄有效遞歸執(zhí)行鉴竭。
使用這一命令的用戶必須是文件的所屬用戶,或者超級用戶岸浑。
hdfs  dfs  -chown  -R hadoop:hadoop  /bigdata.txt

df

格式: hdfs dfs  -df  -h  path
作用: 統(tǒng)計文件系統(tǒng)的可用空間信息

du

格式: hdfs dfs -du -s -h path
作用: 統(tǒng)計文件夾的大小信息

count

格式: hdfs dfs -count path
作用: 統(tǒng)計一個指定目錄下的文件節(jié)點數(shù)量

setrep

格式:  hdfs dfs -setrep num filePath 
作用: 設置hdfs中文件的副本數(shù)量注意: 
即使設置的超過了datanode的數(shù)量,
副本的數(shù)量也最多只能和datanode的數(shù)量是一致的

expunge (慎用)

格式:  hdfs dfs  -expunge
作用: 清空hdfs垃圾桶 

5. hdfs的高級使用命令

5.1. HDFS文件限額配置

在多人共用HDFS的環(huán)境下搏存,配置設置非常重要。特別是在 Hadoop 處理大量資料的環(huán)境矢洲,如果沒有配額管理璧眠,很容易把所有的空間用完造成別人無法存取。HDFS 的配額設定是針對目錄而不是針對賬號兵钮,可以讓每個賬號僅操作某一個目錄蛆橡,然后對目錄設置配置舌界。

HDFS 文件的限額配置允許我們以文件個數(shù)掘譬,或者文件大小來限制我們在某個目錄下上傳的文件數(shù)量或者文件內(nèi)容總量,以便達到我們類似百度網(wǎng)盤網(wǎng)盤等限制每個用戶允許上傳的最大的文件的量呻拌。

 hdfs dfs -count -q -h /user/root/dir1  #查看配額信息

結果:
圖片

5.1.1. 數(shù)量限額

hdfs dfs  -mkdir -p /user/root/dir    #創(chuàng)建hdfs文件夾
hdfs dfsadmin -setQuota 2  dir      # 給該文件夾下面設置最多上傳兩個文件葱轩,發(fā)現(xiàn)只能上傳一個文件
hdfs dfsadmin -clrQuota /user/root/dir  # 清除文件數(shù)量限制

5.1.2. 空間大小限額

在設置空間配額時,設置的空間至少是 block_size * 3 大小

hdfs dfsadmin -setSpaceQuota 4k /user/root/dir   # 限制空間大小4KB
hdfs dfs -put  /root/a.txt  /user/root/dir 

生成任意大小文件的命令:

dd if=/dev/zero of=1.txt  bs=1M count=2     #生成2M的文件

清除空間配額限制

hdfs dfsadmin -clrSpaceQuota /user/root/dir

5.2. HDFS 的安全模式

安全模式是hadoop的一種保護機制藐握,用于保證集群中的數(shù)據(jù)塊的安全性靴拱。當集群啟動的時候,會首先進入安全模式猾普。當系統(tǒng)處于安全模式時會檢查數(shù)據(jù)塊的完整性袜炕。

假設我們設置的副本數(shù)(即參數(shù)dfs.replication)是3,那么在datanode上就應該有3個副本存在初家,假設只存在2個副本偎窘,那么比例就是2/3=0.666。hdfs默認的副本率0.999溜在。我們的副本率0.666明顯小于0.999陌知,因此系統(tǒng)會自動的復制副本到其他dataNode,使得副本率不小于0.999掖肋。如果系統(tǒng)中有5個副本仆葡,超過我們設定的3個副本,那么系統(tǒng)也會刪除多于的2個副本志笼。

在安全模式狀態(tài)下沿盅,文件系統(tǒng)只接受讀數(shù)據(jù)請求把篓,而不接受刪除、修改等變更請求腰涧。在纸俭,當整個系統(tǒng)達到安全標準時,HDFS自動離開安全模式南窗。30s

安全模式操作命令

hdfs  dfsadmin  -safemode  get #查看安全模式狀態(tài)    
hdfs  dfsadmin  -safemode  enter #進入安全模式    
hdfs  dfsadmin  -safemode  leave #離開安全模式

6. HDFS 的 block 塊和副本機制

HDFS 將所有的文件全部抽象成為 block 塊來進行存儲揍很,不管文件大小,全部一視同仁都是以 block 塊的統(tǒng)一大小和形式進行存儲万伤,方便我們的分布式文件系統(tǒng)對文件的管理窒悔。

所有的文件都是以 block 塊的方式存放在 hdfs 文件系統(tǒng)當中,在 Hadoop 1 版本當中敌买,文件的 block 塊默認大小是 64M简珠,Hadoop 2 版本當中,文件的 block 塊大小默認是128M虹钮,block塊的大小可以通過 hdfs-site.xml 當中的配置文件進行指定聋庵。

<property>    
    <name>dfs.block.size</name>    
    <value>塊大小 以字節(jié)為單位</value> //只寫數(shù)值就可以<
/property>

6.1 抽象為block塊的好處

    1. 一個文件有可能大于集群中任意一個磁盤
      10T*3/128 = xxx塊 2T,2T芙粱,2T 文件方式存—–>多個block塊祭玉,這些block塊屬于一個文件
    1. 使用塊抽象而不是文件可以簡化存儲子系統(tǒng)
    1. 塊非常適合用于數(shù)據(jù)備份進而提供數(shù)據(jù)容錯能力和可用性

6.2 塊緩存

通常 DataNode 從磁盤中讀取塊,但對于訪問頻繁的文件春畔,其對應的塊可能被顯示的緩存在 DataNode 的內(nèi)存中脱货,以堆外塊緩存的形式存在。默認情況下律姨,一個塊僅緩存在一個DataNode的內(nèi)存中振峻,當然可以針對每個文件配置DataNode的數(shù)量。作業(yè)調(diào)度器通過在緩存塊的DataNode上運行任務择份,可以利用塊緩存的優(yōu)勢提高讀操作的性能扣孟。

例如:
連接(join)操作中使用的一個小的查詢表就是塊緩存的一個很好的候選。用戶或應用通過在緩存池中增加一個cache directive來告訴namenode需要緩存哪些文件及存多久荣赶。緩存池(cache pool)是一個擁有管理緩存權限和資源使用的管理性分組凤价。

例如:

一個文件 130M,會被切分成2個block塊讯壶,保存在兩個block塊里面料仗,實際占用磁盤130M空間,而不是占用256M的磁盤空間

6.3 hdfs的文件權限驗證

hdfs的文件權限機制與linux系統(tǒng)的文件權限機制類似

r:read w:write x:execute
權限x對于文件表示忽略伏蚊,對于文件夾表示是否有權限訪問其內(nèi)容

如果linux系統(tǒng)用戶zhangsan使用hadoop命令創(chuàng)建一個文件立轧,那么這個文件在HDFS當中的owner就是zhangsan

HDFS文件權限的目的,防止好人做錯事,而不是阻止壞人做壞事氛改。HDFS相信你告訴我你是誰帐萎,你就是誰

6.4 hdfs的副本因子

為了保證block塊的安全性,也就是數(shù)據(jù)的安全性胜卤,在hadoop2當中疆导,文件默認保存三個副本,我們可以更改副本數(shù)以提高數(shù)據(jù)的安全性

葛躏、在hdfs-site.xml當中修改以下配置屬性澈段,即可更改文件的副本數(shù)

<property>     
    <name>dfs.replication</name>     
    <value>3</value>
</property>

7. HDFS 文件寫入過程(非常重要)

HDFS 文件寫入過程
  1. Client 發(fā)起文件上傳請求,通過 RPC 與 NameNode 建立通訊, NameNode 檢查目標文件是否已存在舰攒,父目錄是否存在败富,返回是否可以上傳;

  2. Client 請求第一個 block 該傳輸?shù)侥男?DataNode 服務器上摩窃;

  3. NameNode 根據(jù)配置文件中指定的備份數(shù)量及機架感知原理進行文件分配, 返回可用的 DataNode 的地址如:A, B, C兽叮;

Hadoop 在設計時考慮到數(shù)據(jù)的安全與高效, 數(shù)據(jù)文件默認在 HDFS 上存放三份猾愿, 存儲策略為本地一份鹦聪,同機架內(nèi)其它某一節(jié)點上一份,不同機架的某一節(jié)點上一份蒂秘。

  1. Client 請求 3 臺 DataNode 中的一臺 A 上傳數(shù)據(jù)(本質(zhì)上是一個 RPC 調(diào)用泽本,建立 pipeline ),A 收到請求會繼續(xù)調(diào)用 B材彪,然后 B 調(diào)用 C观挎,將整個 pipeline 建立完成, 后逐級返回 client段化;

  2. Client 開始往 A 上傳第一個 block(先從磁盤讀取數(shù)據(jù)放到一個本地內(nèi)存緩存),以 packet 為單位(默認64K)造成,A 收到一個 packet 就會傳給 B显熏,B 傳給 C。A 每傳一個 packet 會放入一個應答隊列等待應答晒屎;

  3. 數(shù)據(jù)被分割成一個個 packet 數(shù)據(jù)包在 pipeline 上依次傳輸喘蟆,在 pipeline 反方向上, 逐個發(fā)送 ack(命令正確應答)鼓鲁,最終由 pipeline 中第一個 DataNode 節(jié)點 A 將 pipelineack 發(fā)送給 Client蕴轨;

  4. 當一個 block 傳輸完成之后,Client 再次請求 NameNode 上傳第二個 block骇吭,重復步驟 2橙弱。

7.1 網(wǎng)絡拓撲概念

在本地網(wǎng)絡中,兩個節(jié)點被稱為“彼此近鄰”是什么意思?在海量數(shù)據(jù)處理中棘脐,其主要限制因素是節(jié)點之間數(shù)據(jù)的傳輸速率——帶寬很稀缺斜筐。這里的想法是將兩個節(jié)點間的帶寬作為距離的衡量標準。

節(jié)點距離:兩個節(jié)點到達最近的共同祖先的距離總和蛀缝。

例如顷链,假設有數(shù)據(jù)中心d1機架r1中的節(jié)點n1。該節(jié)點可以表示為/d1/r1/n1屈梁。利用這種標記嗤练,這里給出四種距離描述:

Distance(/d1/r1/n1, /d1/r1/n1)=0(同一節(jié)點上的進程)

Distance(/d1/r1/n1, /d1/r1/n2)=2(同一機架上的不同節(jié)點)

Distance(/d1/r1/n1, /d1/r3/n2)=4(同一數(shù)據(jù)中心不同機架上的節(jié)點)

Distance(/d1/r1/n1, /d2/r4/n2)=6(不同數(shù)據(jù)中心的節(jié)點)
機架

7.2 機架感知(副本節(jié)點選擇)

1)低版本Hadoop副本節(jié)點選擇

第一個副本在client所處的節(jié)點上。如果客戶端在集群外在讶,隨機選一個潭苞。

第二個副本和第一個副本位于不相同機架的隨機節(jié)點上。

第三個副本和第二個副本位于相同機架真朗,節(jié)點隨機此疹。

機架感知
  1. Hadoop2.7.2 副本節(jié)點選擇

第一個副本在client所處的節(jié)點上。如果客戶端在集群外遮婶,隨機選一個蝗碎。

第二個副本和第一個副本位于相同機架,隨機節(jié)點旗扑。

第三個副本位于不同機架蹦骑,隨機節(jié)點。

機架感知

8.HDFS 文件讀取過程(非常重要)

HDFS 文件讀取過程
  1. Client向NameNode發(fā)起RPC請求臀防,來確定請求文件block所在的位置眠菇;

  2. NameNode會視情況返回文件的部分或者全部block列表,對于每個block袱衷,NameNode 都會返回含有該 block 副本的 DataNode 地址捎废; 這些返回的 DN 地址,會按照集群拓撲結構得出 DataNode 與客戶端的距離致燥,然后進行排序登疗,排序兩個規(guī)則:網(wǎng)絡拓撲結構中距離 Client 近的排靠前;心跳機制中超時匯報的 DN 狀態(tài)為 STALE嫌蚤,這樣的排靠后辐益;

  3. Client 選取排序靠前的 DataNode 來讀取 block,如果客戶端本身就是DataNode脱吱,那么將從本地直接獲取數(shù)據(jù)(短路讀取特性)智政;

  4. 底層上本質(zhì)是建立 Socket Stream(FSDataInputStream),重復的調(diào)用父類 DataInputStream 的 read 方法箱蝠,直到這個塊上的數(shù)據(jù)讀取完畢续捂;

  5. 當讀完列表的 block 后垦垂,若文件讀取還沒有結束,客戶端會繼續(xù)向NameNode 獲取下一批的 block 列表疾忍;

  6. 讀取完一個 block 都會進行 checksum 驗證乔外,如果讀取 DataNode 時出現(xiàn)錯誤,客戶端會通知 NameNode一罩,然后再從下一個擁有該 block 副本的DataNode 繼續(xù)讀杨幼。

  7. read 方法是并行的讀取 block 信息,不是一塊一塊的讀取聂渊;NameNode 只是返回Client請求包含塊的DataNode地址差购,并不是返回請求塊的數(shù)據(jù);

  8. 最終讀取來所有的 block 會合并成一個完整的最終文件汉嗽。

從 HDFS 文件讀寫過程中欲逃,可以看出,HDFS 文件寫入時是串行寫入的饼暑,數(shù)據(jù)包先發(fā)送給節(jié)點A稳析,然后節(jié)點A發(fā)送給B,B再給C弓叛;而HDFS文件讀取是并行的彰居, 客戶端 Client 直接并行讀取block所在的節(jié)點。

9. NameNode 工作機制以及元數(shù)據(jù)管理(重要)

NameNode 工作機制

9.1 namenode 與 datanode 啟動

  • namenode工作機制
  1. 第一次啟動namenode格式化后撰筷,創(chuàng)建fsimage和edits文件陈惰。如果不是第一次啟動,直接加載編輯日志和鏡像文件到內(nèi)存毕籽。

  2. 客戶端對元數(shù)據(jù)進行增刪改的請求抬闯。

  3. namenode記錄操作日志,更新滾動日志关筒。

  4. namenode在內(nèi)存中對數(shù)據(jù)進行增刪改查溶握。

  • secondary namenode
  1. secondary namenode詢問 namenode 是否需要 checkpoint。直接帶回 namenode 是否檢查結果平委。

  2. secondary namenode 請求執(zhí)行 checkpoint奈虾。

  3. namenode 滾動正在寫的edits日志。

  4. 將滾動前的編輯日志和鏡像文件拷貝到 secondary namenode廉赔。

  5. secondary namenode 加載編輯日志和鏡像文件到內(nèi)存,并合并匾鸥。

  6. 生成新的鏡像文件 fsimage.chkpoint蜡塌。

  7. 拷貝 fsimage.chkpoint 到 namenode。

  8. namenode將 fsimage.chkpoint 重新命名成fsimage勿负。

9.2 FSImage與edits詳解

所有的元數(shù)據(jù)信息都保存在了FsImage與Eidts文件當中馏艾,這兩個文件就記錄了所有的數(shù)據(jù)的元數(shù)據(jù)信息劳曹,元數(shù)據(jù)信息的保存目錄配置在了 hdfs-site.xml 當中

<!--fsimage文件存儲的路徑-->
<property>
    <name>dfs.namenode.name.dir</name>
    <value>file:///opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/namenodeDatas</value>
</property>
<!-- edits文件存儲的路徑 -->
<property>
    <name>dfs.namenode.edits.dir</name>
    <value>file:///opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/nn/edits</value>
</property>

客戶端對hdfs進行寫文件時會首先被記錄在edits文件中。

edits修改時元數(shù)據(jù)也會更新琅摩。

每次hdfs更新時edits先更新后客戶端才會看到最新信息铁孵。

fsimage:是namenode中關于元數(shù)據(jù)的鏡像,一般稱為檢查點房资。

一般開始時對namenode的操作都放在edits中蜕劝,為什么不放在fsimage中呢?

因為fsimage是namenode的完整的鏡像轰异,內(nèi)容很大岖沛,如果每次都加載到內(nèi)存的話生成樹狀拓撲結構,這是非常耗內(nèi)存和CPU搭独。

fsimage內(nèi)容包含了namenode管理下的所有datanode中文件及文件block及block所在的datanode的元數(shù)據(jù)信息婴削。隨著edits內(nèi)容增大,就需要在一定時間點和fsimage合并牙肝。

9.3 FSimage文件當中的文件信息查看

  • 使用命令 hdfs oiv
cd  /opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/namenodeDatas/current
hdfs oiv -i fsimage_0000000000000000112 -p XML -o hello.xml

9.4 edits當中的文件信息查看

  • 查看命令 hdfs oev
cd  /opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/nn/edits
hdfs oev -i  edits_0000000000000000112-0000000000000000113 -o myedit.xml -p XML

9.5 secondarynameNode如何輔助管理FSImage與Edits文件

  1. secnonaryNN通知NameNode切換editlog唉俗。

  2. secondaryNN從NameNode中獲得FSImage和editlog(通過http方式)。

  3. secondaryNN將FSImage載入內(nèi)存配椭,然后開始合并editlog虫溜,合并之后成為新的fsimage。

  4. secondaryNN將新的fsimage發(fā)回給NameNode颂郎。

  5. NameNode用新的fsimage替換舊的fsimage吼渡。

圖片

完成合并的是 secondarynamenode,會請求namenode停止使用edits乓序,暫時將新寫操作放入一個新的文件中(edits.new)寺酪。

secondarynamenode從namenode中通過http get獲得edits,因為要和fsimage合并替劈,所以也是通過http get 的方式把fsimage加載到內(nèi)存寄雀,然后逐一執(zhí)行具體對文件系統(tǒng)的操作,與fsimage合并陨献,生成新的fsimage盒犹,然后把fsimage發(fā)送給namenode,通過http post的方式眨业。

namenode從secondarynamenode獲得了fsimage后會把原有的fsimage替換為新的fsimage急膀,把edits.new變成edits。同時會更新fsimage龄捡。

hadoop進入安全模式時需要管理員使用dfsadmin的save namespace來創(chuàng)建新的檢查點卓嫂。

secondarynamenode在合并edits和fsimage時需要消耗的內(nèi)存和namenode差不多,所以一般把namenode和secondarynamenode放在不同的機器上聘殖。

fsimage與edits的合并時機取決于兩個參數(shù)晨雳,第一個參數(shù)是默認1小時fsimage與edits合并一次行瑞。

  • 第一個參數(shù):時間達到一個小時fsimage與edits就會進行合并
dfs.namenode.checkpoint.period     3600
  • 第二個參數(shù):hdfs操作達到1000000次也會進行合并
dfs.namenode.checkpoint.txns       1000000
  • 第三個參數(shù):每隔多長時間檢查一次hdfs的操作次數(shù)
dfs.namenode.checkpoint.check.period   60

9.6 namenode元數(shù)據(jù)信息多目錄配置

為了保證元數(shù)據(jù)的安全性,我們一般都是先確定好我們的磁盤掛載目錄餐禁,將元數(shù)據(jù)的磁盤做RAID1

namenode的本地目錄可以配置成多個血久,且每個目錄存放內(nèi)容相同,增加了可靠性帮非。

  • 具體配置方案:

    hdfs-site.xml

<property>
     <name>dfs.namenode.name.dir</name>
     <value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/namenodeDatas</value>
</property>

9.7 namenode故障恢復

在我們的secondaryNamenode對namenode當中的fsimage和edits進行合并的時候氧吐,每次都會先將namenode的fsimage與edits文件拷貝一份過來,所以fsimage與edits文件在secondarNamendoe當中也會保存有一份喜鼓,如果namenode的fsimage與edits文件損壞郭毕,那么我們可以將secondaryNamenode當中的fsimage與edits拷貝過去給namenode繼續(xù)使用披粟,只不過有可能會丟失一部分數(shù)據(jù)久信。這里涉及到幾個配置選項

  • namenode保存fsimage的配置路徑
<!--  namenode元數(shù)據(jù)存儲路徑罪塔,實際工作當中一般使用SSD固態(tài)硬盤,并使用多個固態(tài)硬盤隔開隅忿,冗余元數(shù)據(jù) -->
<property>
    <name>dfs.namenode.name.dir</name>
    <value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/namenodeDatas</value>
</property>
  • namenode保存edits文件的配置路徑
<property>
    <name>dfs.namenode.edits.dir</name>
    <value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/nn/edits</value>
</property>
  • secondaryNamenode保存fsimage文件的配置路徑
<property>
    <name>dfs.namenode.checkpoint.dir</name>
    <value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/snn/name</value>
</property>
  • secondaryNamenode保存edits文件的配置路徑
<property>
    <name>dfs.namenode.checkpoint.edits.dir</name>
    <value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/dfs/nn/snn/edits</value>
</property>

接下來我們來模擬namenode的故障恢復功能

  1. 殺死namenode進程: 使用jps查看namenode的進程號 , kill -9 直接殺死心剥。

  2. 刪除namenode的fsimage文件和edits文件。

根據(jù)上述配置, 找到namenode放置fsimage和edits路徑. 直接全部rm -rf 刪除背桐。

  1. 拷貝secondaryNamenode的fsimage與edits文件到namenode的fsimage與edits文件夾下面去优烧。
    根據(jù)上述配置, 找到secondaryNamenode的fsimage和edits路徑, 將內(nèi)容 使用cp -r 全部復制到namenode對應的目錄下即可。
  1. 重新啟動namenode, 觀察數(shù)據(jù)是否存在链峭。

10 datanode工作機制以及數(shù)據(jù)存儲

  • datanode工作機制
  1. 一個數(shù)據(jù)塊在datanode上以文件形式存儲在磁盤上畦娄,包括兩個文件,一個是數(shù)據(jù)本身弊仪,一個是元數(shù)據(jù)包括數(shù)據(jù)塊的長度熙卡,塊數(shù)據(jù)的校驗和,以及時間戳励饵。

  2. DataNode啟動后向namenode注冊驳癌,通過后,周期性(1小時)的向namenode上報所有的塊信息役听。(dfs.blockreport.intervalMsec)颓鲜。

  3. 心跳是每3秒一次,心跳返回結果帶有namenode給該datanode的命令如復制塊數(shù)據(jù)到另一臺機器典予,或刪除某個數(shù)據(jù)塊甜滨。如果超過10分鐘沒有收到某個datanode的心跳,則認為該節(jié)點不可用瘤袖。

  4. 集群運行中可以安全加入和退出一些機器艳吠。

  • 數(shù)據(jù)完整性
  1. 當DataNode讀取block的時候,它會計算checksum孽椰。

  2. 如果計算后的checksum昭娩,與block創(chuàng)建時值不一樣,說明block已經(jīng)損壞黍匾。

  3. client讀取其他DataNode上的block栏渺。

  4. datanode在其文件創(chuàng)建后周期驗證checksum。

  • 掉線時限參數(shù)設置

datanode進程死亡或者網(wǎng)絡故障造成datanode無法與namenode通信锐涯,namenode不會立即把該節(jié)點判定為死亡磕诊,要經(jīng)過一段時間,這段時間暫稱作超時時長纹腌。HDFS默認的超時時長為10分鐘+30秒霎终。如果定義超時時間為timeout,則超時時長的計算公式為:

timeout = 2 * dfs.namenode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval升薯。

而默認的dfs.namenode.heartbeat.recheck-interval 大小為5分鐘莱褒,dfs.heartbeat.interval默認為3秒。

需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的單位為毫秒涎劈,dfs.heartbeat.interval的單位為秒广凸。

<property>
    <name>dfs.namenode.heartbeat.recheck-interval</name>
    <value>300000</value>
</property>
<property>
    <name>dfs.heartbeat.interval </name>
    <value>3</value>
</property>
  • DataNode的目錄結構

    和namenode不同的是,datanode的存儲目錄是初始階段自動創(chuàng)建的蛛枚,不需要額外格式化谅海。

在/opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/datanodeDatas/current這個目錄下查看版本號

    cat VERSION 

    #Thu Mar 14 07:58:46 CST 2019
    storageID=DS-47bcc6d5-c9b7-4c88-9cc8-6154b8a2bf39
    clusterID=CID-dac2e9fa-65d2-4963-a7b5-bb4d0280d3f4
    cTime=0
    datanodeUuid=c44514a0-9ed6-4642-b3a8-5af79f03d7a4
    storageType=DATA_NODE
    layoutVersion=-56

具體解釋:

storageID:存儲id號。

clusterID集群id蹦浦,全局唯一扭吁。

cTime屬性標記了datanode存儲系統(tǒng)的創(chuàng)建時間,對于剛剛格式化的存儲系統(tǒng)盲镶,這個屬性為0侥袜;但是在文件系統(tǒng)升級之后,該值會更新到新的時間戳徒河。

datanodeUuid:datanode的唯一識別碼系馆。

storageType:存儲類型。

layoutVersion是一個負整數(shù)顽照。通常只有HDFS增加新特性時才會更新這個版本號由蘑。

  • datanode多目錄配置

datanode也可以配置成多個目錄,每個目錄存儲的數(shù)據(jù)不一樣代兵。即:數(shù)據(jù)不是副本尼酿。具體配置如下:

  • 只需要在value中使用逗號分隔出多個存儲目錄即可
  cd /opt/hadoop-2.6.0-cdh5.14.0/etc/hadoop
  <!--  定義dataNode數(shù)據(jù)存儲的節(jié)點位置,實際工作中植影,一般先確定磁盤的掛載目錄裳擎,然后多個目錄用,進行分割  -->
          <property>
                  <name>dfs.datanode.data.dir</name>
                  <value>file:///opt/hadoop-2.6.0-cdh5.14.0/hadoopDatas/datanodeDatas</value>
          </property>

10.1 服役新數(shù)據(jù)節(jié)點

需求說明:

隨著公司業(yè)務的增長思币,數(shù)據(jù)量越來越大鹿响,原有的數(shù)據(jù)節(jié)點的容量已經(jīng)不能滿足存儲數(shù)據(jù)的需求羡微,需要在原有集群基礎上動態(tài)添加新的數(shù)據(jù)節(jié)點。

10.1.1 環(huán)境準備

  1. 復制一臺新的虛擬機出來

將我們純凈的虛擬機復制一臺出來惶我,作為我們新的節(jié)點

  1. 修改mac地址以及IP地址
修改mac地址命令
    vim /etc/udev/rules.d/70-persistent-net.rules
修改ip地址命令
    vim /etc/sysconfig/network-scripts/ifcfg-eth0
  1. 關閉防火墻妈倔,關閉selinux
關閉防火墻
    service iptables stop
關閉selinux
    vim /etc/selinux/config
  1. 更改主機名
更改主機名命令,將node04主機名更改為node04.hadoop.com
vim /etc/sysconfig/network
  1. 四臺機器更改主機名與IP地址映射
四臺機器都要添加hosts文件
vim /etc/hosts

192.168.52.100 node01.hadoop.com  node01
192.168.52.110 node02.hadoop.com  node02
192.168.52.120 node03.hadoop.com  node03
192.168.52.130 node04.hadoop.com  node04
  1. node04服務器關機重啟
node04執(zhí)行以下命令關機重啟
    reboot -h now
  1. node04安裝jdk
node04統(tǒng)一兩個路徑
    mkdir -p /export/softwares/
    mkdir -p /export/servers/

然后解壓jdk安裝包绸贡,配置環(huán)境變量

  1. 解壓hadoop安裝包
在node04服務器上面解壓hadoop安裝包到/export/servers , node01執(zhí)行以下命令將hadoop安裝包拷貝到node04服務器
    cd /export/softwares/
    scp hadoop-2.6.0-cdh5.14.0-自己編譯后的版本.tar.gz node04:$PWD

node04解壓安裝包
    tar -zxf hadoop-2.6.0-cdh5.14.0-自己編譯后的版本.tar.gz -C /export/servers/
  1. 將node01關于hadoop的配置文件全部拷貝到node04
node01執(zhí)行以下命令盯蝴,將hadoop的配置文件全部拷貝到node04服務器上面
    cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/
    scp ./* node04:$PWD

10.1.2 服役新節(jié)點具體步驟

  1. 創(chuàng)建dfs.hosts文件
在node01也就是namenode所在的機器的/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop目錄下創(chuàng)建dfs.hosts文件

[root@node01 hadoop]# cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
[root@node01 hadoop]# touch dfs.hosts
[root@node01 hadoop]# vim dfs.hosts

添加如下主機名稱(包含新服役的節(jié)點)
node01
node02
node03
node04
  1. node01編輯hdfs-site.xml添加以下配置

在namenode的hdfs-site.xml配置文件中增加dfs.hosts屬性

node01執(zhí)行以下命令 :

cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
vim hdfs-site.xml

# 添加一下內(nèi)容
    <property>
         <name>dfs.hosts</name>
         <value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/dfs.hosts</value>
    </property>
    <!--動態(tài)上下線配置: 如果配置文件中有, 就不需要配置-->
    <property>
        <name>dfs.hosts</name>
        <value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/accept_host</value>
    </property>

    <property>
        <name>dfs.hosts.exclude</name>
        <value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/deny_host</value>
    </property>
  1. 刷新namenode
  • node01執(zhí)行以下命令刷新namenode
[root@node01 hadoop]# hdfs dfsadmin -refreshNodes
Refresh nodes successful
  1. 更新resourceManager節(jié)點
  • node01執(zhí)行以下命令刷新resourceManager
[root@node01 hadoop]# yarn rmadmin -refreshNodes
19/03/16 11:19:47 INFO client.RMProxy: Connecting to ResourceManager at node01/192.168.52.100:8033
  1. namenode的slaves文件增加新服務節(jié)點主機名稱

node01編輯slaves文件,并添加新增節(jié)點的主機听怕,更改完后捧挺,slaves文件不需要分發(fā)到其他機器上面去

node01執(zhí)行以下命令編輯slaves文件 :
    cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
    vim slaves

添加一下內(nèi)容:     
node01
node02
node03
node04
  1. 單獨啟動新增節(jié)點
node04服務器執(zhí)行以下命令,啟動datanode和nodemanager : 
    cd /export/servers/hadoop-2.6.0-cdh5.14.0/
    sbin/hadoop-daemon.sh start datanode
    sbin/yarn-daemon.sh start nodemanager
  1. 使用負載均衡命令尿瞭,讓數(shù)據(jù)均勻負載所有機器
node01執(zhí)行以下命令 : 
    cd /export/servers/hadoop-2.6.0-cdh5.14.0/
    sbin/start-balancer.sh

10.2 退役舊數(shù)據(jù)

  1. 創(chuàng)建dfs.hosts.exclude配置文件

在namenod所在服務器的/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop目錄下創(chuàng)建dfs.hosts.exclude文件闽烙,并添加需要退役的主機名稱

node01執(zhí)行以下命令 : 
    cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
    touch dfs.hosts.exclude
    vim dfs.hosts.exclude
添加以下內(nèi)容:
    node04.hadoop.com

特別注意:該文件當中一定要寫真正的主機名或者ip地址都行,不能寫node04
  1. 編輯namenode所在機器的hdfs-site.xml

編輯namenode所在的機器的hdfs-site.xml配置文件筷厘,添加以下配置

cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
vim hdfs-site.xml

#添加一下內(nèi)容:
    <property>
         <name>dfs.hosts.exclude</name>
         <value>/export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop/dfs.hosts.exclude</value>
   </property>
  1. 刷新namenode鸣峭,刷新resourceManager
在namenode所在的機器執(zhí)行以下命令,刷新namenode酥艳,刷新resourceManager : 

hdfs dfsadmin -refreshNodes
yarn rmadmin -refreshNodes
  1. 節(jié)點退役完成摊溶,停止該節(jié)點進程

等待退役節(jié)點狀態(tài)為decommissioned(所有塊已經(jīng)復制完成),停止該節(jié)點及節(jié)點資源管理器充石。注意:如果副本數(shù)是3莫换,服役的節(jié)點小于等于3,是不能退役成功的骤铃,需要修改副本數(shù)后才能退役拉岁。

node04執(zhí)行以下命令,停止該節(jié)點進程 : 
    cd /export/servers/hadoop-2.6.0-cdh5.14.0
    sbin/hadoop-daemon.sh stop datanode
    sbin/yarn-daemon.sh stop nodemanager
  1. 從include文件中刪除退役節(jié)點
namenode所在節(jié)點也就是node01執(zhí)行以下命令刪除退役節(jié)點 :
    cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
    vim dfs.hosts

刪除后的內(nèi)容: 刪除了node04
node01
node02
node03
  1. node01執(zhí)行一下命令刷新namenode惰爬,刷新resourceManager
hdfs dfsadmin -refreshNodes
yarn rmadmin -refreshNodes
  1. 從namenode的slave文件中刪除退役節(jié)點
namenode所在機器也就是node01執(zhí)行以下命令從slaves文件中刪除退役節(jié)點 : 
    cd /export/servers/hadoop-2.6.0-cdh5.14.0/etc/hadoop
    vim slaves
刪除后的內(nèi)容: 刪除了 node04 
node01
node02
node03
  1. 如果數(shù)據(jù)負載不均衡喊暖,執(zhí)行以下命令進行均衡負載
node01執(zhí)行以下命令進行均衡負載
    cd /export/servers/hadoop-2.6.0-cdh5.14.0/
    sbin/start-balancer.sh

11 block塊手動拼接成為完整數(shù)據(jù)

所有的數(shù)據(jù)都是以一個個的block塊存儲的,只要我們能夠將文件的所有block塊全部找出來撕瞧,拼接到一起陵叽,又會成為一個完整的文件,接下來我們就來通過命令將文件進行拼接:

  1. 上傳一個大于128M的文件到hdfs上面去

我們選擇一個大于128M的文件上傳到hdfs上面去丛版,只有一個大于128M的文件才會有多個block塊巩掺。

這里我們選擇將我們的jdk安裝包上傳到hdfs上面去。

node01執(zhí)行以下命令上傳jdk安裝包

cd /export/softwares/
hdfs dfs -put jdk-8u141-linux-x64.tar.gz  /
  1. web瀏覽器界面查看jdk的兩個block塊id

這里我們看到兩個block塊id分別為

1073742699和1073742700

那么我們就可以通過blockid將我們兩個block塊進行手動拼接了页畦。

  1. 根據(jù)我們的配置文件找到block塊所在的路徑
根據(jù)我們hdfs-site.xml的配置胖替,找到datanode所在的路徑
<!--  定義dataNode數(shù)據(jù)存儲的節(jié)點位置,實際工作中,一般先確定磁盤的掛載目錄独令,然后多個目錄用端朵,進行分割  -->
        <property>
                <name>dfs.datanode.data.dir</name>
                <value>file:///export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/datanodeDatas</value>
        </property>


進入到以下路徑 : 此基礎路徑為 上述配置中value的路徑
cd /export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/datanodeDatas/current/BP-557466926-192.168.52.100-1549868683602/current/finalized/subdir0/subdir3
  • 4. 執(zhí)行block塊的拼接
將不同的各個block塊按照順序進行拼接起來,成為一個完整的文件
cat blk_1073742699 >> jdk8u141.tar.gz
cat blk_1073742700 >> jdk8u141.tar.gz
移動我們的jdk到/export路徑记焊,然后進行解壓
mv  jdk8u141.tar.gz /export/
cd /export/
tar -zxf jdk8u141.tar.gz
正常解壓逸月,沒有問題,說明我們的程序按照block塊存儲沒有問題
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末遍膜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子瓤湘,更是在濱河造成了極大的恐慌瓢颅,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弛说,死亡現(xiàn)場離奇詭異挽懦,居然都是意外死亡,警方通過查閱死者的電腦和手機木人,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門信柿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人醒第,你說我怎么就攤上這事渔嚷。” “怎么了稠曼?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵形病,是天一觀的道長。 經(jīng)常有香客問我霞幅,道長漠吻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任司恳,我火速辦了婚禮途乃,結果婚禮上,老公的妹妹穿的比我還像新娘扔傅。我一直安慰自己耍共,他們只是感情好,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布铅鲤。 她就那樣靜靜地躺著划提,像睡著了一般。 火紅的嫁衣襯著肌膚如雪邢享。 梳的紋絲不亂的頭發(fā)上鹏往,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音,去河邊找鬼伊履。 笑死韩容,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的唐瀑。 我是一名探鬼主播群凶,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼哄辣!你這毒婦竟也來了请梢?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤力穗,失蹤者是張志新(化名)和其女友劉穎毅弧,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體当窗,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡够坐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了崖面。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片元咙。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖巫员,靈堂內(nèi)的尸體忽然破棺而出庶香,到底是詐尸還是另有隱情,我是刑警寧澤疏遏,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布脉课,位于F島的核電站,受9級特大地震影響财异,放射性物質(zhì)發(fā)生泄漏倘零。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一戳寸、第九天 我趴在偏房一處隱蔽的房頂上張望呈驶。 院中可真熱鬧,春花似錦疫鹊、人聲如沸袖瞻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽聋迎。三九已至,卻和暖如春枣耀,著一層夾襖步出監(jiān)牢的瞬間霉晕,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留牺堰,地道東北人拄轻。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像伟葫,于是被迫代替她去往敵國和親恨搓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

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