「微服務(wù)」緩存本質(zhì)全分析、對(duì)比與實(shí)踐

使用緩存的目的和問(wèn)題

緩存的目的是加快數(shù)據(jù)的讀取數(shù)據(jù)睛低,有效減少核心應(yīng)用、數(shù)據(jù)庫(kù)的壓力。但是緩存的使用也同時(shí)犧牲了其他方面的優(yōu)勢(shì)钱雷,比如數(shù)據(jù)的強(qiáng)一致性骂铁。

因此,我們?cè)谑褂镁彺嫣岣咦x取性能的同時(shí)罩抗,一定會(huì)失去一定的一致性拉庵。在某些場(chǎng)景下對(duì)讀取緩存的一致性要求并不很高,因此可以犧牲一定的一致性來(lái)?yè)Q取高性能套蒂。

下面钞支,我們以秒殺場(chǎng)景中的庫(kù)存查詢?yōu)槔齺?lái)說(shuō)明緩存對(duì)性能的提升和一致性的權(quán)衡。假設(shè)系統(tǒng)的需要滿足10W/s的請(qǐng)求查詢操刀。并且查詢的數(shù)據(jù)允許與實(shí)際數(shù)據(jù)允許5秒以內(nèi)的時(shí)間窗口差異烁挟。

image

從上圖流程與服務(wù)的吞吐量假設(shè)中,我們可以很容易的對(duì)系統(tǒng)需求進(jìn)行設(shè)計(jì)骨坑。

Note:上圖所示中為假設(shè)數(shù)據(jù)撼嗓,在真實(shí)環(huán)境中所有的數(shù)據(jù)都需要經(jīng)過(guò)多輪系統(tǒng)的壓測(cè)得到較為準(zhǔn)確的數(shù)據(jù)。

1. 服務(wù)(Service)可以支撐5K/s的吞吐欢唾,所以10W/s的需求需要20臺(tái)服務(wù)進(jìn)行支撐(這里不考慮服務(wù)不可用問(wèn)題且警,假設(shè)100%可用,正常真實(shí)系統(tǒng)需要有余量)礁遣。

2. 緩存(Cache)可以支撐5W/s的吞吐斑芜,所以10W/s的需求只需要2臺(tái)即可以支撐。

3. 數(shù)據(jù)庫(kù)(Mysql)可以支撐1K/s的吞吐祟霍,所以不使用緩存押搪,則需要100臺(tái)來(lái)進(jìn)行支撐。在使用緩存后浅碾,假設(shè)系統(tǒng)商品數(shù)據(jù)為3000種大州,緩存過(guò)期時(shí)間為5s,則數(shù)據(jù)庫(kù)請(qǐng)求量為3000/5s=600/s垂谢,只需要1臺(tái)厦画。

Note:關(guān)于第3點(diǎn)數(shù)據(jù)計(jì)算的說(shuō)明

首先,緩存的設(shè)計(jì)上必須防止擊穿(熱點(diǎn)Key過(guò)期時(shí)滥朱,所有請(qǐng)求直接打到數(shù)據(jù)庫(kù))與雪崩(大量Key同時(shí)過(guò)期根暑,導(dǎo)致請(qǐng)求大量打到數(shù)據(jù)庫(kù))。

所以徙邻,在商品設(shè)定為3000種的情況下排嫌,最壞的情況所有商品數(shù)據(jù)同時(shí)過(guò)期(雪崩),最高請(qǐng)求量3000(防擊穿設(shè)計(jì)缰犁,可以保證一個(gè)Key過(guò)期只有一個(gè)請(qǐng)求打到數(shù)據(jù)庫(kù))淳地。

這里怖糊,因?yàn)橹皇且粋€(gè)示例,所以以理想的情況來(lái)進(jìn)行評(píng)估颇象。

從上面的圖示中伍伤,可以很好的理解緩存與數(shù)據(jù)庫(kù)由于是分離的,不可能達(dá)到強(qiáng)一致性遣钳。也就是說(shuō)扰魂,分布式緩存會(huì)產(chǎn)生不一致問(wèn)題,因此我們?cè)诜植际骄彺嬖谑褂脮r(shí)需要判斷非強(qiáng)一致性對(duì)用戶的影響蕴茴。

使用緩存的最終目的在于提升系統(tǒng)的性價(jià)比劝评,而不是單純地提高系統(tǒng)的性能。

Redis與Memcache緩存介紹與對(duì)比

1. 數(shù)據(jù)結(jié)構(gòu)

Redis支持多種數(shù)據(jù)結(jié)構(gòu)倦淀,并且查詢性能極高蒋畜,可以達(dá)到log2^N的查詢速度。

Memcache只支持key/value存儲(chǔ)晃听,不支持其他數(shù)據(jù)結(jié)構(gòu)百侧。

2. 線程模型

Redis使用單線程,Memcache使用多線程能扒。所以Redis只支持單線程請(qǐng)求佣渴,一個(gè)Redis進(jìn)程只使用單核,所有命令串行執(zhí)行初斑,并發(fā)情況下不需要考慮數(shù)據(jù)一致性辛润。但是可以通過(guò)多個(gè)Redis進(jìn)程使用多核。而Memcache可以充分發(fā)揮多核優(yōu)勢(shì)见秤,單實(shí)例吞吐量極高砂竖,可以達(dá)到幾十萬(wàn)QPS。

3. 持久化

Redis提供了二種持久化方式:

  1. RDB持久化方式能夠在指定的時(shí)間間隔能對(duì)你的數(shù)據(jù)進(jìn)行快照存儲(chǔ)鹃答。
  2. AOF持久化方式記錄每次對(duì)服務(wù)器寫(xiě)的操作,當(dāng)服務(wù)器重啟的時(shí)候會(huì)重新執(zhí)行這些命令來(lái)恢復(fù)原始的數(shù)據(jù),AOF命令以redis協(xié)議追加保存每次寫(xiě)的操作到文件末尾.Redis還能對(duì)AOF文件進(jìn)行后臺(tái)重寫(xiě),使得AOF文件的體積不至于過(guò)大乎澄。

Memcache并不提供持久化機(jī)制,緩存的數(shù)據(jù)都是臨時(shí)的测摔。但是可以通過(guò)第三方來(lái)提供持久化置济。

4. 高可用

Redis支持主從節(jié)點(diǎn)復(fù)制,還支持Sentinel锋八、Cluster等高可用集群方案浙于。

Memcache不支持高可用模型,但是可使用第三方挟纱,如megagent代理羞酗。當(dāng)一個(gè)實(shí)例宕機(jī)時(shí),可以連接另外一個(gè)實(shí)例紊服。

5. 對(duì)隊(duì)列的支持

Redis本身支持lpush/rpop/brpop檀轨、lpushrprop(安全隊(duì)列)胸竞、publish/subscribe/psubscribe等隊(duì)列與發(fā)布訂閱模式。

Memcache不支持隊(duì)列裤园,但是可以通過(guò)如MemcacheQ來(lái)實(shí)現(xiàn)撤师。

6. 數(shù)據(jù)淘汰機(jī)制

Redis數(shù)據(jù)淘汰策略:

  • noeviction:返回錯(cuò)誤當(dāng)內(nèi)存限制達(dá)到并且客戶端嘗試執(zhí)行會(huì)讓更多內(nèi)存被使用的命令(大部分的寫(xiě)入指令剂府,但DEL和幾個(gè)例外)
  • allkeys-lru: 嘗試回收最少使用的鍵(LRU)拧揽,使得新添加的數(shù)據(jù)有空間存放。
  • volatile-lru: 嘗試回收最少使用的鍵(LRU)腺占,但僅限于在過(guò)期集合的鍵,使得新添加的數(shù)據(jù)有空間存放淤袜。
  • allkeys-random: 回收隨機(jī)的鍵使得新添加的數(shù)據(jù)有空間存放。
  • volatile-random: 回收隨機(jī)的鍵使得新添加的數(shù)據(jù)有空間存放衰伯,但僅限于在過(guò)期集合的鍵铡羡。
  • volatile-ttl: 回收在過(guò)期集合的鍵,并且優(yōu)先回收存活時(shí)間(TTL)較短的鍵,使得新添加的數(shù)據(jù)有空間存放意鲸。
  • volatile-lfu:從所有配置了過(guò)期時(shí)間的鍵中驅(qū)逐使用頻率最少的鍵
  • allkeys-lfu:從所有鍵中驅(qū)逐使用頻率最少的鍵

如果沒(méi)有鍵滿足回收的前提條件的話烦周,策略volatile-lru, volatile-random以及volatile-ttl就和noeviction 差不多了。

Memcache在容量達(dá)到指定值后怎顾,就基于LRU算法自動(dòng)刪除不使用的緩存读慎。

7. 內(nèi)存分配

Redis的內(nèi)存管理主要通過(guò)源碼中zmalloc.h和zmalloc.c兩個(gè)文件來(lái)實(shí)現(xiàn)的。Redis為了方便內(nèi)存的管理槐雾,在分配一塊內(nèi)存之 后夭委,會(huì)將這塊內(nèi)存的大小存入內(nèi)存塊的頭部。如圖 5所示募强,real_ptr是redis調(diào)用malloc后返回的指針株灸。redis將內(nèi)存塊的大小size存入頭部,size所占據(jù)的內(nèi)存大小是已知的擎值,為 size_t類(lèi)型的長(zhǎng)度慌烧,然后返回ret_ptr。當(dāng)需要釋放內(nèi)存的時(shí)候鸠儿,ret_ptr被傳給內(nèi)存管理程序屹蚊。通過(guò)ret_ptr,程序可以很容易的算出 real_ptr的值捆交,然后將real_ptr傳給free釋放內(nèi)存淑翼。

image

Redis通過(guò)定義一個(gè)數(shù)組來(lái)記錄所有的內(nèi)存分配情況,這個(gè)數(shù)組的長(zhǎng)度為ZMALLOC_MAX_ALLOC_STAT品追。數(shù)組的每一個(gè)元素代表當(dāng)前 程序所分配的內(nèi)存塊的個(gè)數(shù)玄括,且內(nèi)存塊的大小為該元素的下標(biāo)。在源碼中肉瓦,這個(gè)數(shù)組為zmalloc_allocations遭京。 zmalloc_allocations[16]代表已經(jīng)分配的長(zhǎng)度為16bytes的內(nèi)存塊的個(gè)數(shù)胃惜。zmalloc.c中有一個(gè)靜態(tài)變量 used_memory用來(lái)記錄當(dāng)前分配的內(nèi)存總大小。所以哪雕,總的來(lái)看船殉,Redis采用的是包裝的mallc/free,相較于Memcached的內(nèi)存 管理方法來(lái)說(shuō)斯嚎,要簡(jiǎn)單很多利虫。

Memcache采用slab table的方式分配內(nèi)存,首先將可得內(nèi)存按照不同大小分類(lèi)堡僻,在使用時(shí)根據(jù)需求查找接近于需求大小的塊分配的機(jī)制減少內(nèi)存碎片糠惫,但是這依賴于合理的配置。

綜上:

Redis和Memcache本質(zhì)上都是基于k/v實(shí)現(xiàn)的緩存钉疫,但是Memcache正如其名硼讽,依賴于內(nèi)存,不支持?jǐn)?shù)據(jù)的持久化牲阁,服務(wù)器關(guān)閉后數(shù)據(jù)丟失固阁。而Redis在很多方面具備數(shù)據(jù)庫(kù)的特征,或者說(shuō)就是一個(gè)數(shù)據(jù)庫(kù)系統(tǒng)城菊,可以通過(guò)RDB快照或者AOF日志將數(shù)據(jù)持久化到磁盤(pán)备燃,支持master-slave機(jī)制的數(shù)據(jù)備份;

在存儲(chǔ)小于100k的數(shù)據(jù)役电,Redis具有性能上的優(yōu)勢(shì)赚爵,而數(shù)據(jù)量大于100k,Memcache性能更好法瑟;

Redis只支持單線程請(qǐng)求冀膝,一個(gè)Redis進(jìn)程只使用單核,所有命令串行執(zhí)行霎挟,并發(fā)情況下不需要考慮數(shù)據(jù)一致性窝剖。但是可以通過(guò)多個(gè)Redis進(jìn)程使用多核。而Memcache可以充分發(fā)揮多核優(yōu)勢(shì)酥夭,單實(shí)例吞吐量極高赐纱,可以達(dá)到幾十萬(wàn)QPS;

在內(nèi)存利用率上Memcache更高熬北,但如果Redis使用hash結(jié)構(gòu)做k/v存儲(chǔ)疙描,由于其組合式的壓縮,內(nèi)存利用率會(huì)高于Memcache讶隐;

支持?jǐn)?shù)據(jù)類(lèi)型上起胰,Memcache只支持k/v類(lèi)型的數(shù)據(jù),而Redis還支持list巫延,set效五,zset地消,hash等數(shù)據(jù)結(jié)構(gòu),并且Redis支持服務(wù)器端的數(shù)據(jù)操作畏妖,而Memcache需要將數(shù)據(jù)拿到客戶端進(jìn)行修改再set回去脉执,大大增加了網(wǎng)絡(luò)IO和數(shù)據(jù)的體積,如果需要緩存能進(jìn)行更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)和操作戒劫,那么Redis更適合

應(yīng)用層緩存經(jīng)典使用姿勢(shì)

image

這是最常用的緩存服務(wù)架構(gòu)模式半夷,對(duì)于讀操作,先讀緩存谱仪,如果緩存不存在數(shù)據(jù)玻熙,則再讀數(shù)據(jù)庫(kù)否彩,讀取數(shù)據(jù)之后再回寫(xiě)緩存疯攒;對(duì)于寫(xiě)操作,先寫(xiě)數(shù)據(jù)列荔,然后刪除緩存(Cache-Aside pattern)敬尺。

緩存在寫(xiě)時(shí)的會(huì)涉及到雙寫(xiě)一致性問(wèn)題,在這里暫時(shí)不展開(kāi)贴浙。后續(xù)會(huì)專(zhuān)門(mén)章節(jié)進(jìn)行介紹砂吞。

緩存穿透、擊穿與雪崩

緩存穿透崎溃、擊穿與雪崩是常見(jiàn)的由于并發(fā)量大而導(dǎo)致的緩存問(wèn)題蜻直。

#緩存穿透

緩存穿透指的是使用不存在的Key請(qǐng)求,導(dǎo)致緩存無(wú)法命中袁串,每次請(qǐng)求都穿透到數(shù)據(jù)庫(kù)概而,使數(shù)據(jù)庫(kù)壓力過(guò)大,甚至宕機(jī)囱修。

通常解決方案是將空值緩存起來(lái)赎瑰,再次接到同樣的請(qǐng)求時(shí),就可以命中緩存空值破镰,直接返回而不再請(qǐng)求數(shù)據(jù)庫(kù)餐曼。當(dāng)然,如果每次的請(qǐng)求Key都不一樣鲜漩,導(dǎo)致空值緩存方案不起作用源譬,這正常依賴于參數(shù)的合法性校驗(yàn)與數(shù)據(jù)摘要的校驗(yàn),盡最大可能使用戶無(wú)法修改請(qǐng)求參數(shù)孕似。

更進(jìn)一步的做法是針對(duì)高并發(fā)接口的數(shù)據(jù)使用布隆過(guò)濾器來(lái)判斷請(qǐng)求的數(shù)據(jù)是否存在踩娘,如果不存在直接返回,避免數(shù)據(jù)庫(kù)的查詢操作鳞青。

什么是布隆過(guò)濾器

本質(zhì)上布隆過(guò)濾器是一種數(shù)據(jù)結(jié)構(gòu)霸饲,比較巧妙的概率型數(shù)據(jù)結(jié)構(gòu)(probabilistic data structure)为朋,特點(diǎn)是高效地插入和查詢,可以用來(lái)告訴你 “某樣?xùn)|西一定不存在或者可能存在”厚脉。

(祥細(xì)原理在后續(xù)文章中介紹)

#緩存擊穿

緩存擊穿是指在高并發(fā)場(chǎng)景下习寸,當(dāng)某個(gè)熱點(diǎn)Key過(guò)期時(shí),大量的并發(fā)請(qǐng)求同時(shí)打到數(shù)據(jù)庫(kù)傻工,造成數(shù)據(jù)庫(kù)壓力巨大甚至打死的情況霞溪。

緩存擊穿的處理方案有:

  • 若緩存的數(shù)據(jù)是基本不會(huì)發(fā)生更新的,則可嘗試將該熱點(diǎn)數(shù)據(jù)設(shè)置為永不過(guò)期中捆。* 若緩存的數(shù)據(jù)更新不頻繁鸯匹,且緩存刷新的整個(gè)流程耗時(shí)較少的情況下,則可以采用基于 redis泄伪、zookeeper 等分布式中間件的分布式互斥鎖殴蓬,或者本地互斥鎖以保證僅少量的請(qǐng)求能請(qǐng)求數(shù)據(jù)庫(kù)并重新構(gòu)建緩存,其余線程則在鎖釋放后能訪問(wèn)到新緩存蟋滴。* 若緩存的數(shù)據(jù)更新頻繁或者緩存刷新的流程耗時(shí)較長(zhǎng)的情況下染厅,可以利用定時(shí)線程在緩存過(guò)期前主動(dòng)的重新構(gòu)建緩存或者延后緩存的過(guò)期時(shí)間,以保證所有的請(qǐng)求能一直訪問(wèn)到對(duì)應(yīng)的緩存津函。

#緩存雪崩

緩存雪崩是指緩存重啟或者大量的緩存數(shù)據(jù)集中在某一時(shí)間內(nèi)失效肖粮,導(dǎo)致所有請(qǐng)求完全打到數(shù)據(jù)庫(kù),造成數(shù)據(jù)庫(kù)負(fù)載巨大、壓垮尔苦。

緩存使用實(shí)踐

緩存系統(tǒng)在使用過(guò)程中涩馆,從配置、使用允坚、監(jiān)控等手段都是必須的魂那。下面對(duì)在使用過(guò)程中實(shí)踐進(jìn)行總結(jié)。

  1. 應(yīng)用數(shù)據(jù)緩存大小評(píng)估屋讶。包括數(shù)據(jù)結(jié)構(gòu)冰寻、緩存大小、緩存數(shù)量皿渗、緩存失效時(shí)間斩芭,然后根據(jù)業(yè)務(wù)情況推算在未來(lái)一段時(shí)間內(nèi)的容量。
  2. 根據(jù)需要的內(nèi)存大小劃分緩存實(shí)例數(shù)量乐疆。
  3. 緩存數(shù)據(jù)超時(shí)划乖。緩存數(shù)據(jù)在正常情況下必須設(shè)置合理過(guò)期時(shí)間,并且不可以設(shè)置為集中的某一時(shí)刻過(guò)期挤土,防止緩存雪崩琴庵,導(dǎo)致服務(wù)拖垮、雪崩。
  4. 建議業(yè)務(wù)隔離迷殿。核心業(yè)務(wù)與非核心業(yè)務(wù)使用不同的緩存集群儿礼,減少相互影響。由于成本問(wèn)題無(wú)法隔離庆寺,規(guī)范各個(gè)應(yīng)用的Key有唯一的前綴蚊夫,避免緩存覆蓋問(wèn)題。
  5. 實(shí)例監(jiān)控懦尝。對(duì)慢查詢知纷、大對(duì)像、內(nèi)存使用情況陵霉、集群健康情況做可靠的監(jiān)控琅轧。
  6. 緩存熱點(diǎn)數(shù)據(jù)。緩存的數(shù)據(jù)應(yīng)該為熱點(diǎn)數(shù)據(jù)踊挠,低頻數(shù)據(jù)不建議放置在緩存中乍桂。
  7. 緩存的數(shù)據(jù)大小。緩存的數(shù)據(jù)大小不能過(guò)大止毕,必須控制在合理的范圍內(nèi)模蜡。
  8. 集合操作。對(duì)大集合不能直接GETALL扁凛,會(huì)導(dǎo)致阻塞。如Redis應(yīng)該使用SCAN闯传。
  9. 寫(xiě)時(shí)數(shù)據(jù)必須完整谨朝。緩存的數(shù)據(jù)更新必須是全量、全整更新甥绿。
  10. 緩存降級(jí)字币。緩存必須有降級(jí)處理,避免緩存全完崩潰時(shí)系統(tǒng)直接不可用共缕。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末洗出,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子图谷,更是在濱河造成了極大的恐慌翩活,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件便贵,死亡現(xiàn)場(chǎng)離奇詭異菠镇,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)承璃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)利耍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事隘梨〕贪” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵轴猎,是天一觀的道長(zhǎng)席楚。 經(jīng)常有香客問(wèn)我,道長(zhǎng)税稼,這世上最難降的妖魔是什么烦秩? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮郎仆,結(jié)果婚禮上只祠,老公的妹妹穿的比我還像新娘。我一直安慰自己扰肌,他們只是感情好抛寝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著曙旭,像睡著了一般盗舰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桂躏,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天钻趋,我揣著相機(jī)與錄音,去河邊找鬼剂习。 笑死蛮位,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鳞绕。 我是一名探鬼主播失仁,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼们何!你這毒婦竟也來(lái)了萄焦?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤冤竹,失蹤者是張志新(化名)和其女友劉穎拂封,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體贴见,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烘苹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了片部。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片镣衡。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡霜定,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出廊鸥,到底是詐尸還是另有隱情望浩,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布惰说,位于F島的核電站磨德,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏吆视。R本人自食惡果不足惜典挑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望啦吧。 院中可真熱鬧您觉,春花似錦、人聲如沸授滓。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)般堆。三九已至在孝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淮摔,已是汗流浹背私沮。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留噩咪,地道東北人顾彰。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像胃碾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子筋搏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

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