Spark on YARN

啟動(dòng)SparkOnYARN

確認(rèn)HADOOP_CONF_DIR或者YARN_CONF_DIR指向的目錄包含Hadoop集群的配置文件。Spark依賴這些配置文件的內(nèi)容寫(xiě)HDFS或者向YARN申請(qǐng)資源叠聋。這些配置需要復(fù)制到Spark集群內(nèi)所有的機(jī)器上炸卑,來(lái)保證整個(gè)集群使用的是同一套配置黎茎。如果配置中的Java系統(tǒng)變量或者環(huán)境變量不是YARN支持的,他們應(yīng)該被設(shè)置到Spark應(yīng)用的配置中(driver速梗、executor和Application Master)

使用YARN啟動(dòng)Spark應(yīng)用有兩種模式(cluster和client)钞啸。在cluster模式下,Spark應(yīng)用的Driver端根據(jù)YARN的調(diào)度運(yùn)行在Application Master進(jìn)程中逾一,在啟動(dòng)Spark應(yīng)用之后铸本,客戶端就可以直接退出了。在client模式下遵堵,Driver端運(yùn)行在客戶端進(jìn)程里箱玷,Application Master只用來(lái)向YARN申請(qǐng)資源。

和standalone以及mesos模式不一樣陌宿,在YARN模式下锡足,ResourceManager的地址是從Hadoop配置文件中讀到的,所以 --master 參數(shù)要設(shè)置值為 "yarn"壳坪,以集群模式啟動(dòng)Spark應(yīng)用需要這樣寫(xiě)

./bin/spark-submit --class path.to.your.Class --master yarn --deploy-mode cluster [options] <app jar> [app options]

例如

./bin/spark-submit --class org.apache.spark.examples.SparkPi \
    --master yarn \
    --deploy-mode cluster \
    --driver-memory 4g \
    --executor-memory 2g \
    --executor-cores 1 \
    --queue thequeue \
    lib/spark-examples*.jar \
    10

上面這行命令啟動(dòng)了一個(gè)YARN的client程序舶得,這個(gè)程序會(huì)啟動(dòng)一個(gè)默認(rèn)的Application Master。 SparkPi這個(gè)類(lèi)會(huì)作為Application Master進(jìn)程的一個(gè)線程執(zhí)行爽蝴°迮客戶端可以定期的從Application Master拉取一些統(tǒng)計(jì)信息纫骑,然后把這些信息顯示在控制臺(tái)上。當(dāng)Spark應(yīng)用執(zhí)行完畢的時(shí)候這個(gè)client會(huì)自動(dòng)退出九孩。

以client模式啟動(dòng)一個(gè)Spark應(yīng)用和前面差不多先馆,只是把deploy-mode參數(shù)的cluster替換成client,下面這個(gè)行命令是使用client模式啟動(dòng)spark-shell

./bin/spark-shell --master yarn --deploy-mode client

添加其他JAR

cluster模式下躺彬,因?yàn)镈river端運(yùn)行在其他機(jī)器上煤墙,所以代碼里寫(xiě)SparkContext.addJar是沒(méi)用的(client模式才可以這樣寫(xiě))。如果cluster模式下我們還有這個(gè)需求宪拥,我們要把想添加的jar文件用--jars參數(shù)拼在啟動(dòng)命令里仿野。

./bin/spark-submit --class my.main.Class \
    --master yarn \
    --deploy-mode cluster \
    --jars my-other-jar.jar,my-other-other-jar.jar \
    my-main-jar.jar \
    app_arg1 app_arg2

準(zhǔn)備

想要使用Spark on YARN需要有Spark獨(dú)立的構(gòu)建結(jié)果。官網(wǎng)上提供了下載地址她君,如果想要自己去構(gòu)建一把也可以设预,相關(guān)信息在這里

配置

Spark on YARN模式的配置項(xiàng)大多數(shù)和另外兩種一樣。關(guān)于on YARN模式的特殊配置可以看這里

調(diào)試Spark應(yīng)用

在YARN的屬于里犁河,executor和application master都運(yùn)行在YARN的容器內(nèi)鳖枕。在Spark應(yīng)用執(zhí)行完畢后YARN有兩種方式來(lái)管理容器內(nèi)的日志。如果日志聚集功能打開(kāi)(使用 yarn.log-aggregation-enable 配置項(xiàng)),容器日志會(huì)被復(fù)制到HDFS桨螺,并從所在的機(jī)器上刪除宾符。這些日志可以使用yarn logs命令在集群內(nèi)的任意一臺(tái)節(jié)點(diǎn)上查看

yarn logs -applicationId <app ID>

這條命令會(huì)打印這個(gè)應(yīng)用(其實(shí)是Spark應(yīng)用,但YARN是一個(gè)獨(dú)立的資源調(diào)度與任務(wù)監(jiān)控工具灭翔,只要符合它的規(guī)范魏烫,任何應(yīng)用都可以使用YARN來(lái)做資源調(diào)度和任務(wù)監(jiān)控,所以這里用了"應(yīng)用"兩個(gè)字而不是"Spark應(yīng)用")在所有容器實(shí)例內(nèi)的所有日志肝箱。我們也可以使用HDFS的API來(lái)直接查看日志哄褒。這些日志的存儲(chǔ)路徑使用yarn.nodemanager.remote-app-log-dir 和 yarn.nodemanager.remote-app-log-dir-suffix來(lái)配置,一個(gè)配置目錄煌张,一個(gè)配置文件后綴呐赡。這些日志還可以在Spark的WEB UI中的Executors 頁(yè)簽中查看。我們需要確保Spark History Server和MapReduce History Server都運(yùn)行正常骏融,并且早yarn-site.xml中配置了yarn.log.server.url屬性链嘀。Spark History Server的UI會(huì)把查看日志的動(dòng)作重定向到MapReduce History Server中來(lái)顯示聚合后的日志。

日志聚合沒(méi)打開(kāi)時(shí)档玻,日志會(huì)保存在每臺(tái)執(zhí)行的機(jī)器上怀泊,所在的目錄是YARN_APP_LOGS_DIR,這個(gè)一般被配置到/tmp/logs目錄或者$HADOOP_HOME/log/uiserlogs目錄(具體位置取決于Hadoop版本和安裝時(shí)的配置)误趴。我們可以到具體的機(jī)器上去查看指定目錄下的日志霹琼,子目錄被按照applicationid和containerid組織。日志同樣可以在Spark WEB UI中的Executors頁(yè)簽中查看,但此時(shí)不會(huì)重定向到MapReduce History Server了枣申。

想查看每個(gè)容器啟動(dòng)時(shí)的環(huán)境變量树灶,可以增加 yarn.nodemanager.delete.debug-delay-sec屬性的值(比如設(shè)置為36000)然后到運(yùn)行容器的機(jī)器上查看 yarn.nodemanager.local-dirs 目錄中的內(nèi)容。這個(gè)目錄中包含了啟動(dòng)容器的腳本糯而,jar包和所有的環(huán)境變量天通。這個(gè)騷操作在調(diào)試classpath和環(huán)境變量等問(wèn)題時(shí)非常有用。(注意熄驼,啟用此選項(xiàng)需要管理員權(quán)限才能進(jìn)行群集設(shè)置并重新啟動(dòng)所有節(jié)點(diǎn)管理器像寒。因此,這不適用于托管群集)瓜贾。

要為application master和 executor使用自定義的log4j配置诺祸,可以使用下面的選項(xiàng)

  • 用spark-submit提交任務(wù)時(shí),使用 --files 來(lái)上傳一個(gè)自定義的log4j.properties
  • 配置Spark集群的時(shí)候祭芦,把 spark.driver.extraJavaOptions(這個(gè)是給driver的)或者spark.executor.extraJavaOptions(這個(gè)是給executor的)配置上 -Dlog4j.configuration=<log4j.properties文件的絕對(duì)路徑>筷笨。注意,這樣做需要配置的時(shí)候把 file:// 這個(gè)協(xié)議寫(xiě)上龟劲,這個(gè)文件也需要放到集群中所有節(jié)點(diǎn)上
  • 修改spark機(jī)器上配置文件目錄內(nèi)的log4j.properties(看樣子是不需要重啟了)胃夏,但要注意這個(gè)配置比前面兩個(gè)優(yōu)先級(jí)要低,互相沖突的時(shí)候這個(gè)文件內(nèi)的配置肯定不生效

需要注意的是:第一種方式的配置會(huì)讓Application Master和Executor使用相同的配置文件昌跌,當(dāng)ApplicationMaster和某個(gè)Executor在同一臺(tái)機(jī)器上的時(shí)候仰禀,可能會(huì)有一些問(wèn)題,因?yàn)樗麄冊(cè)谕瑫r(shí)操作同一個(gè)日志文件蚕愤。

如果我們需要設(shè)置一個(gè)適當(dāng)?shù)奈恢脕?lái)讓YARN放置答恶、聚合日志,在log4j.properties文件中使用spark.yarn.app.container.log.dir 來(lái)配置文件輸出位置萍诱,比如:

log4j.appender.file_appender.File=${spark.yarn.app.container.log.dir}/spark.log

如果是Streaming應(yīng)用悬嗓,需要配置 RollingFileAppender并且設(shè)置本地存儲(chǔ)路徑,來(lái)避免日志文件太大磁盤(pán)空間不足裕坊。

為Application Master和executor指定自定義的metrics.properties 包竹,這個(gè)文件在spark配置目錄中。對(duì)文件的修改會(huì)自動(dòng)被提交給集群碍庵,所以我們不需要每次啟動(dòng)Spark應(yīng)用手動(dòng)指定 --files 參數(shù)映企。

下面是Spark的屬性

名稱 默認(rèn)值 含義
spark.yarn.am.memory 512m client模式下指定Application Master總的內(nèi)存大小,cluster模式下使用spark.driver.memory静浴。使用小寫(xiě)字母后綴來(lái)指定單位:k,m,g,t
spark.yarn.am.cores 1 client模式下Application Master使用的cpu數(shù)量。cluster模式下用spark.driver.cores
spark.yarn.am.waitTime 100s cluster模式下application master等待SparkContext被初始化的時(shí)間挤渐。client模式下application master等待driver連接的時(shí)間
spark.yarn.submit.file.replication HDFS的副本數(shù) Spark應(yīng)用提交的文件在HDFS中的副本數(shù)苹享,一般這些文件是:程序的jar和其他的分布式存儲(chǔ)的文件或歸檔文件
spark.yarn.stagingDir 當(dāng)前用戶家目錄 提交應(yīng)用程序時(shí)使用的暫存目錄。
spark.yarn.preserve.staging.files false 當(dāng)Spark應(yīng)用結(jié)束的時(shí)候,緩存的jar和文件是否刪除得问。false為刪除囤攀,設(shè)置為true是不刪除
spark.yarn.scheduler.heartbeat.interval-ms 3000 application master到Y(jié)ARN resourcemanager的心跳間隔,單位是毫秒宫纬。這個(gè)值的上線時(shí)YARN配置的值的一半焚挠,也就是 yarn.am.liveness-monitor.expiry-interval-ms的值的一半
spark.yarn.scheduler.initial-allocation.interval 200ms 當(dāng)ResourceManager沒(méi)響應(yīng)ApplicationMaster請(qǐng)求的時(shí)候,重復(fù)請(qǐng)求的間隔漓骚。這個(gè)值不應(yīng)該比spark.yarn.scheduler.heartbeat.interval-ms大蝌衔。如果ResourceManager一直沒(méi)響應(yīng),ApplicationMaster會(huì)再次請(qǐng)求蝌蹂,直到得到反饋噩斟,或者總時(shí)間超過(guò)spark.yarn.scheduler.heartbeat.interval-ms值
spark.yarn.historyServer.address 無(wú) Spark History Server地址。
spark.yarn.dist.archives 無(wú) 會(huì)被復(fù)制到每個(gè)Executor所在機(jī)器上的歸檔
文件孤个,逗號(hào)分隔
spark.yarn.dist.files 無(wú) 會(huì)被復(fù)制到每個(gè)Executor所在機(jī)器上的文件剃允,逗號(hào)分隔
spark.yarn.dist.jars 無(wú) 會(huì)被復(fù)制到每個(gè)Executor所在機(jī)器上的jar文件,逗號(hào)分隔
spark.executor.instances 2 靜態(tài)資源exector個(gè)數(shù)分配默認(rèn)值齐鲤。(Spark是靜態(tài)資源分配斥废,因?yàn)槲覀冃枰趫?zhí)行前確認(rèn)資源,不論命令行還是默認(rèn)配置都是預(yù)先分配)當(dāng)spark.dynamicAllocation.enabled為true時(shí)给郊,是動(dòng)態(tài)分配資源营袜,這種場(chǎng)景Streaming的情況更多,因?yàn)樾枰馁Y源和業(yè)務(wù)峰值相關(guān)丑罪。
spark.yarn.executor.memoryOverhead executorMemory * 0.10,最少 384 每個(gè)executor分配的最少非堆內(nèi)存荚板,單位m。
spark.yarn.driver.memoryOverhead driverMemory * 0.10, 最少384 Driver端的非堆內(nèi)存吩屹,單位m
spark.yarn.am.memoryOverhead AM memory * 0.10, 最少384 client模式下Application Master的非堆內(nèi)存
spark.yarn.am.port 隨機(jī) Application Master的端口跪另。client模式下,這個(gè)端口用于Driver端于ApplicationMaster的通信煤搜。cluster模式下用于接收調(diào)度程序的終止命令
spark.yarn.queue default 提交應(yīng)用程序的YARN隊(duì)列名稱
spark.yarn.jars 無(wú) 需要分發(fā)到Y(jié)ARN容器中的Spark代碼的jar包免绿,多個(gè)用逗號(hào)分隔。Spark on YARN中Spark默認(rèn)使用本地的Spark的jar擦盾,但是也可以把Spark的jar放到HDFS中全局可讀嘲驾,這樣Spark應(yīng)用程序使用這些jar的時(shí)候不需要每次都用 --jars 提交然后分發(fā)。
spark.yarn.archive 無(wú) 和spark.yarn.jars同樣原理
spark.yarn.access.namenodes 無(wú) Spark應(yīng)用程序可以訪問(wèn)的安全的HDFS的namenode節(jié)點(diǎn)列表迹卢,多個(gè)用逗號(hào)分隔spark.yarn.access.namenodes=hdfs://nn1.com:8032,hdfs://nn2.com:8032, webhdfs://nn3.com:50070辽故。關(guān)于權(quán)限和K8S相關(guān)信息我還不了解,以后再回來(lái)修改
spark.yarn.appMasterEnv.[EnvironmentVariableName] 無(wú) 把環(huán)境變量添加到Application Master所在的進(jìn)程中腐碱。在cluster模式下誊垢,這個(gè)環(huán)境變量可以被Driver端讀取到, client模式下這個(gè)變量只有啟動(dòng)Driver的程序可以讀取到
spark.yarn.containerLauncherMaxThreads 25 Application Master中用于啟動(dòng)執(zhí)行程序容器的最大線程數(shù)
spark.yarn.am.extraJavaOptions 無(wú) Application Master啟動(dòng)的時(shí)候的JVM參數(shù)配置
spark.yarn.am.extraLibraryPath 無(wú) 在client模式下,啟動(dòng)Application Master的時(shí)候指定的jar加載路徑
spark.yarn.maxAppAttempts yarn-site.xml中配置的yarn.resourcemanager.am.max-attempts 值 向YARN提交申請(qǐng)的時(shí)候最大的嘗試次數(shù)喂走,這個(gè)數(shù)字不應(yīng)該超過(guò)YARN中配置的值
spark.yarn.am.attemptFailuresValidityInterval 無(wú) Spark監(jiān)控ApplicationMaster的失敗次數(shù)殃饿,如果這個(gè)值配置了,當(dāng)ApplicationMaster運(yùn)行持續(xù)時(shí)間超過(guò)這個(gè)值的時(shí)候芋肠,失敗次數(shù)會(huì)被清零乎芳。這個(gè)屬性不配置的時(shí)候不會(huì)生效,并且要求Hadoop版本在2.6以上
spark.yarn.executor.failuresValidityInterval 無(wú) 定義了Executor執(zhí)行是否失敗的檢查間隔帖池,超過(guò)這個(gè)檢查間隔的錯(cuò)誤會(huì)被忽略
spark.yarn.submit.waitAppCompletion true yarn cluster模式下奈惑,這個(gè)屬性控制客戶端是否需要同步等待任務(wù)執(zhí)行完畢。如果設(shè)置為true碘裕,客戶端進(jìn)程會(huì)一直活著携取,并報(bào)告Spark應(yīng)用的當(dāng)前狀態(tài)。如果設(shè)置為false帮孔,則客戶端提交完畢后就立即退出
spark.yarn.am.nodeLabelExpression 無(wú) 聲明ApplicationMaster的節(jié)點(diǎn)標(biāo)簽表達(dá)式雷滋,目的是限制哪些節(jié)點(diǎn)可以作為ApplicationMaster節(jié)點(diǎn),但要求YARN版本在2.6以上
spark.yarn.executor.nodeLabelExpression 無(wú) 聲明Executor的節(jié)點(diǎn)標(biāo)簽表達(dá)式文兢,目的是限制哪些節(jié)點(diǎn)可以作為Executor節(jié)點(diǎn)晤斩,但要求YARN版本在2.6以上

to be continued

重要提示

  • 請(qǐng)求是否被及時(shí)響應(yīng)依賴于當(dāng)前使用的scheduler,以及這個(gè)scheduler的配置方式
  • 在cluster模式下姆坚,driver和executor使用的本地工作目錄是YARN中配置的yarn.nodemanager.local-dirs目錄下澳泵,用戶指定的spark.local.dir是不起作用的。在client模式下兼呵,只有executor和cluster模式下一樣兔辅,而Driver會(huì)使用spark.local.dir中的配置作為本地工作目錄。這是因?yàn)閏lient模式下Driver不是在YARN cluster里執(zhí)行的击喂。
  • 使用--files參數(shù)提交文件到集群可以指定別名维苔,例如 --files localtest.txt#appSees.txt 這是會(huì)把localtest.txt提交到HDFS里,但是想要訪問(wèn)這個(gè)文件需要使用appSees.txt這個(gè)名字懂昂。
  • cluster模式下介时,可以用--jars來(lái)實(shí)現(xiàn)SparkContext.addJar的功能。

在安全集群中運(yùn)行

TODO

給YARN配置外部Shuffle服務(wù)

這部分因?yàn)槲也涣私釿ARN凌彬,所以不是很明白沸柔。以后了解了再回來(lái)補(bǔ)充

使用Spark Shuffle Service,需要在YARN集群里做如下操作

  1. 使用YARN profile構(gòu)建Spark铲敛。如果現(xiàn)在在使用預(yù)編譯的發(fā)布版則跳過(guò)此步
  2. 找到spark-<version>-yarn-shuffle.jar褐澎。如果是自己構(gòu)建這個(gè)包應(yīng)該在 $SPARK_HOME/common/network-yarn/target/scala-<version>目錄下。
    如果使用的是發(fā)布版原探,這個(gè)包應(yīng)該在yarn目錄下
  3. 在集群的每個(gè)NodeManager上把這個(gè)包添加到環(huán)境變量里
  4. 集群的每個(gè)NodeManager上的yarn-site.xml中乱凿,把spark_shuffle設(shè)置為 yarn.nodemanager.aux-services的值顽素。然后設(shè)置org.apache.spark.network.yarn.YarnShuffleService替代yarn.nodemanager.aux-services.spark_shuffle.class
  5. 給NodeManager增加堆內(nèi)存咽弦,在etc/hadoop/yarn-env.sh中設(shè)置YARN_HEAPSIZE徒蟆。這個(gè)設(shè)置避免Shuffle過(guò)程中的內(nèi)存回收
  6. 重啟YARN集群中的所有NodeManager

當(dāng)Spark Shuffle Service在YARN集群跑起來(lái)后,可以使用這個(gè)配置項(xiàng)
spark.yarn.shuffle.stopOnFailure 型型,默認(rèn)是false段审。當(dāng)SparkShuffleService初始化失敗的時(shí)候是否關(guān)閉NodeManager。這個(gè)配置是避免當(dāng)機(jī)器上的SparkShuffleService不可用的時(shí)候闹蒜,任務(wù)被分配到了這臺(tái)機(jī)器上寺枉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市绷落,隨后出現(xiàn)的幾起案子姥闪,更是在濱河造成了極大的恐慌,老刑警劉巖砌烁,帶你破解...
    沈念sama閱讀 221,331評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件筐喳,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡函喉,警方通過(guò)查閱死者的電腦和手機(jī)避归,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)管呵,“玉大人梳毙,你說(shuō)我怎么就攤上這事【柘拢” “怎么了账锹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,755評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)坷襟。 經(jīng)常有香客問(wèn)我奸柬,道長(zhǎng),這世上最難降的妖魔是什么啤握? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,528評(píng)論 1 296
  • 正文 為了忘掉前任鸟缕,我火速辦了婚禮,結(jié)果婚禮上排抬,老公的妹妹穿的比我還像新娘懂从。我一直安慰自己,他們只是感情好蹲蒲,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布番甩。 她就那樣靜靜地躺著,像睡著了一般届搁。 火紅的嫁衣襯著肌膚如雪缘薛。 梳的紋絲不亂的頭發(fā)上窍育,一...
    開(kāi)封第一講書(shū)人閱讀 52,166評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音宴胧,去河邊找鬼漱抓。 笑死,一個(gè)胖子當(dāng)著我的面吹牛恕齐,可吹牛的內(nèi)容都是我干的乞娄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,768評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼显歧,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼仪或!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起士骤,我...
    開(kāi)封第一講書(shū)人閱讀 39,664評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤范删,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后拷肌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體到旦,經(jīng)...
    沈念sama閱讀 46,205評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評(píng)論 3 340
  • 正文 我和宋清朗相戀三年廓块,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了厢绝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,435評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡带猴,死狀恐怖昔汉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拴清,我是刑警寧澤靶病,帶...
    沈念sama閱讀 36,126評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站口予,受9級(jí)特大地震影響娄周,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沪停,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評(píng)論 3 333
  • 文/蒙蒙 一煤辨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧木张,春花似錦众辨、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,276評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至妻献,卻和暖如春蛛株,著一層夾襖步出監(jiān)牢的瞬間团赁,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工谨履, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留欢摄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,818評(píng)論 3 376
  • 正文 我出身青樓屉符,卻偏偏與公主長(zhǎng)得像剧浸,于是被迫代替她去往敵國(guó)和親锹引。 傳聞我的和親對(duì)象是個(gè)殘疾皇子矗钟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評(píng)論 2 359