分布式文件系統(tǒng)HDFS——基礎(chǔ)篇

我們在上一篇《向Hadoop Say Hello——初識Hadoop》中已經(jīng)對HDFS進(jìn)行了簡單介紹砰逻,還不清楚HDFS是什么的朋友可以點(diǎn)擊上面鏈接先看上一篇,在這一篇中我們聚焦HDFS肥缔,從HDFS的設(shè)計(jì)架構(gòu)和重要概念開始學(xué)習(xí),然后會學(xué)習(xí)HDFS的命令行操作以及Java Api操作芙代。

<font color=#dd2c00>特別提示:本文所進(jìn)行的演示都是在hadoop-2.6.0-cdh5.15.1的版本進(jìn)行的</font>

一鼓黔、HDFS概述

HDFS 是 Hadoop Distribute File System,Hadoop分布式文件系統(tǒng)的簡稱谎脯。這個(gè)文件系統(tǒng)是一個(gè)適用于大的數(shù)據(jù)集的支持高吞吐和高容錯(cuò)的運(yùn)行在通用(廉價(jià))機(jī)上的分布式文件系統(tǒng)葱跋。

設(shè)計(jì)目標(biāo)

  • 故障的快速檢測和自動恢復(fù)(容錯(cuò))

分布式的文件系統(tǒng)將由成百上千臺的機(jī)器共同組成集群,在集群中每一臺機(jī)器都可能出現(xiàn)故障,當(dāng)出現(xiàn)部分機(jī)器出現(xiàn)故障時(shí)娱俺,保證服務(wù)的正常提供是一個(gè)重要的工作稍味,因此故障的快遞檢測和自動快速恢復(fù)是 HDFS 的核心設(shè)計(jì)目標(biāo)

  • 流式數(shù)據(jù)訪問(高吞吐)

HDFS 的設(shè)計(jì)是為了存儲大文件,它更注重?cái)?shù)據(jù)訪問的吞吐量荠卷,對訪問的延時(shí)性要求較低模庐,它不適用于低延時(shí)的場景,為了保證大吞吐量的數(shù)據(jù)訪問油宜,HDFS 被設(shè)計(jì)成了更適合批量處理掂碱,且以流式讀取數(shù)據(jù)的方式

  • 存儲大的數(shù)據(jù)集

通常情況下在HDFS上運(yùn)行的應(yīng)用都具有大的數(shù)據(jù)集,一個(gè)典型的 HDFS 文件大小是 GB 到 TB 的級別慎冤,在實(shí)際中超大型集群的HDFS中文件的大小也可能達(dá)到PB級別

  • 簡化數(shù)據(jù)一致性模型

大部分運(yùn)行在 HDFS 上的應(yīng)用對文件都是"一次寫入疼燥,多次讀出"訪問模型。所以HDFS就作出了一個(gè)文件一旦創(chuàng)建粪薛、寫入成功后就不需要再修改了的假設(shè)悴了,這一假設(shè)簡化了數(shù)據(jù)一致性問題,使高吞吐量的數(shù)據(jù)訪問成為可能(后文會分析HDFS的數(shù)據(jù)一致性問題)

  • 移動計(jì)算的位置比移動數(shù)據(jù)的位置更劃算

由于網(wǎng)絡(luò)帶寬是一個(gè)有限資源违寿,一個(gè)計(jì)算任務(wù)的運(yùn)行湃交,當(dāng)計(jì)算數(shù)據(jù)離計(jì)算邏輯所在節(jié)點(diǎn)越近這個(gè)計(jì)算任務(wù)執(zhí)行的就越高效,數(shù)據(jù)量越大這種特點(diǎn)就越明顯藤巢。所以在 HDFS 中設(shè)計(jì)了提供給應(yīng)用將計(jì)算邏輯移動到數(shù)據(jù)附近這樣的接口

  • 可移植性

為了方便HDFS作為大規(guī)模數(shù)據(jù)應(yīng)用平臺得到廣泛應(yīng)用搞莺,HDFS被設(shè)計(jì)成了一個(gè)易于從一個(gè)平臺移植到另一個(gè)平臺的數(shù)據(jù)應(yīng)用系統(tǒng)

二、HDFS中一些概念

Block(塊)

HDFS和一般的磁盤文件系統(tǒng)一樣掂咒,也有Block的概念才沧,和一般文件相同的是,用戶存儲的文件都會被按照Block Size被拆分存儲绍刮,但與一般磁盤文件系統(tǒng)不同的是温圆,當(dāng)一個(gè)文件的實(shí)際大小比Block Size小的時(shí)候,它不會占用Block Size大小的物理空間孩革。這句話如何理解呢岁歉?

咱們舉個(gè)栗子,HDFS的默認(rèn)塊大小是128M,假設(shè)現(xiàn)在有一個(gè)200M的文件那么存儲在HDFS上時(shí)就會被拆分成兩個(gè)Block存儲膝蜈,分別是一個(gè)128M的塊和一個(gè)72M的塊锅移,且他們占用的物理空間也是200M。而在一般的磁盤文件系統(tǒng)中塊的大小是4K饱搏,不同點(diǎn)就是如果一個(gè)文件大小是5K那么它存儲在磁盤文件系統(tǒng)中所占用的物理空間大小是8k非剃,在一般磁盤文件系統(tǒng)中文件大小沒有超過一個(gè)塊大小時(shí),是按照一個(gè)塊的大小占用空間推沸。

文件系統(tǒng)命名空間

HDFS和傳統(tǒng)的文件系統(tǒng)一樣支持分層的文件組織結(jié)構(gòu)备绽。支持常用的文件創(chuàng)建券坞,刪除、移動疯坤,重命名等操作报慕,并且也支持用戶配額和訪問權(quán)限控制。現(xiàn)有的HDFS實(shí)現(xiàn)不支持硬鏈接或軟鏈接压怠。

副本機(jī)制

為了容錯(cuò)眠冈,每個(gè)文件被拆分后的 Block 都是以副本的方式存儲,每個(gè)文件的塊大小和以及復(fù)制的副本系數(shù)都是可以配置菌瘫,HDFS 默認(rèn)是3副本配置蜗顽。

在集群中副本的放置位置對HDFS的可靠性和性能都有很大的影響,所以優(yōu)化副本擺放策略在一個(gè)大型集群中顯得尤為重要雨让。在HDFS中是使用一種機(jī)架感知的副本放置策略雇盖,這種策略是基于提高數(shù)據(jù)可靠性、可用性和網(wǎng)絡(luò)帶寬利用率而設(shè)計(jì)的一種策略

在機(jī)架感知副本策略下栖忠,當(dāng)副本系數(shù)是3時(shí)崔挖,HDFS的文件副本放置方式如下:如果寫入程序位于數(shù)據(jù)節(jié)點(diǎn)上,則將一個(gè)副本放在本地計(jì)算機(jī)上庵寞,否則放在與寫入程序位于同一機(jī)架中的隨機(jī)數(shù)據(jù)節(jié)點(diǎn)上狸相,另一個(gè)副本放在不同(遠(yuǎn)程)機(jī)架中的節(jié)點(diǎn)上,最后一個(gè)放在同一遠(yuǎn)程機(jī)架中的不同節(jié)點(diǎn)上捐川。

二脓鹃、HDFS的架構(gòu)

HDFS 是一個(gè)主從架構(gòu)的服務(wù)。一個(gè) HDFS 集群包括一個(gè) NameNode 節(jié)點(diǎn)古沥、一個(gè) SecondaryNameNode 節(jié)點(diǎn)(非必須)和多個(gè) DataNode 節(jié)點(diǎn)瘸右。

NameNode

NameNode是一個(gè)主節(jié)點(diǎn),是所有 HDFS 元數(shù)據(jù)的決策器和存儲庫岩齿,它管理文件系統(tǒng)名稱空間太颤、確定塊到數(shù)據(jù)節(jié)點(diǎn)的映射,并且控制客戶端對文件的訪問盹沈。但是 NameNode 從不與用戶數(shù)據(jù)直接交互栋齿,與用戶數(shù)據(jù)交互的工作都由DataNode 來做。

DataNode

DataNode是管理它們運(yùn)行的節(jié)點(diǎn)的數(shù)據(jù)存儲襟诸,通常一個(gè)集群中每個(gè)節(jié)點(diǎn)一個(gè)都有一個(gè) DataNode。DataNode 負(fù)責(zé)為來自客戶端的讀寫請求提供服務(wù)基协,同時(shí)它還會根據(jù) NameNode 的指令執(zhí)行塊創(chuàng)建歌亲、刪除和復(fù)制。

SecondaryNameNode

SecondaryNameNode是NameNode的一個(gè)冷備份澜驮,可以看做是一個(gè)CheckPoint陷揪,它主要負(fù)責(zé)合并 fsimage 和 fsedits,并推送給 NameNode。它也會維護(hù)一個(gè)合并后的 Namespace Image 副本悍缠, 可用于在 NameNode 故障后恢復(fù)數(shù)據(jù)

架構(gòu)圖

接下來咱們可以看下面這張圖(圖片來自Hadoop官網(wǎng))卦绣,這就是HDFS的一個(gè)架構(gòu)圖

圖中的幾個(gè)要點(diǎn):

  • NameNode管理著Metadata(元數(shù)據(jù))

  • 客戶端client對元數(shù)據(jù)的操作是指向NameNode,對用戶數(shù)據(jù)的讀寫是通過DataNode

  • NameNode向DataNode發(fā)送Block的操作命令

  • 一塊的副本被存儲在不同的機(jī)架中

HDFS Federation

通過了解架構(gòu)大家是否發(fā)現(xiàn)了一個(gè)問題飞蚓?在 HDFS 的主從架構(gòu)中 NameNode 成了集群擴(kuò)大的瓶頸滤港,隨著集群增大和文件數(shù)據(jù)量增多,單個(gè) NameNode 性能就無法滿足需求趴拧,這也就意味著溅漾,HDFS 集群的大小是受 NameNode 節(jié)點(diǎn)約束的。

HDFS Federation( HDFS 聯(lián)邦)就是為了解決這種問題著榴,它提供了一種橫向擴(kuò)展 NameNode 的方式添履。在 Federation 模式中,每個(gè) NameNode 管理命名空間的一部分脑又,同時(shí)也各自維護(hù)一個(gè) Block Pool暮胧,保存 Block 的節(jié)點(diǎn)映射信息。各 NameNode 節(jié)點(diǎn)之間是獨(dú)立的问麸,一個(gè)節(jié)點(diǎn)的失敗不會導(dǎo)致其他節(jié)點(diǎn)管理的文件不可用往衷,同時(shí)失敗的節(jié)點(diǎn)所管理的文件數(shù)據(jù)也就不可訪問,所以 HDFS Federation 只是解決 HDFS 的拓展問題口叙,并不是解決單點(diǎn)故障問題的炼绘。

四、HDFS的安裝和使用

在剛開始學(xué)習(xí)的過程中建議先使用單機(jī)版妄田,避免因?yàn)榧旱膯栴}提高了學(xué)習(xí)門檻俺亮,打擊自己學(xué)習(xí)信心,在熟練其使用和原理后在使用集群也不遲疟呐。

HDFS的安裝可以參照《教你安裝單機(jī)版Hadoop》,這篇文章里面有講述HFDS的安裝脚曾。

HDFS安裝成功后如下操作

  • 第一次啟動前需要對文件系統(tǒng)進(jìn)行格式化:${HADOOP_HOME}/bin/hdfs name -format

  • 啟動HDFS:${HADOOP_HOME}/sbin/start-dfs.sh

在HDFS啟動后,我們就可以訪問 HDFS 的 Web 頁面启具,查看HDFS的信息本讥,HDFS web 訪問默認(rèn)端口是50070,瀏覽器打開效果如下:

首頁是一個(gè)Overview概覽信息鲁冯,里面包括了集群基本信息(Hadoop版本拷沸、集群ID、Block Pool ID等)薯演、存儲摘要以及NameNode的運(yùn)行狀態(tài)等撞芍。

在頂部第二個(gè)主菜單下是DataNode的信息,頁面效果如下:

在主菜單的最后一項(xiàng)Utilities下面有一個(gè)Browse the file system跨扮,這個(gè)頁面就是HDFS的一個(gè)文件瀏覽器序无,可以查看在HDFS上存儲的文件验毡,效果如下:

四、HDFS基本操作(命令和Java Api)

HDFS 包含的常用操作如下

命令操作

HDFS的命令有兩種使用方式

  • 通過hadoop命令:hadoop fs [options]帝嗡,eg:./hadoop fs -ls /

  • 通過hdfs命令:hdfs dfs [options],eg:./hdfs dfs -ls /

其實(shí)兩種方法調(diào)用的是相同的腳本代碼晶通。

常用命令中有一部分是類似于Linux的文件管理命令,對于這一部分命令可以類比Linux中的使用哟玷,我們就不講解了狮辽,我們只把HDFS中一些特別的命令學(xué)習(xí)一下。

類似Linux系統(tǒng)的文件管理命令有:<font color=#00bfa5>ls, cat, chgrp, chmod, chown, cp, df, du, find, mkdir, mv, rm, rmdir, tail, test</font>

我們學(xué)習(xí)一下這些命令:

  • appendToFile:將一個(gè)或者多個(gè)文件添加到HDFS系統(tǒng)中

  • copyFromLocal:將本地文件拷貝到HDFS

  • count:統(tǒng)計(jì)hdfs對應(yīng)路徑下的目錄個(gè)數(shù)碗降,文件個(gè)數(shù)隘竭,文件總計(jì)大小

  • expunge:從垃圾箱目錄永久刪除超過保留閾值的檢查點(diǎn)中的文件,并創(chuàng)建新檢查點(diǎn)

  • get:從HDFS上傳輸文件到本地

  • getmerge:把hdfs指定目錄下的所有文件內(nèi)容合并到本地linux的文件中

  • moveFromLocal:把本地文件移動到HDFS上讼渊,本地文件會被刪除

  • moveToLocal:把HDFS文件移動到本地动看,HDFS文件會被刪除

  • put:將文件上傳到HDFS上

  • setrep:修改文件或目錄副本數(shù)

  • stat:輸出指定目錄的信息,可設(shè)置格式化輸出(%b: 文件大小爪幻,%n: 文件名菱皆,%o: 塊大小,%r: 副本個(gè)數(shù)挨稿,%y, %Y: 修改日期)

  • text:格式化輸出文件的內(nèi)容仇轻,允許的格式化包括zip,和 TextRecordInputStream

  • touchz:在指定目錄創(chuàng)建一個(gè)新文件,如果文件存在奶甘,則創(chuàng)建失敗

Hadoop的文件系統(tǒng)

在使用Java的Api前我們現(xiàn)先了解一下Hadoop的抽象文件系統(tǒng)

org.apache.hadoop.fs.FileSystem 是Hadoop中抽象的一個(gè)文件系統(tǒng)篷店,我們今天所使用的HDFS只是這個(gè)抽象的文件系統(tǒng)的實(shí)現(xiàn)之一,HDFS提供了幾個(gè)主要的實(shí)現(xiàn)包括:LocalFileSystem臭家、 DistributeFileSystem疲陕、 WebHdfsFileSystem、 HarFileSystem钉赁、 ViewFileSystem蹄殃、 FtpFileSystem、 S3AFileSystem

  • LocalFileSystem:對本地文件系統(tǒng)的一個(gè)實(shí)現(xiàn)

  • DistributeFileSystem:HDFS的實(shí)現(xiàn)

  • WebHdfsFileSystem:通過Http請求提供對HDFS的認(rèn)證和讀寫操作的實(shí)現(xiàn),還有一個(gè)SWebHdfsFileSystem是基于Https的實(shí)現(xiàn)

  • HarFileSystem:這是Hadoop存檔文件系統(tǒng)的實(shí)現(xiàn)你踩,歸檔后的多個(gè)文件可以進(jìn)行壓縮成一個(gè)文件

  • ViewFileSystem:視圖文件系統(tǒng)诅岩,只是邏輯上唯一的一個(gè)視圖文件系統(tǒng),主要是來做HDFS Federation的時(shí)候带膜,將不同集群中的文件系統(tǒng)進(jìn)行映射吩谦,在邏輯上形成一個(gè)文件系統(tǒng),在客戶端屏蔽底層細(xì)節(jié)

  • FtpFileSystem:基于ftp協(xié)議的一個(gè)文件系統(tǒng)實(shí)現(xiàn)

  • S3AFileSystem: 基于S3A協(xié)議的一個(gè)文件系統(tǒng)實(shí)現(xiàn)膝藕,S3是Amazon的對象存儲服務(wù)

Java Api

  • pom中加入hadoop-client依賴

<repositories>
<!--使用的Hadoop是CDH版本的需要引用一下cloudera的倉庫庫-->
    <repository>
        <id>cloudera</id>
        <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
    </repository>
</repositories>

<dependencies>
    <!--Hadoop客戶端-->
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>2.6.0-cdh5.15.1</version>
    </dependency>
</dependencies>
    
  • 一個(gè)簡單的演示代碼

package site.teamo.learning.hdfs;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

import java.io.Closeable;
import java.io.IOException;

public class HdfsApp {

    /**
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {

        FileSystem fs = null;

        try {
            //創(chuàng)建配置逮京,設(shè)置Hdfs的地址信息
            Configuration configuration = new Configuration();
            configuration.set("fs.defaultFS", "hdfs://hdh100:8020");
            //在系統(tǒng)環(huán)境變量設(shè)置使用的用戶名
            System.setProperty("HADOOP_USER_NAME", "root");

            //打開一個(gè)文件系統(tǒng)
            fs = FileSystem.get(configuration);

            //創(chuàng)建一個(gè)目錄
            fs.mkdirs(new Path("/dream-hammer"));

            //判斷是否是目錄
            fs.isDirectory(new Path("/dream-hammer"));

            //創(chuàng)建一個(gè)文件dream1.txt,返回值boolean類型束莫,true:創(chuàng)建成功懒棉;false:創(chuàng)建失敗
            fs.createNewFile(new Path("/dream-hammer/dream1.txt"));

            //判斷文件是否存在,返回值是boolean類型览绿,true:存在策严;false:不存在
            fs.exists(new Path("/dream-hammer/dream1.txt"));

            //向文件追加內(nèi)容
            FSDataOutputStream out = null;
            try {
                out = fs.append(new Path("/dream-hammer/dream1.txt"));
                out.writeUTF("dream-hammer");
                out.flush();
                out.close();
            } finally {
                close(out);
            }

            //打開dream1的輸入流

            FSDataInputStream in = null;
            try {
                in = fs.open(new Path("/dream-hammer/dream1.txt"));
                System.out.println(in.readUTF());
                in.close();
            } finally {
                close(in);
            }

            //刪除目錄和文件
            fs.delete(new Path("/dream-hammer"), true);
        } finally {
            close(fs);
        }

    }

    /**
     * 關(guān)閉流,釋放資源
     * @param closeable
     */
    public static void close(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}


** 總結(jié) ** :這篇文章主要是對HDFS的基礎(chǔ)理論知識進(jìn)行了介紹和說明饿敲,同時(shí)也介紹了HDFS的基本使用妻导,比較基礎(chǔ)易懂,也適合剛接觸HDFS的朋友閱讀學(xué)習(xí)怀各,錘子會在下一篇文章里面介紹 HDFS讀寫數(shù)據(jù)流程倔韭,這個(gè)屬于更深層次的東西了,關(guān)注【愛做夢的錘子】瓢对,一起學(xué)習(xí)進(jìn)步

文章歡迎轉(zhuǎn)載寿酌,轉(zhuǎn)載請注明出處,個(gè)人公眾號【愛做夢的錘子】硕蛹,全網(wǎng)同id醇疼,個(gè)站 http://te-amo.site,歡迎關(guān)注法焰,里面會分享更多有用知識秧荆,還有我的私密照片

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市埃仪,隨后出現(xiàn)的幾起案子乙濒,更是在濱河造成了極大的恐慌,老刑警劉巖卵蛉,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颁股,死亡現(xiàn)場離奇詭異,居然都是意外死亡毙玻,警方通過查閱死者的電腦和手機(jī)豌蟋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桑滩,“玉大人梧疲,你說我怎么就攤上這事≡俗迹” “怎么了幌氮?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長胁澳。 經(jīng)常有香客問我该互,道長,這世上最難降的妖魔是什么韭畸? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任宇智,我火速辦了婚禮蔓搞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘随橘。我一直安慰自己喂分,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布机蔗。 她就那樣靜靜地躺著蒲祈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪萝嘁。 梳的紋絲不亂的頭發(fā)上梆掸,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天,我揣著相機(jī)與錄音牙言,去河邊找鬼酸钦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛嬉挡,可吹牛的內(nèi)容都是我干的钝鸽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼庞钢,長吁一口氣:“原來是場噩夢啊……” “哼拔恰!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起基括,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤颊郎,失蹤者是張志新(化名)和其女友劉穎句葵,沒想到半個(gè)月后呐籽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體璃谨,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年桐款,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咸这。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,643評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡魔眨,死狀恐怖媳维,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情遏暴,我是刑警寧澤侄刽,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站朋凉,受9級特大地震影響州丹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一墓毒、第九天 我趴在偏房一處隱蔽的房頂上張望吓揪。 院中可真熱鬧,春花似錦蚁鳖、人聲如沸磺芭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至徙垫,卻和暖如春讥裤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姻报。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工己英, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吴旋。 一個(gè)月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓损肛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親荣瑟。 傳聞我的和親對象是個(gè)殘疾皇子治拿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評論 2 348