Redis進(jìn)階 - 緩存問題:一致性苞也、穿擊、穿透殷勘、雪崩输拇、污染等.

image

01 為什么要理解Redis緩存問題?

在高并發(fā)的業(yè)務(wù)場(chǎng)景下奴曙,數(shù)據(jù)庫(kù)大多數(shù)情況都是用戶并發(fā)訪問最薄弱的環(huán)節(jié)。所以坤溃,就需要使用redis做一個(gè)緩沖操作,讓請(qǐng)求先訪問到redis嘱丢,而不是直接訪問Mysql等數(shù)據(jù)庫(kù)薪介。這樣可以大大緩解數(shù)據(jù)庫(kù)的壓力。

當(dāng)緩存庫(kù)出現(xiàn)時(shí)越驻,必須要考慮如下問題:

  • 緩存穿透
  • 緩存穿擊
  • 緩存雪崩
  • 緩存污染(或者滿了)
  • 緩存和數(shù)據(jù)庫(kù)一致性

02 緩存穿透

  • 問題來源

緩存穿透是指緩存和數(shù)據(jù)庫(kù)中都沒有的數(shù)據(jù)汁政,而用戶不斷發(fā)起請(qǐng)求。由于緩存是不命中時(shí)被動(dòng)寫的缀旁,并且出于容錯(cuò)考慮记劈,如果從存儲(chǔ)層查不到數(shù)據(jù)則不寫入緩存,這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請(qǐng)求都要到存儲(chǔ)層去查詢目木,失去了緩存的意義誓禁。

在流量大時(shí)骇两,可能DB就掛掉了示血,要是有人利用不存在的key頻繁攻擊我們的應(yīng)用,這就是漏洞。

如發(fā)起為id為“-1”的數(shù)據(jù)或id為特別大不存在的數(shù)據(jù)。這時(shí)的用戶很可能是攻擊者烈疚,攻擊會(huì)導(dǎo)致數(shù)據(jù)庫(kù)壓力過大金赦。

  • 解決方案
  1. 接口層增加校驗(yàn),如用戶鑒權(quán)校驗(yàn)珊楼,id做基礎(chǔ)校驗(yàn)已慢,id<=0的直接攔截乍丈;
  2. 從緩存取不到的數(shù)據(jù),在數(shù)據(jù)庫(kù)中也沒有取到亚兄,這時(shí)也可以將key-value對(duì)寫為key-null洽洁,緩存有效時(shí)間可以設(shè)置短點(diǎn),如30秒(設(shè)置太長(zhǎng)會(huì)導(dǎo)致正常情況也沒法使用)。這樣可以防止攻擊用戶反復(fù)用同一個(gè)id暴力攻擊
  3. 布隆過濾器攒盈。bloomfilter就類似于一個(gè)hash set飘言,用于快速判某個(gè)元素是否存在于集合中句狼,其典型的應(yīng)用場(chǎng)景就是快速判斷一個(gè)key是否存在于某容器,不存在就直接返回铡俐。布隆過濾器的關(guān)鍵就在于hash算法和容器大小,

03 緩存擊穿

  • 問題來源

緩存擊穿是指緩存中沒有但數(shù)據(jù)庫(kù)中有的數(shù)據(jù)(一般是緩存時(shí)間到期),這時(shí)由于并發(fā)用戶特別多,同時(shí)讀緩存沒讀到數(shù)據(jù),又同時(shí)去數(shù)據(jù)庫(kù)去取數(shù)據(jù)偎痛,引起數(shù)據(jù)庫(kù)壓力瞬間增大,造成過大壓力娜膘。

  • 解決方案

1、設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過期甘桑。

2咆耿、接口限流與熔斷吻商,降級(jí)。重要的接口一定要做好限流策略,防止用戶惡意刷接口夹厌,同時(shí)要降級(jí)準(zhǔn)備豹爹,當(dāng)接口中的某些 服務(wù) 不可用時(shí)候,進(jìn)行熔斷矛纹,失敗快速返回機(jī)制臂聋。

3、加互斥鎖

04 緩存雪崩

  • 問題來源

緩存雪崩是指緩存中數(shù)據(jù)大批量到過期時(shí)間或南,而查詢數(shù)據(jù)量巨大孩等,引起數(shù)據(jù)庫(kù)壓力過大甚至down機(jī)。和緩存擊穿不同的是采够,緩存擊穿指并發(fā)查同一條數(shù)據(jù)肄方,緩存雪崩是不同數(shù)據(jù)都過期了,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫(kù)吁恍。

  • 解決方案
  1. 緩存數(shù)據(jù)的過期時(shí)間設(shè)置隨機(jī)扒秸,防止同一時(shí)間大量數(shù)據(jù)過期現(xiàn)象發(fā)生。
  2. 如果緩存數(shù)據(jù)庫(kù)是分布式部署冀瓦,將熱點(diǎn)數(shù)據(jù)均勻分布在不同的緩存數(shù)據(jù)庫(kù)中伴奥。
  3. 設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過期。

05 緩存污染(或滿了)

緩存污染問題說的是緩存中一些只會(huì)被訪問一次或者幾次的的數(shù)據(jù)翼闽,被訪問完后拾徙,再也不會(huì)被訪問到,但這部分?jǐn)?shù)據(jù)依然留存在緩存中感局,消耗緩存空間尼啡。

緩存污染會(huì)隨著數(shù)據(jù)的持續(xù)增加而逐漸顯露暂衡,隨著服務(wù)的不斷運(yùn)行,緩存中會(huì)存在大量的永遠(yuǎn)不會(huì)再次被訪問的數(shù)據(jù)崖瞭。緩存空間是有限的狂巢,如果緩存空間滿了,再往緩存里寫數(shù)據(jù)時(shí)就會(huì)有額外開銷书聚,影響Redis性能唧领。這部分額外開銷主要是指寫的時(shí)候判斷淘汰策略,根據(jù)淘汰策略去選擇要淘汰的數(shù)據(jù)雌续,然后進(jìn)行刪除操作斩个。

5.1 最大緩存設(shè)置多大

系統(tǒng)的設(shè)計(jì)選擇是一個(gè)權(quán)衡的過程:大容量緩存是能帶來性能加速的收益,但是成本也會(huì)更高驯杜,而小容量緩存不一定就起不到加速訪問的效果受啥。一般來說,我會(huì)建議把緩存容量設(shè)置為總數(shù)據(jù)量的 15% 到 30%鸽心,兼顧訪問性能和內(nèi)存空間開銷滚局。

對(duì)于 Redis 來說,一旦確定了緩存最大容量再悼,比如 4GB核畴,你就可以使用下面這個(gè)命令來設(shè)定緩存的大小了:

CONFIG SET maxmemory 4gb

        @pdai: 代碼已經(jīng)復(fù)制到剪貼板

不過,緩存被寫滿是不可避免的, 所以需要數(shù)據(jù)淘汰策略冲九。

5.2 緩存淘汰策略

Redis共支持八種淘汰策略谤草,分別是noeviction、volatile-random莺奸、volatile-ttl丑孩、volatile-lru、volatile-lfu灭贷、allkeys-lru温学、allkeys-random 和 allkeys-lfu 策略。

怎么理解呢甚疟?主要看分三類看:

  • 不淘汰

  • noeviction (v4.0后默認(rèn)的)

  • 對(duì)設(shè)置了過期時(shí)間的數(shù)據(jù)中進(jìn)行淘汰

  • 隨機(jī):volatile-random

  • ttl:volatile-ttl

  • lru:volatile-lru

  • lfu:volatile-lfu

  • 全部數(shù)據(jù)進(jìn)行淘汰

  • 隨機(jī):allkeys-random

  • lru:allkeys-lru

  • lfu:allkeys-lfu

具體對(duì)照下:

  1. noeviction

該策略是Redis的默認(rèn)策略仗岖。在這種策略下,一旦緩存被寫滿了览妖,再有寫請(qǐng)求來時(shí)轧拄,Redis 不再提供服務(wù),而是直接返回錯(cuò)誤讽膏。這種策略不會(huì)淘汰數(shù)據(jù)檩电,所以無法解決緩存污染問題。一般生產(chǎn)環(huán)境不建議使用。

其他七種規(guī)則都會(huì)根據(jù)自己相應(yīng)的規(guī)則來選擇數(shù)據(jù)進(jìn)行刪除操作俐末。

  1. volatile-random

這個(gè)算法比較簡(jiǎn)單料按,在設(shè)置了過期時(shí)間的鍵值對(duì)中,進(jìn)行隨機(jī)刪除卓箫。因?yàn)槭请S機(jī)刪除载矿,無法把不再訪問的數(shù)據(jù)篩選出來,所以可能依然會(huì)存在緩存污染現(xiàn)象烹卒,無法解決緩存污染問題恢准。

  1. volatile-ttl

這種算法判斷淘汰數(shù)據(jù)時(shí)參考的指標(biāo)比隨即刪除時(shí)多進(jìn)行一步過期時(shí)間的排序。Redis在篩選需刪除的數(shù)據(jù)時(shí)甫题,越早過期的數(shù)據(jù)越優(yōu)先被選擇。

  1. volatile-lru

LRU算法:LRU 算法的全稱是 Least Recently Used涂召,按照最近最少使用的原則來篩選數(shù)據(jù)坠非。這種模式下會(huì)使用 LRU 算法篩選設(shè)置了過期時(shí)間的鍵值對(duì)。

Redis優(yōu)化的LRU算法實(shí)現(xiàn)

Redis會(huì)記錄每個(gè)數(shù)據(jù)的最近一次被訪問的時(shí)間戳果正。在Redis在決定淘汰的數(shù)據(jù)時(shí)炎码,第一次會(huì)隨機(jī)選出 N 個(gè)數(shù)據(jù),把它們作為一個(gè)候選集合秋泳。接下來潦闲,Redis 會(huì)比較這 N 個(gè)數(shù)據(jù)的 lru 字段,把 lru 字段值最小的數(shù)據(jù)從緩存中淘汰出去迫皱。通過隨機(jī)讀取待刪除集合歉闰,可以讓Redis不用維護(hù)一個(gè)巨大的鏈表,也不用操作鏈表卓起,進(jìn)而提升性能和敬。

Redis 選出的數(shù)據(jù)個(gè)數(shù) N,通過 配置參數(shù) maxmemory-samples 進(jìn)行配置戏阅。個(gè)數(shù)N越大昼弟,則候選集合越大,選擇到的最久未被使用的就更準(zhǔn)確奕筐,N越小舱痘,選擇到最久未被使用的數(shù)據(jù)的概率也會(huì)隨之減小。

  1. volatile-lfu

會(huì)使用 LFU 算法選擇設(shè)置了過期時(shí)間的鍵值對(duì)离赫。

LFU 算法:LFU 緩存策略是在 LRU 策略基礎(chǔ)上芭逝,為每個(gè)數(shù)據(jù)增加了一個(gè)計(jì)數(shù)器,來統(tǒng)計(jì)這個(gè)數(shù)據(jù)的訪問次數(shù)笆怠。當(dāng)使用 LFU 策略篩選淘汰數(shù)據(jù)時(shí)铝耻,首先會(huì)根據(jù)數(shù)據(jù)的訪問次數(shù)進(jìn)行篩選,把訪問次數(shù)最低的數(shù)據(jù)淘汰出緩存。如果兩個(gè)數(shù)據(jù)的訪問次數(shù)相同瓢捉,LFU 策略再比較這兩個(gè)數(shù)據(jù)的訪問時(shí)效性频丘,把距離上一次訪問時(shí)間更久的數(shù)據(jù)淘汰出緩存。 Redis的LFU算法實(shí)現(xiàn):

當(dāng) LFU 策略篩選數(shù)據(jù)時(shí)泡态,Redis 會(huì)在候選集合中搂漠,根據(jù)數(shù)據(jù) lru 字段的后 8bit 選擇訪問次數(shù)最少的數(shù)據(jù)進(jìn)行淘汰。當(dāng)訪問次數(shù)相同時(shí)某弦,再根據(jù) lru 字段的前 16bit 值大小桐汤,選擇訪問時(shí)間最久遠(yuǎn)的數(shù)據(jù)進(jìn)行淘汰。

Redis 只使用了 8bit 記錄數(shù)據(jù)的訪問次數(shù)靶壮,而 8bit 記錄的最大值是 255怔毛,這樣在訪問快速的情況下,如果每次被訪問就將訪問次數(shù)加一腾降,很快某條數(shù)據(jù)就達(dá)到最大值255拣度,可能很多數(shù)據(jù)都是255,那么退化成LRU算法了螃壤。所以Redis為了解決這個(gè)問題抗果,實(shí)現(xiàn)了一個(gè)更優(yōu)的計(jì)數(shù)規(guī)則,并可以通過配置項(xiàng)奸晴,來控制計(jì)數(shù)器增加的速度冤馏。

參數(shù)

lfu-log-factor ,用計(jì)數(shù)器當(dāng)前的值乘以配置項(xiàng) lfu_log_factor 再加 1寄啼,再取其倒數(shù)逮光,得到一個(gè) p 值;然后墩划,把這個(gè) p 值和一個(gè)取值范圍在(0睦霎,1)間的隨機(jī)數(shù) r 值比大小,只有 p 值大于 r 值時(shí)走诞,計(jì)數(shù)器才加 1副女。

lfu-decay-time, 控制訪問次數(shù)衰減蚣旱。LFU 策略會(huì)計(jì)算當(dāng)前時(shí)間和數(shù)據(jù)最近一次訪問時(shí)間的差值碑幅,并把這個(gè)差值換算成以分鐘為單位。然后塞绿,LFU 策略再把這個(gè)差值除以 lfu_decay_time 值沟涨,所得的結(jié)果就是數(shù)據(jù) counter 要衰減的值。

lfu-log-factor設(shè)置越大异吻,遞增概率越低裹赴,lfu-decay-time設(shè)置越大喜庞,衰減速度會(huì)越慢。

我們?cè)趹?yīng)用 LFU 策略時(shí)棋返,一般可以將 lfu_log_factor 取值為 10延都。 如果業(yè)務(wù)應(yīng)用中有短時(shí)高頻訪問的數(shù)據(jù)的話,建議把 lfu_decay_time 值設(shè)置為 1睛竣∥浚可以快速衰減訪問次數(shù)。

volatile-lfu 策略是 Redis 4.0 后新增射沟。

  1. allkeys-lru

使用 LRU 算法在所有數(shù)據(jù)中進(jìn)行篩選殊者。具體LFU算法跟上述 volatile-lru 中介紹的一致,只是篩選的數(shù)據(jù)范圍是全部緩存验夯,這里就不在重復(fù)猖吴。

  1. allkeys-random

從所有鍵值對(duì)中隨機(jī)選擇并刪除數(shù)據(jù)。volatile-random 跟 allkeys-random算法一樣挥转,隨機(jī)刪除就無法解決緩存污染問題距误。

  1. allkeys-lfu 使用 LFU 算法在所有數(shù)據(jù)中進(jìn)行篩選。具體LFU算法跟上述 volatile-lfu 中介紹的一致扁位,只是篩選的數(shù)據(jù)范圍是全部緩存,這里就不在重復(fù)趁俊。

allkeys-lfu 策略是 Redis 4.0 后新增域仇。

06 數(shù)據(jù)庫(kù)和緩存一致性

  • 問題來源

使用redis做一個(gè)緩沖操作,讓請(qǐng)求先訪問到redis寺擂,而不是直接訪問MySQL等數(shù)據(jù)庫(kù):

image

讀取緩存步驟一般沒有什么問題暇务,但是一旦涉及到數(shù)據(jù)更新:數(shù)據(jù)庫(kù)和緩存更新,就容易出現(xiàn)緩存(Redis)和數(shù)據(jù)庫(kù)(MySQL)間的數(shù)據(jù)一致性問題怔软。

不管是先寫MySQL數(shù)據(jù)庫(kù)垦细,再刪除Redis緩存;還是先刪除緩存挡逼,再寫庫(kù)括改,都有可能出現(xiàn)數(shù)據(jù)不一致的情況。舉一個(gè)例子:

1.如果刪除了緩存Redis家坎,還沒有來得及寫庫(kù)MySQL嘱能,另一個(gè)線程就來讀取,發(fā)現(xiàn)緩存為空虱疏,則去數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)寫入緩存惹骂,此時(shí)緩存中為臟數(shù)據(jù)。

2.如果先寫了庫(kù)做瞪,在刪除緩存前对粪,寫庫(kù)的線程宕機(jī)了,沒有刪除掉緩存,則也會(huì)出現(xiàn)數(shù)據(jù)不一致情況著拭。

因?yàn)閷懞妥x是并發(fā)的纱扭,沒法保證順序,就會(huì)出現(xiàn)緩存和數(shù)據(jù)庫(kù)的數(shù)據(jù)不一致的問題。

6.1 4種相關(guān)模式

更新緩存的的Design Pattern有四種:Cache aside, Read through, Write through, Write behind caching; 我強(qiáng)烈建議你看看這篇茫死,左耳朵耗子的文章:緩存更新的套路 (opens new window)

節(jié)選最最常用的Cache Aside Pattern, 總結(jié)來說就是

  • 讀的時(shí)候跪但,先讀緩存,緩存沒有的話峦萎,就讀數(shù)據(jù)庫(kù)屡久,然后取出數(shù)據(jù)后放入緩存,同時(shí)返回響應(yīng)爱榔。
  • 更新的時(shí)候被环,先更新數(shù)據(jù)庫(kù),然后再刪除緩存详幽。

其具體邏輯如下:

  • 失效:應(yīng)用程序先從cache取數(shù)據(jù)筛欢,沒有得到,則從數(shù)據(jù)庫(kù)中取數(shù)據(jù)唇聘,成功后版姑,放到緩存中。
  • 命中:應(yīng)用程序從cache中取數(shù)據(jù)迟郎,取到后返回剥险。
  • 更新:先把數(shù)據(jù)存到數(shù)據(jù)庫(kù)中,成功后宪肖,再讓緩存失效表制。
image

注意,我們的更新是先更新數(shù)據(jù)庫(kù)控乾,成功后么介,讓緩存失效。那么蜕衡,這種方式是否可以沒有文章前面提到過的那個(gè)問題呢壤短?我們可以腦補(bǔ)一下。

一個(gè)是查詢操作慨仿,一個(gè)是更新操作的并發(fā)鸽扁,首先,沒有了刪除cache數(shù)據(jù)的操作了镶骗,而是先更新了數(shù)據(jù)庫(kù)中的數(shù)據(jù)桶现,此時(shí),緩存依然有效鼎姊,所以骡和,并發(fā)的查詢操作拿的是沒有更新的數(shù)據(jù)相赁,但是,更新操作馬上讓緩存的失效了慰于,后續(xù)的查詢操作再把數(shù)據(jù)從數(shù)據(jù)庫(kù)中拉出來钮科。而不會(huì)像文章開頭的那個(gè)邏輯產(chǎn)生的問題,后續(xù)的查詢操作一直都在取老的數(shù)據(jù)婆赠。

這是標(biāo)準(zhǔn)的design pattern绵脯,包括Facebook的論文《Scaling Memcache at Facebook (opens new window)》也使用了這個(gè)策略。為什么不是寫完數(shù)據(jù)庫(kù)后更新緩存休里?你可以看一下Quora上的這個(gè)問答《Why does Facebook use delete to remove the key-value pair in Memcached instead of updating the Memcached during write request to the backend? (opens new window)》憋沿,主要是怕兩個(gè)并發(fā)的寫操作導(dǎo)致臟數(shù)據(jù)圾旨。

那么痒谴,是不是Cache Aside這個(gè)就不會(huì)有并發(fā)問題了是整?不是的,比如拭嫁,一個(gè)是讀操作可免,但是沒有命中緩存,然后就到數(shù)據(jù)庫(kù)中取數(shù)據(jù)做粤,此時(shí)來了一個(gè)寫操作浇借,寫完數(shù)據(jù)庫(kù)后,讓緩存失效怕品,然后妇垢,之前的那個(gè)讀操作再把老的數(shù)據(jù)放進(jìn)去,所以堵泽,會(huì)造成臟數(shù)據(jù)。

但恢总,這個(gè)case理論上會(huì)出現(xiàn)迎罗,不過,實(shí)際上出現(xiàn)的概率可能非常低片仿,因?yàn)檫@個(gè)條件需要發(fā)生在讀緩存時(shí)緩存失效纹安,而且并發(fā)著有一個(gè)寫操作。而實(shí)際上數(shù)據(jù)庫(kù)的寫操作會(huì)比讀操作慢得多砂豌,而且還要鎖表厢岂,而讀操作必須在寫操作前進(jìn)入數(shù)據(jù)庫(kù)操作,而又要晚于寫操作更新緩存阳距,所有的這些條件都具備的概率基本并不大塔粒。

所以,這也就是Quora上的那個(gè)答案里說的筐摘,要么通過2PC或是Paxos協(xié)議保證一致性卒茬,要么就是拼命的降低并發(fā)時(shí)臟數(shù)據(jù)的概率船老,而Facebook使用了這個(gè)降低概率的玩法,因?yàn)?PC太慢圃酵,而Paxos太復(fù)雜柳畔。當(dāng)然,最好還是為緩存設(shè)置上過期時(shí)間郭赐。

6.2 方案:隊(duì)列 + 重試機(jī)制

image

流程如下所示

  • 更新數(shù)據(jù)庫(kù)數(shù)據(jù)薪韩;
  • 緩存因?yàn)榉N種問題刪除失敗
  • 將需要?jiǎng)h除的key發(fā)送至消息隊(duì)列
  • 自己消費(fèi)消息,獲得需要?jiǎng)h除的key
  • 繼續(xù)重試刪除操作捌锭,直到成功

然而俘陷,該方案有一個(gè)缺點(diǎn),對(duì)業(yè)務(wù)線代碼造成大量的侵入舀锨。于是有了方案二岭洲,在方案二中,啟動(dòng)一個(gè)訂閱程序去訂閱數(shù)據(jù)庫(kù)的binlog坎匿,獲得需要操作的數(shù)據(jù)盾剩。在應(yīng)用程序中,另起一段程序替蔬,獲得這個(gè)訂閱程序傳來的信息告私,進(jìn)行刪除緩存操作。

6.3 方案:異步更新緩存(基于訂閱binlog的同步機(jī)制)

image
  1. 技術(shù)整體思路

MySQL binlog增量訂閱消費(fèi)+消息隊(duì)列+增量數(shù)據(jù)更新到redis

1)讀Redis:熱數(shù)據(jù)基本都在Redis

2)寫MySQL: 增刪改都是操作MySQL

3)更新Redis數(shù)據(jù):MySQ的數(shù)據(jù)操作binlog承桥,來更新到Redis

  1. Redis更新

1)數(shù)據(jù)操作主要分為兩大塊:

  • 一個(gè)是全量(將全部數(shù)據(jù)一次寫入到redis)
  • 一個(gè)是增量(實(shí)時(shí)更新)

這里說的是增量,指的是mysql的update驻粟、insert、delate變更數(shù)據(jù)凶异。

2)讀取binlog后分析 蜀撑,利用消息隊(duì)列,推送更新各臺(tái)的redis緩存數(shù)據(jù)

這樣一旦MySQL中產(chǎn)生了新的寫入剩彬、更新酷麦、刪除等操作,就可以把binlog相關(guān)的消息推送至Redis喉恋,Redis再根據(jù)binlog中的記錄沃饶,對(duì)Redis進(jìn)行更新。

其實(shí)這種機(jī)制轻黑,很類似MySQL的主從備份機(jī)制糊肤,因?yàn)镸ySQL的主備也是通過binlog來實(shí)現(xiàn)的數(shù)據(jù)一致性。

這里可以結(jié)合使用canal(阿里的一款開源框架)氓鄙,通過該框架可以對(duì)MySQL的binlog進(jìn)行訂閱馆揉,而canal正是模仿了mysql的slave數(shù)據(jù)庫(kù)的備份請(qǐng)求,使得Redis的數(shù)據(jù)更新達(dá)到了相同的效果抖拦。

當(dāng)然把介,這里的消息推送工具你也可以采用別的第三方:kafka勤讽、rabbitMQ等來實(shí)現(xiàn)推送更新Redis。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拗踢,一起剝皮案震驚了整個(gè)濱河市脚牍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巢墅,老刑警劉巖诸狭,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異君纫,居然都是意外死亡驯遇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門蓄髓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來叉庐,“玉大人,你說我怎么就攤上這事会喝《傅” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵肢执,是天一觀的道長(zhǎng)枉阵。 經(jīng)常有香客問我,道長(zhǎng)预茄,這世上最難降的妖魔是什么兴溜? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮耻陕,結(jié)果婚禮上拙徽,老公的妹妹穿的比我還像新娘。我一直安慰自己诗宣,他們只是感情好膘怕,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著梧田,像睡著了一般淳蔼。 火紅的嫁衣襯著肌膚如雪侧蘸。 梳的紋絲不亂的頭發(fā)上裁眯,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音讳癌,去河邊找鬼穿稳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛晌坤,可吹牛的內(nèi)容都是我干的逢艘。 我是一名探鬼主播旦袋,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼它改!你這毒婦竟也來了疤孕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤央拖,失蹤者是張志新(化名)和其女友劉穎祭阀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲜戒,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡专控,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遏餐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伦腐。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖失都,靈堂內(nèi)的尸體忽然破棺而出柏蘑,到底是詐尸還是另有隱情,我是刑警寧澤嗅剖,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布辩越,位于F島的核電站,受9級(jí)特大地震影響信粮,放射性物質(zhì)發(fā)生泄漏黔攒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一强缘、第九天 我趴在偏房一處隱蔽的房頂上張望督惰。 院中可真熱鬧,春花似錦旅掂、人聲如沸赏胚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽觉阅。三九已至,卻和暖如春秘车,著一層夾襖步出監(jiān)牢的瞬間典勇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工叮趴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留割笙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓眯亦,卻偏偏與公主長(zhǎng)得像伤溉,于是被迫代替她去往敵國(guó)和親般码。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

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