8须眷、NameNode和SecondaryNameNode工作原理

Fsimage和Edits解析

相關(guān)概念

namenode被格式化之后撤逢,將在/opt/module/hadoop-2.8.3/data/tmp/dfs/name/current目錄中產(chǎn)生如下文件


namenode格式化后文件.png
  1. Fsimage文件:HDFS文件系統(tǒng)元數(shù)據(jù)的一個(gè)永久性的檢查點(diǎn)颜屠,其中包含HDFS文件系統(tǒng)的所有目錄和文件idnode的序列化信息晴氨。
  2. Edits文件:存放HDFS文件系統(tǒng)的所有更新操作的路徑,文件系統(tǒng)客戶端執(zhí)行的所有寫操作首先會(huì)被記錄到edits文件中。
  3. seen_txid文件保存的是一個(gè)數(shù)字巩割,就是最后一個(gè)edits_的數(shù)字

每次NameNode啟動(dòng)的時(shí)候都會(huì)將最新的fsimage文件讀入內(nèi)存裙顽,并合并edits里面的更新操作,保證內(nèi)存中的元數(shù)據(jù)信息是最新的宣谈、同步的愈犹,可以看成NameNode啟動(dòng)的時(shí)候就將fsimage和edits文件進(jìn)行了合并。
NameNode會(huì)把最新的fsimage后綴和seen_txid 之間的edits合并蒲祈。

使用OIV查看fsimage文件

hdfs oiv -p 文件類型 -i鏡像文件 -o 轉(zhuǎn)換后文件輸出路徑
hdfs oiv -p XML -i fsimage_0000000000000000294 -o fsimage.xml
文件內(nèi)容如下

<?xml version="1.0"?>
<fsimage>
    <version>
        <layoutVersion>-63</layoutVersion>
        <onDiskVersion>1</onDiskVersion>
        <oivRevision>b3fe56402d908019d99af1f1f4fc65cb1d1436a2</oivRevision>
    </version>
    <NameSection>
        <namespaceId>1560614512</namespaceId>
        <genstampV1>1000</genstampV1>
        <genstampV2>1040</genstampV2>
        <genstampV1Limit>0</genstampV1Limit>
        <lastAllocatedBlockId>1073741862</lastAllocatedBlockId>
        <txid>294</txid>
    </NameSection>
    <INodeSection>
        <lastInodeId>16407</lastInodeId>
        <numInodes>6</numInodes>
        <inode>
            <id>16385</id>
            <type>DIRECTORY</type>
            <name></name>
            <mtime>1536189784686</mtime>
            <permission>hadoop:supergroup:0755</permission>
            <nsquota>9223372036854775807</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16403</id>
            <type>DIRECTORY</type>
            <name>user</name>
            <mtime>1536189784687</mtime>
            <permission>hadoop:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16404</id>
            <type>DIRECTORY</type>
            <name>hadoop</name>
            <mtime>1536190852299</mtime>
            <permission>hadoop:supergroup:0755</permission>
            <nsquota>-1</nsquota>
            <dsquota>-1</dsquota>
        </inode>
        <inode>
            <id>16405</id>
            <type>FILE</type>
            <name>client</name>
            <replication>3</replication>
            <mtime>1536189786438</mtime>
            <atime>1536320623173</atime>
            <preferredBlockSize>134217728</preferredBlockSize>
            <permission>hadoop:supergroup:0644</permission>
            <blocks>
                <block>
                    <id>1073741858</id>
                    <genstamp>1036</genstamp>
                    <numBytes>36667596</numBytes>
                </block>
            </blocks>
            <storagePolicyId>0</storagePolicyId>
        </inode>
    </INodeSection>
    <INodeReferenceSection></INodeReferenceSection>
    <SnapshotSection>
        <snapshotCounter>0</snapshotCounter>
        <numSnapshots>0</numSnapshots>
    </SnapshotSection>
    <INodeDirectorySection>
        <directory>
            <parent>16385</parent>
            <child>16403</child>
        </directory>
        <directory>
            <parent>16403</parent>
            <child>16404</child>
        </directory>
        <directory>
            <parent>16404</parent>
            <child>16405</child>
            <child>16406</child>
        </directory>
        <directory>
            <parent>16406</parent>
            <child>16407</child>
        </directory>
    </INodeDirectorySection>
    <FileUnderConstructionSection></FileUnderConstructionSection>
    <SecretManagerSection>
        <currentId>0</currentId>
        <tokenSequenceNumber>0</tokenSequenceNumber>
        <numDelegationKeys>0</numDelegationKeys>
        <numTokens>0</numTokens>
    </SecretManagerSection>
    <CacheManagerSection>
        <nextDirectiveId>1</nextDirectiveId>
        <numDirectives>0</numDirectives>
        <numPools>0</numPools>
    </CacheManagerSection>
</fsimage>

從上面的文件中可以看出甘萧,fsimage中并沒有記錄塊所對(duì)應(yīng)的datenode,這是因?yàn)闆]有必要在fsimage文件中記錄梆掸,在內(nèi)存中維護(hù)就可以了扬卷,datenode像namenode匯報(bào)。

oev查看edits文件

hdfs oev -p 文件類型 -i編輯日志 -o 轉(zhuǎn)換后文件輸出路徑
hdfs oev -p XML -i edits_inprogress_0000000000000000336 -o edits_inprogress_0000000000000000336.xml
內(nèi)容如下

<?xml version="1.0" encoding="UTF-8"?>
<EDITS>
  <EDITS_VERSION>-63</EDITS_VERSION>
  <RECORD>
    <OPCODE>OP_START_LOG_SEGMENT</OPCODE>
    <DATA>
      <TXID>303</TXID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_MKDIR</OPCODE>
    <DATA>
      <TXID>304</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>16408</INODEID>
      <PATH>/user/hadoop/test</PATH>
      <TIMESTAMP>1536562302682</TIMESTAMP>
      <PERMISSION_STATUS>
        <USERNAME>hadoop</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>493</MODE>
      </PERMISSION_STATUS>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ADD</OPCODE>
    <DATA>
      <TXID>305</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>16409</INODEID>
      <PATH>/user/hadoop/test/cpHello.txt._COPYING_</PATH>
      <REPLICATION>3</REPLICATION>
      <MTIME>1536562302831</MTIME>
      <ATIME>1536562302831</ATIME>
      <BLOCKSIZE>134217728</BLOCKSIZE>
      <CLIENT_NAME>DFSClient_NONMAPREDUCE_1326850463_1</CLIENT_NAME>
      <CLIENT_MACHINE>192.168.114.102</CLIENT_MACHINE>
      <OVERWRITE>true</OVERWRITE>
      <PERMISSION_STATUS>
        <USERNAME>hadoop</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>420</MODE>
      </PERMISSION_STATUS>
      <RPC_CLIENTID>424e8401-aa20-4dd2-83ae-cedd762158f0</RPC_CLIENTID>
      <RPC_CALLID>7</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ALLOCATE_BLOCK_ID</OPCODE>
    <DATA>
      <TXID>306</TXID>
      <BLOCK_ID>1073741863</BLOCK_ID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_SET_GENSTAMP_V2</OPCODE>
    <DATA>
      <TXID>307</TXID>
      <GENSTAMPV2>1041</GENSTAMPV2>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_ADD_BLOCK</OPCODE>
    <DATA>
      <TXID>308</TXID>
      <PATH>/user/hadoop/test/cpHello.txt._COPYING_</PATH>
      <BLOCK>
        <BLOCK_ID>1073741863</BLOCK_ID>
        <NUM_BYTES>0</NUM_BYTES>
        <GENSTAMP>1041</GENSTAMP>
      </BLOCK>
      <RPC_CLIENTID></RPC_CLIENTID>
      <RPC_CALLID>-2</RPC_CALLID>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_CLOSE</OPCODE>
    <DATA>
      <TXID>309</TXID>
      <LENGTH>0</LENGTH>
      <INODEID>0</INODEID>
      <PATH>/user/hadoop/test/cpHello.txt._COPYING_</PATH>
      <REPLICATION>3</REPLICATION>
      <MTIME>1536562304777</MTIME>
      <ATIME>1536562302831</ATIME>
      <BLOCKSIZE>134217728</BLOCKSIZE>
      <CLIENT_NAME></CLIENT_NAME>
      <CLIENT_MACHINE></CLIENT_MACHINE>
      <OVERWRITE>false</OVERWRITE>
      <BLOCK>
        <BLOCK_ID>1073741863</BLOCK_ID>
        <NUM_BYTES>1116</NUM_BYTES>
        <GENSTAMP>1041</GENSTAMP>
      </BLOCK>
      <PERMISSION_STATUS>
        <USERNAME>hadoop</USERNAME>
        <GROUPNAME>supergroup</GROUPNAME>
        <MODE>420</MODE>
      </PERMISSION_STATUS>
    </DATA>
  </RECORD>
  <RECORD>
    <OPCODE>OP_RENAME_OLD</OPCODE>
    <DATA>
      <TXID>310</TXID>
      <LENGTH>0</LENGTH>
      <SRC>/user/hadoop/test/cpHello.txt._COPYING_</SRC>
      <DST>/user/hadoop/test/cpHello.txt</DST>
      <TIMESTAMP>1536562304822</TIMESTAMP>
      <RPC_CLIENTID>424e8401-aa20-4dd2-83ae-cedd762158f0</RPC_CLIENTID>
      <RPC_CALLID>12</RPC_CALLID>
    </DATA>
  </RECORD>
</EDITS>

上述是往hdfs上傳文件的一個(gè)完成過(guò)程
首先創(chuàng)建文件夾酸钦,添加文件(不是真正的添加怪得,只是占個(gè)位置),分配塊ID卑硫,生成時(shí)間戳徒恋,真正上傳文件,關(guān)閉流欢伏,重命名文件入挣。

NameNode和SecondaryNameNode工作機(jī)制

namenode和secondardnamenode工作流程.png

該圖可以分成兩個(gè)階段看

  1. 第一階段:NameNode啟動(dòng)
    1). 第一次啟動(dòng)NameNode格式化后,創(chuàng)建fsimage和edits文件硝拧。如果不是第一次啟動(dòng)径筏,直接加載編輯日志和鏡像文件到內(nèi)存。
    2). 客戶端對(duì)元數(shù)據(jù)進(jìn)行增刪改的請(qǐng)求障陶。
    3). NameNode記錄操作日志滋恬,更新滾動(dòng)日志。
    4). NameNode在內(nèi)存中對(duì)數(shù)據(jù)進(jìn)行增刪改查抱究。

  2. 第二階段:Secondary NameNode工作
    1). Secondary NameNode詢問(wèn)NameNode是否需要checkpoint恢氯。直接帶回NameNode是否檢查結(jié)果。
    2). Secondary NameNode請(qǐng)求執(zhí)行checkpoint鼓寺。
    3). NameNode滾動(dòng)正在寫的edits日志勋拟。
    4). 將滾動(dòng)前的編輯日志和鏡像文件拷貝到Secondary NameNode。
    5). Secondary NameNode加載編輯日志和鏡像文件到內(nèi)存妈候,并合并敢靡。
    6). 生成新的鏡像文件fsimage.ckpt。
    7). 拷貝fsimage.chkpoint到NameNode州丹。
    8). NameNode將fsimage.chkpoint重新命名成fsimage醋安。

checkpoint時(shí)間設(shè)置

  1. 通常情況下,SecondaryNameNode每隔一小時(shí)執(zhí)行一次墓毒。如果修改在hdfs-site中
    在hdfs-default.xml中值如下
<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>3600</value>
  <description>The number of seconds between two periodic checkpoints.
  </description>
</property>
  1. 一分鐘檢查一次操作次數(shù)吓揪,當(dāng)操作次數(shù)達(dá)到1百萬(wàn)時(shí),SecondaryNameNode執(zhí)行一次所计。
    在hdfs-default.xml配置如下
<property>
  <name>dfs.namenode.checkpoint.txns</name>
  <value>1000000</value>
  <description>The Secondary NameNode or CheckpointNode will create a checkpoint
  of the namespace every 'dfs.namenode.checkpoint.txns' transactions, regardless
  of whether 'dfs.namenode.checkpoint.period' has expired.
  </description>
</property>

<property>
  <name>dfs.namenode.checkpoint.check.period</name>
  <value>60</value>
  <description>The SecondaryNameNode and CheckpointNode will poll the NameNode
  every 'dfs.namenode.checkpoint.check.period' seconds to query the number
  of uncheckpointed transactions.
  </description>
</property>

NameNode故障處理

方法一

將SecondaryNameNode中數(shù)據(jù)拷貝到NameNode存儲(chǔ)數(shù)據(jù)的目錄

  1. kill -9 NameNode對(duì)應(yīng)的進(jìn)程
  2. 刪除NameNode存儲(chǔ)數(shù)據(jù)
    rm -rf /opt/module/hadoop-2.8.3/data/tmp/dfs/name/
  3. 拷貝SecondaryNameNode中數(shù)據(jù)到原NameNode存儲(chǔ)數(shù)據(jù)目錄
    scp -r hadoop@hadoop-102:/opt/module/hadoop-2.8.3/data/tmp/dfs/namesecondary/* ./name
  4. 重新啟動(dòng)NameNode

方法二

使用-importCheckpoint選項(xiàng)啟動(dòng)NameNode守護(hù)進(jìn)程柠辞,從而將SecondaryNameNode中數(shù)據(jù)拷貝到NameNode目錄中

  1. 修改hdfs-site.xml
<property>
 <name>dfs.namenode.checkpoint.period</name>
 <value>120</value>
</property>

<property>
 <name>dfs.namenode.name.dir</name>
 <value>/opt/module/hadoop-2.7.2/data/tmp/dfs/name</value>
</property>
  1. kill -9 namenode進(jìn)程
  2. 刪除NameNode存儲(chǔ)的數(shù)據(jù)
    rm -rf /opt/module/hadoop-2.8.3/data/tmp/dfs/name/
  3. 如果SecondaryNameNode不和NameNode在一個(gè)主機(jī)節(jié)點(diǎn)上,需要將SecondaryNameNode存儲(chǔ)數(shù)據(jù)的目錄拷貝到NameNode存儲(chǔ)數(shù)據(jù)的平級(jí)目錄主胧,并刪除in_use.lock文件
    在dfs目錄下執(zhí)行
    scp -r hadoop@hadoop-102:/opt/module/hadoop-2.8.3/data/tmp/dfs/namesecondary ./
    進(jìn)入namesecondary目錄叭首,刪除in_use.lock文件
    cd namesecondary
    rm -rf in_use.lock
  4. 導(dǎo)入檢查點(diǎn)數(shù)據(jù)(等待一會(huì)ctrl+c結(jié)束掉)
    hdfs namenode -importCheckpoint
  5. 啟動(dòng)namenode
    hadoop-daemon.sh start namenode

集群安全模式

概述

NameNode啟動(dòng)時(shí),首先將映像文件(fsimage)載入內(nèi)存踪栋,并執(zhí)行編輯日志(edits)中的各項(xiàng)操作焙格。一旦在內(nèi)存中成功建立文件系統(tǒng)元數(shù)據(jù)的映像,則創(chuàng)建一個(gè)新的fsimage文件和一個(gè)空的編輯日志夷都。此時(shí)眷唉,NameNode開始監(jiān)聽DataNode請(qǐng)求。但是此刻囤官,NameNode運(yùn)行在安全模式冬阳,即NameNode的文件系統(tǒng)對(duì)于客戶端來(lái)說(shuō)是只讀的。
系統(tǒng)中的數(shù)據(jù)塊的位置并不是由NameNode維護(hù)的党饮,而是以塊列表的形式存儲(chǔ)在DataNode中肝陪。在系統(tǒng)的正常操作期間,NameNode會(huì)在內(nèi)存中保留所有塊位置的映射信息刑顺。在安全模式下氯窍,各個(gè)DataNode會(huì)向NameNode發(fā)送最新的塊列表信息,NameNode了解到足夠多的塊位置信息之后捏检,即可高效運(yùn)行文件系統(tǒng)荞驴。
如果滿足“最小副本條件”,NameNode會(huì)在30秒鐘之后就退出安全模式贯城。所謂的最小副本條件指的是在整個(gè)文件系統(tǒng)中99.9%的塊滿足最小副本級(jí)別(默認(rèn)值:dfs.replication.min=1)熊楼。在啟動(dòng)一個(gè)剛剛格式化的HDFS集群時(shí),因?yàn)橄到y(tǒng)中還沒有任何塊能犯,所以NameNode不會(huì)進(jìn)入安全模式鲫骗。

基本語(yǔ)法

集群處于安全模式,不能執(zhí)行重要操作(寫操作)踩晶。集群?jiǎn)?dòng)完成后执泰,自動(dòng)退出安全模式。

  1. bin/hdfs dfsadmin -safemode get (功能描述:查看安全模式狀態(tài))
  2. bin/hdfs dfsadmin -safemode enter (功能描述:進(jìn)入安全模式狀態(tài))
  3. bin/hdfs dfsadmin -safemode leave (功能描述:離開安全模式狀態(tài))
  4. bin/hdfs dfsadmin -safemode wait (功能描述:等待安全模式狀態(tài)渡蜻,監(jiān)控安全模式)

模擬等待安全模式

  1. 先進(jìn)入安全模式
    hdfs dfsadmin -safemode enter
  2. 編寫并執(zhí)行下面腳本
    vim testWait.sh
    輸入如下內(nèi)容
#!/bin/bash
hdfs dfsadmin -safemode wait
hdfs dfs -put test.txt /

給執(zhí)行權(quán)限
chmod +x testWait.sh
執(zhí)行
./testWait.sh

  1. 新打開一個(gè)窗口术吝,離開安全模式
    hdfs dfsadmin -safemode leave
    觀察結(jié)果计济,是否上傳成功

NameNode多目錄配置

NameNode的本地目錄可以配置成多個(gè),且每個(gè)目錄存放內(nèi)容相同排苍,增加了可靠性
具體步驟如下

  1. 在hdfs-site.xml文件中增加如下內(nèi)容
<property>
 <name>dfs.namenode.name.dir</name>
<value>file:///${hadoop.tmp.dir}/dfs/name1,file:///${hadoop.tmp.dir}/dfs/name2</value>
</property>
  1. 停止集群
    stop-dfs.sh
  2. 刪除date和logs中所有數(shù)據(jù)
    rm -rf /data /logs
  3. 格式化集群并啟動(dòng)
    hdfs namenode -format
    start-dfs.sh
  4. 查看結(jié)果


    namenode多級(jí)目錄.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沦寂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子淘衙,更是在濱河造成了極大的恐慌传藏,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彤守,死亡現(xiàn)場(chǎng)離奇詭異毯侦,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)具垫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門侈离,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人筝蚕,你說(shuō)我怎么就攤上這事霍狰。” “怎么了饰及?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵蔗坯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我燎含,道長(zhǎng)宾濒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任屏箍,我火速辦了婚禮绘梦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赴魁。我一直安慰自己卸奉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布颖御。 她就那樣靜靜地躺著榄棵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪潘拱。 梳的紋絲不亂的頭發(fā)上疹鳄,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音芦岂,去河邊找鬼瘪弓。 笑死,一個(gè)胖子當(dāng)著我的面吹牛禽最,可吹牛的內(nèi)容都是我干的腺怯。 我是一名探鬼主播袱饭,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼呛占!你這毒婦竟也來(lái)了宁赤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤栓票,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后愕够,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體走贪,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年惑芭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坠狡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遂跟,死狀恐怖逃沿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情幻锁,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站动分,受9級(jí)特大地震影響侍咱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜岭接,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一富拗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鸣戴,春花似錦啃沪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至入偷,卻和暖如春签餐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盯串。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工氯檐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人体捏。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓冠摄,卻偏偏與公主長(zhǎng)得像糯崎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子河泳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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