深入理解Redis(二)----使用緩存可能遇到的問題和解決方案(緩存穿透木西、緩存雪崩)

一、緩存穿透

緩存穿透是指查詢一個(gè)根本不存在的數(shù)據(jù)随静,緩存層和存儲(chǔ)層都不會(huì)命中八千,通常出于容錯(cuò)的考慮,如果從存儲(chǔ)層查不到數(shù)據(jù)則不寫入緩存層燎猛,如圖11-3所示整個(gè)過程分為如下3步:
1)緩存層不命中恋捆。

2)存儲(chǔ)層不命中,不將空結(jié)果寫回緩存重绷。

3)返回空結(jié)果沸停。
緩存穿透將導(dǎo)致不存在的數(shù)據(jù)每次請(qǐng)求都要到存儲(chǔ)層去查詢,失去了緩存保護(hù)后端存儲(chǔ)的意義论寨。緩存穿透問題可能會(huì)使后端存儲(chǔ)負(fù)載加大星立,由于很多后端存儲(chǔ)不具備高并發(fā)性,甚至可能造成后端存儲(chǔ)宕掉葬凳。通炒麓梗可以在程序中分別統(tǒng)計(jì)總調(diào)用數(shù)、緩存層命中數(shù)火焰、存儲(chǔ)層命中數(shù)劲装,如果發(fā)現(xiàn)大量存儲(chǔ)層空命中,可能就是出現(xiàn)了緩存穿透問題。

造成緩存穿透的基本原因有兩個(gè):

①自身業(yè)務(wù)代碼或者數(shù)據(jù)出現(xiàn)問題

②一些惡意攻擊占业、爬蟲等造成大量空命中

如何解決緩存穿透問題绒怨,實(shí)際上這是一個(gè)開放問題,有很多解決方法谦疾。下面是兩種典型的解決方案:

\color{red}{1.緩存空對(duì)象}

當(dāng)存儲(chǔ)層不命中后南蹂,仍然將空對(duì)象保留到緩存層中,之后再訪問這個(gè)數(shù)據(jù)將會(huì)從緩存中獲取念恍,這樣就保護(hù)了后端數(shù)據(jù)源六剥。

image

下面是緩存空對(duì)象的代碼實(shí)現(xiàn):

String get(String key) {
    // 從緩存中獲取數(shù)據(jù)
    String cacheValue = cache.get(key);
    // 緩存為空
    if (StringUtils.isBlank(cacheValue)) {
        // 從存儲(chǔ)中獲取
        String storageValue = storage.get(key);
        cache.set(key, storageValue);
        // 如果存儲(chǔ)數(shù)據(jù)為空,需要設(shè)置一個(gè)過期時(shí)間(300秒)
        if (storageValue == null) {
            cache.expire(key, 60 * 5);
        }
        return storageValue;
    } else {
        // 緩存非空
        return cacheValue;
    }
}

緩存空對(duì)象會(huì)有兩個(gè)問題:

①空值做了緩存峰伙,意味著緩存層中存了更多的鍵疗疟,需要更多的內(nèi)存空間(如果是攻擊,問題更嚴(yán)重)瞳氓,比較有效的方法是針對(duì)這類數(shù)據(jù)設(shè)置一個(gè)較短的過期時(shí)間策彤,讓其自動(dòng)剔除。

②緩存層和存儲(chǔ)層的數(shù)據(jù)會(huì)有一段時(shí)間窗口的不一致匣摘,可能會(huì)對(duì)業(yè)務(wù)有一定影響店诗。例如過期時(shí)間設(shè)置為5分鐘,如果此時(shí)存儲(chǔ)層添加了這個(gè)數(shù)據(jù)恋沃,那此段時(shí)間就會(huì)出現(xiàn)緩存層和存儲(chǔ)層數(shù)據(jù)的不一致必搞,此時(shí)可以利用消息系統(tǒng)或者其他方式清除掉緩存層中的空對(duì)象。

\color{red}{2.布隆過濾器攔截}

在訪問緩存層和存儲(chǔ)層之前囊咏,將存在的key用布隆過濾器提前保存起來,做第一層攔截塔橡。例如:一個(gè)推薦系統(tǒng)有4億個(gè)用戶id梅割,每個(gè)小時(shí)算法工程師會(huì)根據(jù)每個(gè)用戶之前歷史行為計(jì)算出推薦數(shù)據(jù)放到存儲(chǔ)層中,但是最新的用戶由于沒有歷史行為葛家,就會(huì)發(fā)生緩存穿透的行為户辞,為此可以將所有推薦數(shù)據(jù)的用戶做成布隆過濾器。如果布隆過濾器認(rèn)為該用戶id不存在癞谒,那么就不會(huì)訪問存儲(chǔ)層底燎,在一定程度保護(hù)了存儲(chǔ)層。

布隆過濾器的相關(guān)知識(shí)可以參考https://en.wikipedia.org/wiki/Bloom_filter弹砚∷裕可以利用Redis的Bitmaps實(shí)現(xiàn)布隆過濾器,GitHub上已經(jīng)開源了類似的方案桌吃,可以參考:https://github.com/erikdubbelboer/redis-lua-scaling-bloom-filter朱沃。這種方法適用于數(shù)據(jù)命中不高、數(shù)據(jù)相對(duì)固定、實(shí)時(shí)性低(通常是數(shù)據(jù)集較大)的應(yīng)用場(chǎng)景逗物,代碼維護(hù)較為復(fù)雜搬卒,但是緩存空間占用少。

(3)兩種方案的對(duì)比


二翎卓、緩存雪崩

由于緩存層承載著大量請(qǐng)求契邀,有效地保護(hù)了存儲(chǔ)層,但是如果緩存層由于某些原因不能提供服務(wù)失暴,于是所有的請(qǐng)求都會(huì)達(dá)到存儲(chǔ)層蹂安,存儲(chǔ)層的調(diào)用量會(huì)暴增,造成存儲(chǔ)層也會(huì)級(jí)聯(lián)宕機(jī)的情況锐帜。緩存雪崩的英文原意是stampeding herd(奔逃的野牛)田盈,指的是緩存層宕掉后,流量會(huì)像奔逃的野牛一樣缴阎,打向后端存儲(chǔ)允瞧。

image

預(yù)防和解決緩存雪崩問題,可以從以下三個(gè)方面進(jìn)行著手蛮拔。

\color{red}{1.提前演練}

在項(xiàng)目上線前述暂,演練緩存層宕掉后,應(yīng)用以及后端的負(fù)載情況以及可能出現(xiàn)的問題建炫,在此基礎(chǔ)上做一些預(yù)案設(shè)定畦韭。

\color{red}{2.保證緩存層服務(wù)高可用性}

和飛機(jī)都有多個(gè)引擎一樣,如果緩存層設(shè)計(jì)成高可用的肛跌,即使個(gè)別節(jié)點(diǎn)艺配、個(gè)別機(jī)器、甚至是機(jī)房宕掉衍慎,依然可以提供服務(wù)转唉,例如前面介紹過的Redis Sentinel和Redis Cluster都實(shí)現(xiàn)了高可用。

\color{red}{3.依賴隔離組件為后端限流并降級(jí)}

無論是緩存層還是存儲(chǔ)層都會(huì)有出錯(cuò)的概率稳捆,可以將它們視同為資源赠法。作為并發(fā)量較大的系統(tǒng),假如有一個(gè)資源不可用乔夯,可能會(huì)造成線程全部阻塞(hang)在這個(gè)資源上砖织,造成整個(gè)系統(tǒng)不可用。降級(jí)機(jī)制在高并發(fā)系統(tǒng)中是非常普遍的:比如推薦服務(wù)中末荐,如果個(gè)性化推薦服務(wù)不可用侧纯,可以降級(jí)補(bǔ)充熱點(diǎn)數(shù)據(jù),不至于造成前端頁面是開天窗鞠评。在實(shí)際項(xiàng)目中茂蚓,我們需要對(duì)重要的資源(例如Redis、MySQL、HBase聋涨、外部接口)都進(jìn)行隔離晾浴,讓每種資源都單獨(dú)運(yùn)行在自己的線程池中,即使個(gè)別資源出現(xiàn)了問題牍白,對(duì)其他服務(wù)沒有影響脊凰。但是線程池如何管理,比如如何關(guān)閉資源池茂腥、開啟資源池狸涌、資源池閥值管理,這些做起來還是相當(dāng)復(fù)雜的最岗。這里推薦一個(gè)Java依賴隔離工具Hystrix帕胆,如圖11-15所示。Hystrix是解決依賴隔離的利器般渡,只適用于Java應(yīng)用懒豹。

事前: 項(xiàng)目上線前提前演練,做好預(yù)案驯用;
事中: ①高可用集群(sentinel/cluster)脸秽,避免緩存全盤崩潰。 ②本地緩存+限流&降級(jí)(hystrix)蝴乔,避免mysql被拖垮记餐。(可以通過限流組件設(shè)置讓多少請(qǐng)求進(jìn)入,比如來了5000請(qǐng)求薇正,讓2000通過片酝,進(jìn)入數(shù)據(jù)庫,剩余請(qǐng)求走降級(jí)铝穷,限流組件會(huì)調(diào)用你自己開發(fā)好的一個(gè)降級(jí)組件钠怯,返回一些默認(rèn)值,友情提示等) 【這樣能保證數(shù)據(jù)庫不會(huì)死曙聂。能保證2/5的請(qǐng)求可以被處理,也就是說用戶點(diǎn)5次可能有幾次刷不出來頁面鞠鲜∧梗】
事后: 借助持久化,快速恢復(fù)贤姆。</textarea>


三榆苞、緩存并發(fā)競(jìng)爭(zhēng)

多客戶端同時(shí)并發(fā)寫一個(gè)key,可能本來應(yīng)該先到的數(shù)據(jù)后到了霞捡,導(dǎo)致數(shù)據(jù)版本錯(cuò)了坐漏。或者是多客戶端同時(shí)獲取一個(gè)key,修改值之后再寫回去赊琳,只要順序錯(cuò)了街夭,數(shù)據(jù)就錯(cuò)了。

image

解決方法:

1.分布式鎖+時(shí)間戳

主要是使用一個(gè)分布式鎖躏筏,大家去搶鎖板丽,搶到鎖就做set操作。加鎖的目的實(shí)際上就是把并行讀寫改成串行讀寫的方式趁尼,從而來避免資源競(jìng)爭(zhēng)埃碱。

我們線上常用的是zookeeper的分布式鎖,用redis自身的分布式鎖也可以實(shí)現(xiàn)酥泞,但是我們很少這樣做砚殿。

另外,Redis自己就有天然解決這個(gè)問題的CAS類的樂觀鎖方案芝囤∷蒲祝基于redis的分布式鎖主要用到的是setnx。

2.利用消息隊(duì)列

在并發(fā)量過大的情況下,可以通過消息中間件進(jìn)行處理凡人,把并行讀寫進(jìn)行串行化名党。把Redis.set操作放在隊(duì)列中使其串行化,必須的一個(gè)一個(gè)執(zhí)行。這種方式在一些高并發(fā)的場(chǎng)景中算是一種通用的解決方案挠轴。


四传睹、緩存與數(shù)據(jù)庫雙寫一致性

1.Cache-Aside Pattern

最經(jīng)典的緩存+數(shù)據(jù)庫讀寫的模式,Cache-Aside Pattern岸晦,可以參考微軟官網(wǎng)的介紹:Cache-Aside Pattern(翻譯)

Cache-Aside Pattern總結(jié)起來就是下面兩句話:

(1)讀的時(shí)候:先讀緩存欧啤,如果緩存中沒有,就讀數(shù)據(jù)庫启上,然后取出數(shù)據(jù)后放入緩存邢隧,同時(shí)返回響應(yīng)

(2)更新的時(shí)候:先刪除緩存,然后再更新數(shù)據(jù)庫

2.操作緩存時(shí)是先操作數(shù)據(jù)庫還是先操作緩存冈在?操作緩存是刪除緩存倒慧,還是更新緩存?

參考:究竟先操作緩存包券,還是數(shù)據(jù)庫纫谅?

讀緩存的情況,應(yīng)該先讀緩存溅固,再讀數(shù)據(jù)庫付秕,這點(diǎn)是沒有疑問的 。而寫緩存的情況就有點(diǎn)復(fù)雜了侍郭,可以看下面這幅圖询吴。

對(duì)于刪除緩存的方案掠河,當(dāng)緩存刪除后,客戶端如果再次需要訪問相關(guān)數(shù)據(jù)時(shí)猛计,由于緩存中沒有唠摹,就會(huì)通過走數(shù)據(jù)庫,最終再放入緩存中有滑。

另外需要說明的是跃闹,緩存中的數(shù)據(jù)有時(shí)可能就是一張表中的某個(gè)字段的值,而有時(shí)可能是多張表進(jìn)行復(fù)雜計(jì)算后生成的一個(gè)最終值毛好。

3.庫存案例

以庫存服務(wù)來說明說明更新緩存的操作望艺。庫存服務(wù)特點(diǎn)是實(shí)時(shí)性比較高,也會(huì)用到緩存肌访,會(huì)將庫存數(shù)據(jù)放在緩存中找默。

如何保證數(shù)據(jù)庫和緩存中的庫存數(shù)據(jù)的雙寫一致性?

(1)最初級(jí)的解決方案

也就是使用前面提到的:操作緩存時(shí)吼驶,先刪除緩存惩激,在更新數(shù)據(jù)庫。

(2)將數(shù)據(jù)庫與緩存更新與讀取操作進(jìn)行異步串行化

image

隊(duì)列頭部的寫請(qǐng)求操作可能20ms完成蟹演,之后的讀請(qǐng)求可能會(huì)hang住40ms风钻,之后也可能花費(fèi)20ms完成讀操作。

高并發(fā)的場(chǎng)景下酒请,該解決方案要注意的問題
(1)讀請(qǐng)求長時(shí)阻塞
由于讀請(qǐng)求進(jìn)行了非常輕度的異步化骡技,所以一定要注意讀超時(shí)的問題,每個(gè)讀請(qǐng)求必須在超時(shí)時(shí)間范圍內(nèi)返回

該解決方案羞反,最大的風(fēng)險(xiǎn)點(diǎn)在于說布朦,可能數(shù)據(jù)更新很頻繁,導(dǎo)致隊(duì)列中積壓了大量更新操作在里面昼窗,然后讀請(qǐng)求會(huì)發(fā)生大量的超時(shí)是趴,最后導(dǎo)致大量的請(qǐng)求直接走數(shù)據(jù)庫。

務(wù)必通過一些模擬真實(shí)的測(cè)試澄惊,看看更新數(shù)據(jù)的頻繁是怎樣的

另外一點(diǎn)唆途,因?yàn)橐粋€(gè)隊(duì)列中,可能會(huì)積壓針對(duì)多個(gè)數(shù)據(jù)項(xiàng)的更新操作掸驱,因此需要根據(jù)自己的業(yè)務(wù)情況進(jìn)行測(cè)試窘哈,可能需要部署多個(gè)服務(wù),每個(gè)服務(wù)分?jǐn)傄恍?shù)據(jù)的更新操作

如果一個(gè)內(nèi)存隊(duì)列里居然會(huì)擠壓100個(gè)商品的庫存修改操作亭敢,每隔庫存修改操作要耗費(fèi)10ms區(qū)完成,那么最后一個(gè)商品的讀請(qǐng)求图筹,可能等待10 * 100 = 1000ms = 1s后帅刀,才能得到數(shù)據(jù)让腹,這個(gè)時(shí)候就導(dǎo)致讀請(qǐng)求的長時(shí)阻塞

一定要做根據(jù)實(shí)際業(yè)務(wù)系統(tǒng)的運(yùn)行情況,去進(jìn)行一些壓力測(cè)試扣溺,和模擬線上環(huán)境骇窍,去看看最繁忙的時(shí)候,內(nèi)存隊(duì)列可能會(huì)擠壓多少更新操作锥余,可能會(huì)導(dǎo)致最后一個(gè)更新操作對(duì)應(yīng)的讀請(qǐng)求腹纳,會(huì)hang多少時(shí)間,如果讀請(qǐng)求在200ms返回驱犹,如果你計(jì)算過后嘲恍,哪怕是最繁忙的時(shí)候,積壓10個(gè)更新操作雄驹,最多等待200ms佃牛,那還可以的。

如果一個(gè)內(nèi)存隊(duì)列可能積壓的更新操作特別多医舆,那么你就要加機(jī)器俘侠,讓每個(gè)機(jī)器上部署的服務(wù)實(shí)例處理更少的數(shù)據(jù),那么每個(gè)內(nèi)存隊(duì)列中積壓的更新操作就會(huì)越少

其實(shí)根據(jù)之前的項(xiàng)目經(jīng)驗(yàn)蔬将,一般來說數(shù)據(jù)的寫頻率是很低的爷速,因此實(shí)際上正常來說,在隊(duì)列中積壓的更新操作應(yīng)該是很少的

針對(duì)讀高并發(fā)霞怀,讀緩存架構(gòu)的項(xiàng)目惫东,一般寫請(qǐng)求相對(duì)讀來說,是非常非常少的里烦,每秒的QPS能到幾百就不錯(cuò)了

一秒凿蒜,500的寫操作,5份胁黑,每200ms废封,就100個(gè)寫操作

單機(jī)器,20個(gè)內(nèi)存隊(duì)列丧蘸,每個(gè)內(nèi)存隊(duì)列漂洋,可能就積壓5個(gè)寫操作,每個(gè)寫操作性能測(cè)試后力喷,一般在20ms左右就完成

那么針對(duì)每個(gè)內(nèi)存隊(duì)列中的數(shù)據(jù)的讀請(qǐng)求刽漂,也就最多hang一會(huì)兒,200ms以內(nèi)肯定能返回了

寫QPS擴(kuò)大10倍弟孟,但是經(jīng)過剛才的測(cè)算贝咙,就知道,單機(jī)支撐寫QPS幾百?zèng)]問題拂募,那么就擴(kuò)容機(jī)器庭猩,擴(kuò)容10倍的機(jī)器窟她,10臺(tái)機(jī)器,每個(gè)機(jī)器20個(gè)隊(duì)列蔼水,200個(gè)隊(duì)列

大部分的情況下震糖,應(yīng)該是這樣的,大量的讀請(qǐng)求過來趴腋,都是直接走緩存取到數(shù)據(jù)的

少量情況下吊说,可能遇到讀跟數(shù)據(jù)更新沖突的情況,如上所述优炬,那么此時(shí)更新操作如果先入隊(duì)列颁井,之后可能會(huì)瞬間來了對(duì)這個(gè)數(shù)據(jù)大量的讀請(qǐng)求,但是因?yàn)樽隽巳ブ氐膬?yōu)化穿剖,所以也就一個(gè)更新緩存的操作跟在它后面

等數(shù)據(jù)更新完了蚤蔓,讀請(qǐng)求觸發(fā)的緩存更新操作也完成,然后臨時(shí)等待的讀請(qǐng)求全部可以讀到緩存中的數(shù)據(jù)

(2)讀請(qǐng)求并發(fā)量過高

這里還必須做好壓力測(cè)試糊余,確保恰巧碰上上述情況的時(shí)候秀又,還有一個(gè)風(fēng)險(xiǎn),就是突然間大量讀請(qǐng)求會(huì)在幾十毫秒的延時(shí)hang在服務(wù)上贬芥,看服務(wù)能不能抗的住吐辙,需要多少機(jī)器才能抗住最大的極限情況的峰值

但是因?yàn)椴⒉皇撬械臄?shù)據(jù)都在同一時(shí)間更新,緩存也不會(huì)同一時(shí)間失效蘸劈,所以每次可能也就是少數(shù)數(shù)據(jù)的緩存失效了昏苏,然后那些數(shù)據(jù)對(duì)應(yīng)的讀請(qǐng)求過來,并發(fā)量應(yīng)該也不會(huì)特別大

按1:99的比例計(jì)算讀和寫的請(qǐng)求威沫,每秒5萬的讀QPS贤惯,可能只有500次更新操作

如果一秒有500的寫QPS,那么要測(cè)算好棒掠,可能寫操作影響的數(shù)據(jù)有500條孵构,這500條數(shù)據(jù)在緩存中失效后,可能導(dǎo)致多少讀請(qǐng)求烟很,發(fā)送讀請(qǐng)求到庫存服務(wù)來颈墅,要求更新緩存

一般來說,1:1雾袱,1:2恤筛,1:3,每秒鐘有1000個(gè)讀請(qǐng)求芹橡,會(huì)hang在庫存服務(wù)上毒坛,每個(gè)讀請(qǐng)求最多hang多少時(shí)間,200ms就會(huì)返回

在同一時(shí)間最多hang住的可能也就是單機(jī)200個(gè)讀請(qǐng)求林说,同時(shí)hang住

單機(jī)hang200個(gè)讀請(qǐng)求粘驰,還是ok的 1:20屡谐,每秒更新500條數(shù)據(jù),這500秒數(shù)據(jù)對(duì)應(yīng)的讀請(qǐng)求蝌数,會(huì)有20 * 500 = 1萬

1萬個(gè)讀請(qǐng)求全部hang在庫存服務(wù)上,就死定了

(3)【多服務(wù)實(shí)例部署的請(qǐng)求路由】

可能這個(gè)服務(wù)部署了多個(gè)實(shí)例度秘,那么必須保證執(zhí)行數(shù)據(jù)更新操作顶伞,以及執(zhí)行緩存更新操作的請(qǐng)求,都通過nginx服務(wù)器路由到相同的服務(wù)實(shí)例上

(4)熱點(diǎn)商品的路由問題剑梳,導(dǎo)致請(qǐng)求的傾斜

萬一某個(gè)商品的讀寫請(qǐng)求特別高唆貌,全部打到相同的機(jī)器的相同的隊(duì)列里面去了,可能造成某臺(tái)機(jī)器的壓力過大

就是說垢乙,因?yàn)橹挥性谏唐窋?shù)據(jù)更新的時(shí)候才會(huì)清空緩存锨咙,然后才會(huì)導(dǎo)致讀寫并發(fā),所以更新頻率不是太高的話追逮,這個(gè)問題的影響并不是特別大

但是的確可能某些機(jī)器的負(fù)載會(huì)高一些


引用(本文章只供本人學(xué)習(xí)以及學(xué)習(xí)的記錄酪刀,如有侵權(quán),請(qǐng)聯(lián)系我刪除)

使用緩存可能遇到的問題和解決方案(緩存穿透钮孵、緩存雪崩)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末骂倘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子巴席,更是在濱河造成了極大的恐慌历涝,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漾唉,死亡現(xiàn)場(chǎng)離奇詭異荧库,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)赵刑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門分衫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人料睛,你說我怎么就攤上這事丐箩。” “怎么了恤煞?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵屎勘,是天一觀的道長。 經(jīng)常有香客問我居扒,道長概漱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任喜喂,我火速辦了婚禮瓤摧,結(jié)果婚禮上竿裂,老公的妹妹穿的比我還像新娘。我一直安慰自己照弥,他們只是感情好腻异,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著这揣,像睡著了一般悔常。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上给赞,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天机打,我揣著相機(jī)與錄音,去河邊找鬼片迅。 笑死残邀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的柑蛇。 我是一名探鬼主播芥挣,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼唯蝶!你這毒婦竟也來了九秀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤粘我,失蹤者是張志新(化名)和其女友劉穎鼓蜒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體征字,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡都弹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了匙姜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畅厢。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖氮昧,靈堂內(nèi)的尸體忽然破棺而出框杜,到底是詐尸還是另有隱情,我是刑警寧澤袖肥,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布咪辱,位于F島的核電站,受9級(jí)特大地震影響椎组,放射性物質(zhì)發(fā)生泄漏油狂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望专筷。 院中可真熱鬧弱贼,春花似錦、人聲如沸磷蛹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弦聂。三九已至鸟辅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間莺葫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工枪眉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捺檬,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓贸铜,卻偏偏與公主長得像堡纬,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蒿秦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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