Hadoop框架基礎(chǔ)(五)

** Hadoop框架基礎(chǔ)(五)

已經(jīng)部署了Hadoop的完全分布式集群,我們知道NameNode節(jié)點(diǎn)的正常運(yùn)行對(duì)于整個(gè)HDFS系統(tǒng)來說非常重要什荣,如果NameNode宕掉了琅翻,那么整個(gè)HDFS就要整段垮掉了诺祸,所以人類思考,能不能讓世界多一點(diǎn)愛:)获询,我們能不能弄個(gè)備用的NameNode涨岁,一旦正在使用的NameNode原地爆炸了,另一臺(tái)備用的NameNode能立刻代替原先NameNode的位置吉嚣,繼續(xù)讓HDFS系統(tǒng)正常運(yùn)行卵惦?(同理,ResourceManager也是可以的瓦戚。)

世界果然充滿愛沮尿,動(dòng)物管理員橫空出世——zookeeper框架

** ZooKeeper

這個(gè)框架的翻譯為動(dòng)物園管理員,想想其實(shí)是有道理的较解,大數(shù)據(jù)領(lǐng)域畜疾,Hadoop框架是大象,Hive框架是蜜蜂(為啥是個(gè)大象頭哎喂印衔?)啡捶,Pig框架是豬,都是人類的好朋友奸焙,所以有個(gè)動(dòng)物管理員也不差異瞎暑。接下來簡(jiǎn)單介紹一下zookeeper框架。

** zookeeper功能:

* 統(tǒng)一命名服務(wù)(Name Service)

* 配置管理(Configuration Management)

* 集群管理(Group Membership)

* 共享鎖(Locks)/同步鎖

** zookeeper簡(jiǎn)述:

apache開源項(xiàng)目与帆,提供分布式集群了赌,屬于Hadoop底下的一個(gè)分支,為分布式應(yīng)用提供協(xié)調(diào)服務(wù)玄糟,官方網(wǎng)站:zookeeper.apache.org勿她,zookeeper服務(wù)器為奇數(shù)個(gè),即2n+1個(gè)服務(wù)器阵翎,允許有n個(gè)機(jī)器宕機(jī)逢并,不影響整個(gè)系統(tǒng)的運(yùn)行。比如:3臺(tái)機(jī)器郭卫,其中有1臺(tái)機(jī)器宕機(jī)砍聊,且存活的Server的數(shù)目不得少于n+1.盾沫,不會(huì)影響整個(gè)系統(tǒng)運(yùn)行吊洼。 zookeeper集群會(huì)選擇出一個(gè)leader服務(wù)器,其他服務(wù)器角色是follower瞧甩,它使用的FastLeaderELection選舉算法是類fast paoxs的算法(有興趣的可以周邊查閱下)谓形,投票數(shù)量結(jié)果過半的服務(wù)器選為leader服務(wù)器灶伊。

** zookeeper原理簡(jiǎn)述

當(dāng)leader崩潰或者leader失去大多數(shù)的follower,這時(shí)候zookeeper進(jìn)入恢復(fù)模式寒跳,恢復(fù)模式需要重新選舉出一個(gè)新的leader聘萨,讓所有的Server都恢復(fù)到一個(gè)正確的狀態(tài),系統(tǒng)默認(rèn)的選舉算法為fast paxos童太。

** zookeeper的Fast Leader選舉機(jī)制

首先介紹幾個(gè)概念

服務(wù)器ID

比如有三臺(tái)服務(wù)器米辐,編號(hào)分別是1,2,3胸完。

編號(hào)越大在選擇算法中的權(quán)重越大。

數(shù)據(jù)ID

服務(wù)器中存放的最大數(shù)據(jù)ID.

值越大說明數(shù)據(jù)越新翘贮,在選舉算法中數(shù)據(jù)越新權(quán)重越大赊窥。

邏輯時(shí)鐘

或者叫投票的輪數(shù),同一輪投票過程中的邏輯時(shí)鐘值是相同的狸页。每投完一輪票這個(gè)數(shù)據(jù)就會(huì)增加锨能,然后與接收到的其它服務(wù)器返回的投票信息中的數(shù)值相比,根據(jù)不同的值做出不同的判斷芍耘。

選舉狀態(tài)

LOOKING址遇,競(jìng)選狀態(tài)。

FOLLOWING斋竞,隨從狀態(tài)倔约,同步leader狀態(tài),參與投票坝初。

OBSERVING浸剩,觀察狀態(tài),同步leader狀態(tài),不參與投票鳄袍。

LEADING绢要,領(lǐng)導(dǎo)者狀態(tài)。

選舉消息內(nèi)容

在投票完成后畦木,需要將投票信息發(fā)送給集群中的所有服務(wù)器袖扛,它包含如下內(nèi)容。

服務(wù)器ID

數(shù)據(jù)ID

邏輯時(shí)鐘(或者理解為選舉輪數(shù)十籍,從0開始遞增)

選舉狀態(tài)

開始投票:

1、恢復(fù)數(shù)據(jù)

zookeeper服務(wù)器中的每份數(shù)據(jù)唇礁,都有一個(gè)對(duì)應(yīng)的id值勾栗,這個(gè)值是依次遞增的,越新的數(shù)據(jù)盏筐,對(duì)應(yīng)的ID值就越大围俘,所以先把數(shù)據(jù)恢復(fù)到最新。

2琢融、廣播投票到其他服務(wù)器

恢復(fù)數(shù)據(jù)到最新之后界牡,每個(gè)zookeeper服務(wù)器發(fā)送自己選舉的leader(嶄新狀態(tài)首次投票推選自己),這個(gè)協(xié)議中包含了以下幾部分的數(shù)據(jù):

* 當(dāng)前的服務(wù)器的id漾抬,即sid

* 當(dāng)前服務(wù)器的最大的數(shù)據(jù)id宿亡,這個(gè)值大的服務(wù)器,說明存放了更新的數(shù)據(jù).

* 當(dāng)前服務(wù)器本次的邏輯時(shí)鐘的值

* 當(dāng)前機(jī)器的選舉狀態(tài)

3纳令、接收其他服務(wù)器的廣播

每個(gè)服務(wù)器將自己的數(shù)據(jù)(以上4個(gè))廣播給其他服務(wù)器挽荠,同時(shí)也接收其他服務(wù)器廣播過來的數(shù)據(jù)克胳,之后:

如果所接收數(shù)據(jù)中服務(wù)器的狀態(tài)還是在選舉階段(LOOKING 狀態(tài)),那么首先判斷邏輯時(shí)鐘值圈匆,又分為以下三種情況:

* 如果發(fā)送過來的邏輯時(shí)鐘大于目前的邏輯時(shí)鐘漠另,那么說明這次選舉更加的新,此時(shí)需要更新一下本機(jī)的邏輯時(shí)鐘值跃赚,同時(shí)將之前收集到的來自其他服務(wù)器的選舉清空笆搓,因?yàn)檫@些數(shù)據(jù)已經(jīng)過期了。然后判斷是否需要更新當(dāng)前自己的選舉情況纬傲。在這里是根據(jù)選舉sid和保存的最大數(shù)據(jù)id來進(jìn)行判斷的砚作,這兩種數(shù)據(jù)之間對(duì)這個(gè)選舉結(jié)果的影響的權(quán)重關(guān)系是:首先看數(shù)據(jù)id,數(shù)據(jù)id大者勝出嘹锁;其次再判斷sid葫录,sid大者勝出。然后再將自身最新的選舉結(jié)果廣播給其他服務(wù)器领猾。

* 如果發(fā)送過來數(shù)據(jù)的邏輯時(shí)鐘小于本機(jī)的邏輯時(shí)鐘米同,說明對(duì)方在一個(gè)相對(duì)較早的選舉進(jìn)程中,此時(shí)只需要發(fā)送自己的選舉數(shù)據(jù)即可摔竿。

* 兩邊的邏輯時(shí)鐘相同面粮,此時(shí)只需要判斷是否需要更新本機(jī)的數(shù)據(jù),如果更新了再將自己最新的選舉結(jié)果廣播出去就是了继低。

然后再處理兩種情況:

* 服務(wù)器判斷是不是已經(jīng)收集到了所有服務(wù)器的選舉狀態(tài)熬苍,如果是,那么這臺(tái)服務(wù)器選舉的leader就定下來了袁翁,然后根據(jù)選舉結(jié)果設(shè)置自己的角色(FOLLOWING還是LEADER)柴底,選舉結(jié)束。

* 即使沒有收集到所有服務(wù)器的選舉狀態(tài)粱胜,也可以根據(jù)該節(jié)點(diǎn)上選擇的最新的leader是不是得到了超過半數(shù)以上服務(wù)器的支持柄驻,如果是,那么當(dāng)前線程將被阻塞等待一段時(shí)間(這個(gè)時(shí)間在finalizeWait定義)看看是不是還會(huì)收到當(dāng)前l(fā)eader的數(shù)據(jù)更優(yōu)的leader焙压,如果經(jīng)過一段時(shí)間還沒有這個(gè)新的leader提出來鸿脓,那么這臺(tái)服務(wù)器最終的leader就確定了,否則進(jìn)行下一次選舉涯曲。

?如果所接收服務(wù)器不在選舉狀態(tài),也就是在FOLLOWING或者LEADING狀態(tài)做以下兩個(gè)判斷:

* 如果邏輯時(shí)鐘相同野哭,將該數(shù)據(jù)保存到recvset,如果所接收服務(wù)器宣稱自己是leader幻件,那么將判斷是不是有半數(shù)以上的服務(wù)器選舉它拨黔,如果是則設(shè)置選舉狀態(tài),選舉結(jié)束傲武。

* 否則這是一條與當(dāng)前邏輯時(shí)鐘不符合的消息蓉驹,那么說明在另一個(gè)選舉過程中已經(jīng)有了選舉結(jié)果城榛,于是將該選舉結(jié)果加入到集合中,再根據(jù)集合來判斷是否可以結(jié)束選舉态兴,如果可以也是保存邏輯時(shí)鐘狠持,設(shè)置選舉狀態(tài),選舉結(jié)束瞻润。

原理引用網(wǎng)絡(luò)上的一張圖喘垂,如圖所示:

在此舉個(gè)例子:假設(shè)有5臺(tái)機(jī)器

服務(wù)器1啟動(dòng),給自己投票绍撞,然后發(fā)投票信息正勒,由于其它機(jī)器還沒有啟動(dòng)所以它收不到反饋信息,服務(wù)器1的狀態(tài)一直屬于Looking傻铣。

服務(wù)器2啟動(dòng)章贞,給自己投票,同時(shí)與之前啟動(dòng)的服務(wù)器1交換結(jié)果非洲,由于服務(wù)器2的編號(hào)大所以服務(wù)器2勝出鸭限,但此時(shí)投票數(shù)沒有大于半數(shù),所以兩個(gè)服務(wù)器的狀態(tài)依然是LOOKING两踏。

服務(wù)器3啟動(dòng)败京,給自己投票,同時(shí)與之前啟動(dòng)的服務(wù)器1梦染,2交換信息赡麦,由于服務(wù)器3的編號(hào)最大所以服務(wù)器3勝出,此時(shí)投票數(shù)正好大于半數(shù)帕识,所以服務(wù)器3成為leader泛粹,服務(wù)器1,2成為follower渡冻。

服務(wù)器4啟動(dòng)戚扳,給自己投票,同時(shí)與之前啟動(dòng)的服務(wù)器1族吻,2,3交換信息珠增,盡管服務(wù)器4的編號(hào)大超歌,但之前服務(wù)器3已經(jīng)勝出,所以服務(wù)器4只能成為follower蒂教。

服務(wù)器5啟動(dòng)巍举,后面的邏輯同服務(wù)器4成為follower。

zookeeper安裝:

* 下載地址傳送門:

zookeeper下載:鏈接:http://pan.baidu.com/s/1o78IBsY 密碼:xh3k

* 解壓到modules目錄中

* 修改配置文件(cp -a命令意為保留原文件屬性的情況下凝垛,復(fù)制文件)

復(fù)制conf目錄下的zoo_sample.cfg文件并重命名為zoo.cfg文件

$ cp -a zoo_sample.cfg zoo.cfg懊悯,執(zhí)行后蜓谋,如圖:

對(duì)文件做如下修改:

$ vi zoo.cfg

dataDir=/opt/modules/zookeeper-3.4.5/zkData, 如圖:

創(chuàng)建這個(gè)目錄:

$ mkdir /opt/modules/zookeeper-3.4.5/zkData

* 啟動(dòng)zookeeper

單節(jié)點(diǎn)啟動(dòng)炭分,切換到zookeeper的安裝根目錄:

$ bin/zkServer.sh start

查看啟動(dòng)狀態(tài):

$ bin/zkServer.sh status桃焕,如圖:

** zookeeper集群的部署

集群規(guī)劃如下:

* 修改zoo.cfg

dataDir=/opt/modules/zookeeper-3.4.5/zkData

server.1=192.168.122.200:2888:3888

server.2=192.168.122.201:2888:3888

server.3=192.168.122.202:2888:3888

注意:這里我使用的是三臺(tái)服務(wù)器的ip地址,如圖:

* 添加myid文件捧毛,注意一定要在linux里面創(chuàng)建

$ vi zkData/myid

添加內(nèi)容:1

* 把zookeeper目錄拷貝給其他集群服務(wù)器

$ scp -r zookeeper-3.4.5/ z02:/opt/modules/

$ scp -r zookeeper-3.4.5/ z03:/opt/modules/

修改myid文件

z02 為 2

z03 為 3

* 依次啟動(dòng)所有集群服務(wù)

$ bin/zkServer.sh start

* 檢查每個(gè)服務(wù)器的狀態(tài)

$ bin/zkServer.sh status

一頓操作之后观堂,如圖:通過查看狀態(tài),可以發(fā)現(xiàn)呀忧,現(xiàn)在的leader服務(wù)器是z02师痕,其他的服務(wù)器為follower。

** NameNode的HA部署

目標(biāo): 防止單個(gè)namenode宕機(jī)以后,整個(gè)HDFS集群失效

集群規(guī)劃:

注意:建議配置之前把之前服務(wù)器配置備份一次,方便以后使用

$ cp -ra hadoop-2.5.0/ back-up-hadoop-2.5.0/而账,如圖:

* 配置core-site.xml胰坟,如圖:


* 配置:hdfs-site.xml,如圖:

* 拷貝文件給其他服務(wù)器

刪除三臺(tái)服務(wù)器的數(shù)據(jù)目錄泞辐,去每個(gè)機(jī)器上執(zhí)行該命令:

$ rm -rf data/ ?

拷貝給其他兩臺(tái)服務(wù)器:

$ scp etc/hadoop/core-site.xml etc/hadoop/hdfs-site.xml ?z02:/opt/modules/hadoop-2.5.0/etc/hadoop/

$ scp etc/hadoop/core-site.xml etc/hadoop/hdfs-site.xml? z03:/opt/modules/hadoop-2.5.0/etc/hadoop/

* 啟動(dòng)服務(wù)

* 在各個(gè)JournalNode節(jié)點(diǎn)上笔横,輸入以下命令啟動(dòng)journalnode服務(wù):

$ sbin/hadoop-daemon.sh start journalnode

* 在[nn1]上,對(duì)其進(jìn)行格式化铛碑,并啟動(dòng)

$ bin/hdfs namenode -format

$ sbin/hadoop-daemon.sh start namenode

* 在[nn2]上狠裹,同步nn1的元數(shù)據(jù)信息,并啟動(dòng)

$ bin/hdfs namenode -bootstrapStandby

$ sbin/hadoop-daemon.sh start namenode

* 在nn1中與nn2中查看jps進(jìn)程如下圖:

* 瀏覽器瀏覽汽烦,以下兩個(gè)地址均可以訪問HDFS:

http://z01:50070/

http://z02:50070/

* 手動(dòng)把nn1設(shè)置為active

$ bin/hdfs haadmin -transitionToActive nn1

以上為手動(dòng)故障轉(zhuǎn)移涛菠,如果我們想自動(dòng)切換故障,需要進(jìn)行如下配置撇吞,即開啟故障自動(dòng)轉(zhuǎn)移功能

*關(guān)閉所有HDFS服務(wù)

在[nn1]執(zhí)行:

$ sbin/stop-dfs.sh俗冻,如圖:

配置core-site.xml

添加屬性:

ha.zookeeper.quorum:z01:2181,z02:2181,z03:2181

配置hdfs-site.xml

添加屬性:

dfs.ha.automatic-failover.enabled.mycluster:true

* 拷貝文件給后面兩臺(tái)服務(wù)器

$ scp etc/hadoop/core-site.xml etc/hadoop/hdfs-site.xml z02:/opt/modules/hadoop-2.5.0/etc/hadoop/

$ scp etc/hadoop/core-site.xml etc/hadoop/hdfs-site.xml z03:/opt/modules/hadoop-2.5.0/etc/hadoop/

* 啟動(dòng)Zookeeper服務(wù)

$ bin/zkServer.sh start

啟動(dòng)zookeeper,初始化HA在Zookeeper中狀態(tài)

$ bin/hdfs zkfc -formatZK

*啟動(dòng)HDFS服務(wù)

在[nn1]執(zhí)行:

$ sbin/start-dfs.sh

nn1與nn2的jps如圖所示:

* 查看活躍狀態(tài)

$ bin/hdfs haadmin -getServiceState nn1

$ bin/hdfs haadmin -getServiceState nn2

如圖:

* 測(cè)試牍颈,訪問如下站點(diǎn)也可以查看NameNode的活躍狀態(tài):

http://z01:50070/

http://z02:50070/

此時(shí)kill掉active的NameNode進(jìn)程迄薄,查看standby狀態(tài)會(huì)自動(dòng)切換到active

** Yarn的HA部署

目標(biāo): 防止單個(gè)resourcemanager宕機(jī)以后,整個(gè)YARN集群失效

集群規(guī)劃:

* 配置:yarn-site.xml,如圖:

* 拷貝給其他服務(wù)器并修改

$ scp etc/hadoop/yarn-site.xml z02:/opt/modules/hadoop-2.5.0/etc/hadoop/

$ scp etc/hadoop/yarn-site.xml z03:/opt/modules/hadoop-2.5.0/etc/hadoop/

* 啟動(dòng)每個(gè)服務(wù)器的服務(wù)

通過jps查看每個(gè)服務(wù)器的zookeeper服務(wù)QuorumPeerMain已經(jīng)運(yùn)行煮岁,沒有運(yùn)行則開啟讥蔽,方式前文已經(jīng)說過,不再贅述画机。

在 z02中:

$ sbin/start-yarn.sh

在z03中:

$ sbin/yarn-daemon.sh start resourcemanager

查看服務(wù)狀態(tài):

$ bin/yarn rmadmin -getServiceState rm1

$ bin/yarn rmadmin -getServiceState rm2

如圖:

測(cè)試:

運(yùn)行我們之前打好的jar包冶伞,進(jìn)行wordcount實(shí)例運(yùn)算,在運(yùn)算過程中kill掉active的rm步氏,觀察任務(wù)運(yùn)行响禽。

先開啟HDFS服務(wù)(忘記的請(qǐng)看上邊的內(nèi)容),再上傳一個(gè)words.txt文檔到HDFS,再開始單詞統(tǒng)計(jì)芋类,涉及命令:

$ bin/hdfs dfs -mkdir /input/

$ bin/hdfs dfs -mkdir /input/words/

$ bin/hdfs dfs -put words.txt /input/words/

如圖:

$ bin/yarn jar MyWordCount.jar /input/words/words.txt /output/

** 總結(jié)

這一節(jié)簡(jiǎn)單介紹了zookeeper并闡述其工作原理隆嗅,成功使用zookeeper部署了NameNode HA和Resourcemanager HA。


IT全棧公眾號(hào):

QQ大數(shù)據(jù)技術(shù)交流群(廣告勿入):476966007


下一節(jié):Hadoop框架基礎(chǔ)(六)后續(xù)更新

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末侯繁,一起剝皮案震驚了整個(gè)濱河市胖喳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巫击,老刑警劉巖禀晓,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異坝锰,居然都是意外死亡粹懒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門顷级,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凫乖,“玉大人,你說我怎么就攤上這事弓颈∶毖浚” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵翔冀,是天一觀的道長导街。 經(jīng)常有香客問我,道長纤子,這世上最難降的妖魔是什么搬瑰? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮控硼,結(jié)果婚禮上泽论,老公的妹妹穿的比我還像新娘。我一直安慰自己卡乾,他們只是感情好翼悴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著幔妨,像睡著了一般鹦赎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上误堡,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天钙姊,我揣著相機(jī)與錄音,去河邊找鬼埂伦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛思恐,可吹牛的內(nèi)容都是我干的沾谜。 我是一名探鬼主播膊毁,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼基跑!你這毒婦竟也來了婚温?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤媳否,失蹤者是張志新(化名)和其女友劉穎栅螟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體篱竭,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡力图,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掺逼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吃媒。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖吕喘,靈堂內(nèi)的尸體忽然破棺而出赘那,到底是詐尸還是另有隱情,我是刑警寧澤氯质,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布募舟,位于F島的核電站,受9級(jí)特大地震影響闻察,放射性物質(zhì)發(fā)生泄漏拱礁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一蜓陌、第九天 我趴在偏房一處隱蔽的房頂上張望觅彰。 院中可真熱鬧,春花似錦钮热、人聲如沸填抬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽飒责。三九已至,卻和暖如春仆潮,著一層夾襖步出監(jiān)牢的瞬間宏蛉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國打工性置, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拾并,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像嗅义,于是被迫代替她去往敵國和親屏歹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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