詳解分布式共識(shí)(一致性)算法Raft

分布式共識(shí)及Raft簡(jiǎn)介

所謂分布式共識(shí)(consensus)则吟,與CAP理論中的一致性(consistency)其實(shí)是異曲同工序无,就是在分布式系統(tǒng)中先誉,所有節(jié)點(diǎn)對(duì)同一份數(shù)據(jù)的認(rèn)知能夠達(dá)成一致望迎。保證集群共識(shí)的算法就叫共識(shí)算法搜骡,它與一致性協(xié)議這個(gè)詞也經(jīng)嘲雎保互相通用稿壁。

當(dāng)今最著名的共識(shí)算法就是Paxos算法幽钢。它由Leslie Lamport在1990年提出,很長(zhǎng)時(shí)間以來(lái)都是一致性的事實(shí)標(biāo)準(zhǔn)傅是。但是它有兩個(gè)不小的缺點(diǎn):難以理解和證明匪燕,難以在實(shí)際工程中實(shí)現(xiàn)绍绘。Google Chubby的工程師就曾有以下的評(píng)論:

There are significant gaps between the description of the Paxos algorithm and the needs of a real-world system... the final system will be based on an unproven protocol.

于是2014年滤否,來(lái)自斯坦福的兩位大佬Diego Ongaro與John Ousterhout通過(guò)論文《In Search of an Understandable Consensus Algorithm》提出了一個(gè)新的共識(shí)算法Raft贬墩。從題目就可以看出肠牲,Raft的特點(diǎn)就是容易理解,在此基礎(chǔ)上也容易實(shí)現(xiàn)迟隅,因此在real world中啼止,它的應(yīng)用也比Paxos要廣泛锦聊,比較有名的如etcd梗劫、Kudu等享甸。

Raft為了達(dá)到易懂易用的目標(biāo)截碴,主要做了兩件事:一是分解問(wèn)題(decomposition)梳侨,即將復(fù)雜的分布式共識(shí)問(wèn)題拆分為領(lǐng)導(dǎo)選舉(leader election)、日志復(fù)制(log replication)和安全性(safety)三個(gè)子問(wèn)題日丹,并分別解決走哺;二是壓縮狀態(tài)空間(state space reduction),相對(duì)于Paxos算法而言施加了更合理的限制哲虾,減少因?yàn)橄到y(tǒng)狀態(tài)過(guò)多而產(chǎn)生的不確定性丙躏。

下面先簡(jiǎn)要介紹共識(shí)算法的基礎(chǔ)——復(fù)制狀態(tài)機(jī),然后就來(lái)按順序研究Raft是如何解決三個(gè)子問(wèn)題的束凑。

復(fù)制狀態(tài)機(jī)

在共識(shí)算法中晒旅,所有服務(wù)器節(jié)點(diǎn)都會(huì)包含一個(gè)有限狀態(tài)自動(dòng)機(jī),名為復(fù)制狀態(tài)機(jī)(replicated state machine)汪诉。每個(gè)節(jié)點(diǎn)都維護(hù)著一個(gè)復(fù)制日志(replicated logs)的隊(duì)列废恋,復(fù)制狀態(tài)機(jī)會(huì)按序輸入并執(zhí)行該隊(duì)列中的請(qǐng)求,執(zhí)行狀態(tài)轉(zhuǎn)換并輸出結(jié)果扒寄∮愎模可見(jiàn),如果能保證各個(gè)節(jié)點(diǎn)中日志的一致性该编,那么所有節(jié)點(diǎn)狀態(tài)機(jī)的狀態(tài)轉(zhuǎn)換和輸出也就都一致迄本。共識(shí)算法就是為了保障這種一致性的,下圖示出簡(jiǎn)單的復(fù)制狀態(tài)機(jī)及其相關(guān)架構(gòu)课竣。

  1. 某個(gè)節(jié)點(diǎn)的共識(shí)模塊(包含共識(shí)算法的實(shí)現(xiàn))從客戶端接收請(qǐng)求嘉赎。
  2. 該共識(shí)模塊將請(qǐng)求寫(xiě)入自身的日志隊(duì)列置媳,并與其他節(jié)點(diǎn)的共識(shí)模塊交流,保證每個(gè)節(jié)點(diǎn)日志都相同公条。
  3. 復(fù)制狀態(tài)機(jī)處理日志中的請(qǐng)求半开。
  4. 將輸出結(jié)果返回給客戶端。

領(lǐng)導(dǎo)選舉

節(jié)點(diǎn)狀態(tài)與轉(zhuǎn)移規(guī)則

根據(jù)分布式系統(tǒng)的Quorum機(jī)制與NRW算法赃份,集群中半數(shù)以上節(jié)點(diǎn)可用時(shí)寂拆,就能正確處理分布式事務(wù),因此Raft集群幾乎都使用奇數(shù)節(jié)點(diǎn)抓韩,可以防止腦裂并避免浪費(fèi)資源纠永。采用ZAB協(xié)議的ZooKeeper集群也是如此。

在Raft集群中谒拴,任意節(jié)點(diǎn)同一時(shí)刻只能處于領(lǐng)導(dǎo)者(leader)尝江、跟隨者(follower)、候選者(candidate)三種狀態(tài)之一英上。下圖示出節(jié)點(diǎn)狀態(tài)的轉(zhuǎn)移規(guī)則炭序。

可見(jiàn),集群建立時(shí)所有節(jié)點(diǎn)都是跟隨節(jié)點(diǎn)苍日。如果在一定時(shí)間過(guò)后發(fā)現(xiàn)沒(méi)有領(lǐng)導(dǎo)節(jié)點(diǎn)惭聂,就會(huì)切換到候選狀態(tài),發(fā)起選舉相恃。得到多數(shù)票的候選者就會(huì)成為領(lǐng)導(dǎo)節(jié)點(diǎn)辜纲。如果候選節(jié)點(diǎn)或當(dāng)前領(lǐng)導(dǎo)節(jié)點(diǎn)發(fā)現(xiàn)了更新的領(lǐng)導(dǎo)者,就會(huì)主動(dòng)退回跟隨狀態(tài)拦耐。

領(lǐng)導(dǎo)節(jié)點(diǎn)全權(quán)負(fù)責(zé)管理復(fù)制日志耕腾,也就是從客戶端接收請(qǐng)求,復(fù)制到跟隨節(jié)點(diǎn)杀糯,并告訴跟隨節(jié)點(diǎn)何時(shí)可以處理這些請(qǐng)求扫俺。如果領(lǐng)導(dǎo)節(jié)點(diǎn)故障或斷開(kāi)連接,就會(huì)重新進(jìn)行選舉固翰±俏常可見(jiàn),領(lǐng)導(dǎo)節(jié)點(diǎn)的存在大大簡(jiǎn)化了共識(shí)算法的設(shè)計(jì)倦挂。

領(lǐng)導(dǎo)任期

在上面的圖中出現(xiàn)了任期(term)這個(gè)詞畸颅。領(lǐng)導(dǎo)者并不是一直“在位”的,工作一段時(shí)間之后方援,就會(huì)選舉出新的領(lǐng)導(dǎo)者來(lái)接替它没炒。

由上圖可見(jiàn),藍(lán)色表示選舉時(shí)間段,綠色表示選舉出的領(lǐng)導(dǎo)者在位的時(shí)間段送火,這兩者合起來(lái)即稱作一個(gè)任期拳话,其計(jì)數(shù)值是自增的。任期的值就可以在邏輯上充當(dāng)時(shí)間戳种吸,每個(gè)節(jié)點(diǎn)都會(huì)保存一份自己所見(jiàn)的最新任期值弃衍,稱為currentTerm。另外坚俗,如果因?yàn)槠睌?shù)相同镜盯,沒(méi)能選出領(lǐng)導(dǎo),就會(huì)立即再發(fā)起新的選舉猖败。

選舉流程

如果一個(gè)或多個(gè)跟隨節(jié)點(diǎn)在選舉超時(shí)(election timeout)內(nèi)沒(méi)有收到領(lǐng)導(dǎo)節(jié)點(diǎn)的心跳(一個(gè)名為AppendEntries的RPC消息速缆,本意是做日志復(fù)制用途,但此時(shí)不攜帶日志數(shù)據(jù))恩闻,就會(huì)發(fā)起選舉流程:

  1. 增加本地的currentTerm值艺糜;
  2. 將自己切換到候選狀態(tài);
  3. 給自己投一票幢尚;
  4. 給其他節(jié)點(diǎn)發(fā)送名為RequestVote的RPC消息破停,請(qǐng)求投票;
  5. 等待其他節(jié)點(diǎn)的消息尉剩。

根據(jù)其他節(jié)點(diǎn)回復(fù)的消息真慢,會(huì)出現(xiàn)如下三種結(jié)果:

  • 收到多數(shù)節(jié)點(diǎn)的投票,贏得選舉边涕,成為領(lǐng)導(dǎo)節(jié)點(diǎn)晤碘;
  • 收到其他當(dāng)選節(jié)點(diǎn)發(fā)來(lái)的AppendEntries消息,轉(zhuǎn)換回跟隨節(jié)點(diǎn)功蜓;
  • 選舉超時(shí)后沒(méi)收到多數(shù)票,也沒(méi)有其他節(jié)點(diǎn)當(dāng)選宠蚂,就保持候選狀態(tài)重新選舉式撼。

獲得多數(shù)票的節(jié)點(diǎn)只要當(dāng)選,就會(huì)立即給其他所有節(jié)點(diǎn)發(fā)送AppendEntries求厕,避免再次選舉著隆。另外,在同一任期內(nèi)呀癣,每個(gè)節(jié)點(diǎn)只能投一票美浦,并且先到先得(first-come-first-served),也就是會(huì)把票投給RequestVote消息第一個(gè)到達(dá)的那個(gè)節(jié)點(diǎn)项栏。

至于上面的第三種情況浦辨,也就是所謂“split vote”現(xiàn)象,容易在很多跟隨者變成候選者時(shí)出現(xiàn)沼沈,因?yàn)闆](méi)有節(jié)點(diǎn)能得到多數(shù)票流酬,選舉有可能無(wú)限繼續(xù)下去币厕。所以,Raft設(shè)置的選舉超時(shí)并不是完全一樣的芽腾,而是有些許隨機(jī)性旦装,來(lái)盡量使得投票能夠集中到那些較“快”的節(jié)點(diǎn)上。

日志復(fù)制

日志格式

領(lǐng)導(dǎo)節(jié)點(diǎn)選舉出來(lái)后摊滔,集群就可以開(kāi)始處理客戶端請(qǐng)求了阴绢。前面已經(jīng)說(shuō)過(guò),每個(gè)節(jié)點(diǎn)都維護(hù)著一個(gè)復(fù)制日志的隊(duì)列艰躺,它們的格式如下圖所示旱函。

可見(jiàn),日志由一個(gè)個(gè)按序排列的entry組成描滔。每個(gè)entry內(nèi)包含有請(qǐng)求的數(shù)據(jù)棒妨,還有該entry產(chǎn)生時(shí)的領(lǐng)導(dǎo)任期值。在論文中含长,每個(gè)節(jié)點(diǎn)上的日志隊(duì)列用一個(gè)數(shù)組log[]表示券腔。

復(fù)制流程

當(dāng)客戶端發(fā)來(lái)請(qǐng)求時(shí),領(lǐng)導(dǎo)節(jié)點(diǎn)首先將其加入自己的日志隊(duì)列拘泞,再并行地發(fā)送AppendEntries RPC消息給所有跟隨節(jié)點(diǎn)纷纫。領(lǐng)導(dǎo)節(jié)點(diǎn)收到來(lái)自多數(shù)跟隨者的回復(fù)之后,就認(rèn)為該請(qǐng)求可以提交了(見(jiàn)圖中的commited entries)陪腌。然后辱魁,領(lǐng)導(dǎo)節(jié)點(diǎn)將請(qǐng)求應(yīng)用(apply)到復(fù)制狀態(tài)機(jī),并通知跟隨節(jié)點(diǎn)也這樣做诗鸭。這兩步做完后染簇,就不會(huì)再回滾。
這種從提交到應(yīng)用的方式與最基礎(chǔ)的一致性協(xié)議——兩階段提交(2PC)有些相似强岸,但Raft只需要多數(shù)節(jié)點(diǎn)的確認(rèn)锻弓,并不需要全部節(jié)點(diǎn)都可用。

注意在上圖中蝌箍,領(lǐng)導(dǎo)節(jié)點(diǎn)和4個(gè)跟隨節(jié)點(diǎn)的日志并不完全相同青灼,這可能是由于跟隨節(jié)點(diǎn)反應(yīng)慢、網(wǎng)絡(luò)狀況差等原因妓盲。領(lǐng)導(dǎo)節(jié)點(diǎn)會(huì)不斷地重試發(fā)送AppendEntries杂拨,直到所有節(jié)點(diǎn)上的日志達(dá)到最終一致,而不實(shí)現(xiàn)強(qiáng)一致性悯衬。這就是CAP理論中在保證P的情況下弹沽,C與A無(wú)法兼得的體現(xiàn)。

日志復(fù)制的過(guò)程仍然遺留了一個(gè)問(wèn)題:如果領(lǐng)導(dǎo)或者跟隨節(jié)點(diǎn)發(fā)生異常情況而崩潰,如何保證日志的最終一致性贷币?它屬于下面的安全性問(wèn)題中的一部分击胜,稍后會(huì)解答它。

安全性

安全性是施加在領(lǐng)導(dǎo)選舉役纹、日志復(fù)制兩個(gè)解決方案上的約束偶摔,用于保證在異常情況下Raft算法仍然有效,不能破壞一致性促脉,也不能返回錯(cuò)誤的結(jié)果辰斋。所有分布式算法都應(yīng)保障安全性,在其基礎(chǔ)上再保證活性(liveness)瘸味。

Raft協(xié)議的安全性保障有5種宫仗,分別是:選舉安全性(election safety)、領(lǐng)導(dǎo)者只追加(leader append-only)旁仿、日志匹配(log matching)藕夫、領(lǐng)導(dǎo)者完全性(leader completeness)、狀態(tài)機(jī)安全性(state machine safety) 枯冈。下面分別來(lái)看毅贮。

選舉安全性

選舉安全性是指每個(gè)任期內(nèi)只允許選出最多一個(gè)領(lǐng)導(dǎo)。如果集群中有多于一個(gè)領(lǐng)導(dǎo)尘奏,就發(fā)生了腦裂(split brain)滩褥。根據(jù)“領(lǐng)導(dǎo)選舉”一節(jié)中的描述,Raft能夠保證選舉安全炫加,因?yàn)椋?/p>

  • 在同一任期內(nèi)瑰煎,每個(gè)節(jié)點(diǎn)只能投一票;
  • 只有獲得多數(shù)票的節(jié)點(diǎn)才能成為領(lǐng)導(dǎo)俗孝。

領(lǐng)導(dǎo)者只追加

在講解日志復(fù)制時(shí)酒甸,我們可以明顯地看出,客戶端發(fā)出的請(qǐng)求都是插入領(lǐng)導(dǎo)者日志隊(duì)列的尾部驹针,沒(méi)有修改或刪除的操作烘挫。這樣可以使領(lǐng)導(dǎo)者的行為盡量簡(jiǎn)單化,使之沒(méi)有任何不確定的行為柬甥,同時(shí)也作為下一節(jié)要說(shuō)的日志匹配的基礎(chǔ)。

日志匹配

日志匹配的具體描述如下其垄。
如果兩個(gè)節(jié)點(diǎn)的日志隊(duì)列中苛蒲,兩個(gè)entry具有相同的下標(biāo)和任期值,那么:

  • 它們攜帶的客戶端請(qǐng)求相同绿满;
  • 它們之前的所有entry也都相同臂外。

第一點(diǎn)自然由上一節(jié)的“領(lǐng)導(dǎo)者只追加”特性來(lái)保證,而第二點(diǎn)則由AppendEntries RPC消息的一個(gè)簡(jiǎn)單機(jī)制來(lái)保證:每條AppendEntries都會(huì)包含最新entry之前那個(gè)entry的下標(biāo)與任期值,如果跟隨節(jié)點(diǎn)在對(duì)應(yīng)下標(biāo)找不到對(duì)應(yīng)任期的日志漏健,就會(huì)拒絕接受并告知領(lǐng)導(dǎo)節(jié)點(diǎn)嚎货。

有了日志匹配特性,就可以解決日志復(fù)制中那個(gè)遺留問(wèn)題了蔫浆。假設(shè)由于節(jié)點(diǎn)崩潰殖属,跟隨節(jié)點(diǎn)的日志出現(xiàn)了多種異常情況,如下圖瓦盛。

注意圖中不是6個(gè)跟隨節(jié)點(diǎn)洗显,而是6種可能的情況。比如a和b是丟失了entry原环,c和d是有多余的未提交entry挠唆,e和f則是既有丟失又有冗余。這時(shí)領(lǐng)導(dǎo)節(jié)點(diǎn)就會(huì)找到兩個(gè)日志隊(duì)列中最近一條匹配的日志點(diǎn)嘱吗,將該點(diǎn)之后跟隨節(jié)點(diǎn)的所有日志都刪除玄组,然后將自己的這部分日志復(fù)制給它。例如對(duì)于上圖中的情況e來(lái)說(shuō)谒麦,最近一條匹配的日志下標(biāo)為5俄讹,那么5之后的所有entry都會(huì)被刪除,被替換成領(lǐng)導(dǎo)者的日志弄匕。

領(lǐng)導(dǎo)者完全性

領(lǐng)導(dǎo)者完全性是指颅悉,如果有一條日志在某個(gè)任期被提交了,那么它一定會(huì)出現(xiàn)在所有任期更大的領(lǐng)導(dǎo)者日志里迁匠。這也是由兩點(diǎn)來(lái)決定的:

  • 日志提交的定義:該條日志被成功復(fù)制到多數(shù)節(jié)點(diǎn)才算是提交剩瓶;
  • 選舉投票的附加限制:只有當(dāng)節(jié)點(diǎn)A的日志比節(jié)點(diǎn)B的日志更新時(shí),B才可能會(huì)投票給A城丧。也就是說(shuō)延曙,如果一個(gè)候選節(jié)點(diǎn)沒(méi)有包含所有被提交的日志,那么它一定不會(huì)被選舉為領(lǐng)導(dǎo)亡哄。

根據(jù)這兩個(gè)描述枝缔,每次選舉出的領(lǐng)導(dǎo)節(jié)點(diǎn)一定包含有最新的日志,因此只存在跟隨節(jié)點(diǎn)從領(lǐng)導(dǎo)節(jié)點(diǎn)更新日志的情況蚊惯,而不會(huì)反過(guò)來(lái)愿卸,這也使得一致性邏輯更加簡(jiǎn)化,并且為下面的狀態(tài)機(jī)安全性提供保證截型。

狀態(tài)機(jī)安全性

狀態(tài)機(jī)安全性是說(shuō)趴荸,如果一個(gè)節(jié)點(diǎn)已經(jīng)向其復(fù)制狀態(tài)機(jī)應(yīng)用了一條日志中的請(qǐng)求,那么對(duì)于其他節(jié)點(diǎn)的同一下標(biāo)的日志宦焦,不能應(yīng)用不同的請(qǐng)求发钝。這句話就很拗口了顿涣,因此我們來(lái)看一種意外的情況。

  1. 在時(shí)刻a酝豪,節(jié)點(diǎn)S1是領(lǐng)導(dǎo)者涛碑,第2個(gè)任期的日志只復(fù)制給了S2就崩潰了。
  2. 在時(shí)刻b孵淘,S5被選舉為領(lǐng)導(dǎo)者蒲障,第3個(gè)任期的日志還沒(méi)來(lái)得及復(fù)制,也崩潰了夺英。
  3. 在時(shí)刻c晌涕,S1又被選舉為領(lǐng)導(dǎo)者,繼續(xù)復(fù)制日志痛悯,將任期2的日志給了S3余黎。此時(shí)該日志復(fù)制給了多數(shù)節(jié)點(diǎn),但還未提交载萌。
  4. 在時(shí)刻d惧财,S1又崩潰,并且S5重新被選舉為領(lǐng)導(dǎo)者扭仁,將任期3的日志復(fù)制給S0~S4垮衷。

這里就有問(wèn)題了,在時(shí)刻c的日志與新領(lǐng)導(dǎo)者的日志發(fā)生了沖突乖坠,此時(shí)狀態(tài)機(jī)是不安全的搀突。
為了解決該問(wèn)題,Raft不允許領(lǐng)導(dǎo)者在當(dāng)選后提交“前任”的日志熊泵,而是通過(guò)日志匹配原則仰迁,在處理“現(xiàn)任”日志時(shí)將之前的日志一同提交。具體方法是:在領(lǐng)導(dǎo)者任期開(kāi)始時(shí)顽分,立刻提交一條空的日志徐许,所以上圖中時(shí)刻c的情況不會(huì)發(fā)生,而是像時(shí)刻e一樣先提交任期4的日志卒蘸,連帶提交任期2的日志雌隅。就算此時(shí)S1再崩潰,S5也不會(huì)重新被選舉了缸沃。

The End

如果想要更直觀地理解Raft恰起,建議參考這里,是一個(gè)用動(dòng)畫(huà)來(lái)描述該算法的網(wǎng)頁(yè)趾牧,形象生動(dòng)村缸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市武氓,隨后出現(xiàn)的幾起案子梯皿,更是在濱河造成了極大的恐慌,老刑警劉巖县恕,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件东羹,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡忠烛,警方通過(guò)查閱死者的電腦和手機(jī)属提,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)美尸,“玉大人冤议,你說(shuō)我怎么就攤上這事∈玻” “怎么了恕酸?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)胯陋。 經(jīng)常有香客問(wèn)我蕊温,道長(zhǎng),這世上最難降的妖魔是什么遏乔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任义矛,我火速辦了婚禮,結(jié)果婚禮上盟萨,老公的妹妹穿的比我還像新娘凉翻。我一直安慰自己,他們只是感情好捻激,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布制轰。 她就那樣靜靜地躺著,像睡著了一般铺罢。 火紅的嫁衣襯著肌膚如雪艇挨。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,155評(píng)論 1 299
  • 那天韭赘,我揣著相機(jī)與錄音缩滨,去河邊找鬼。 笑死泉瞻,一個(gè)胖子當(dāng)著我的面吹牛脉漏,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播袖牙,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼侧巨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了鞭达?” 一聲冷哼從身側(cè)響起司忱,我...
    開(kāi)封第一講書(shū)人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤皇忿,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后坦仍,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鳍烁,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年繁扎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了幔荒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梳玫,死狀恐怖爹梁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情提澎,我是刑警寧澤姚垃,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站虱朵,受9級(jí)特大地震影響莉炉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碴犬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一絮宁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧服协,春花似錦绍昂、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至跳纳,卻和暖如春忍饰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寺庄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工艾蓝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人斗塘。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓赢织,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親馍盟。 傳聞我的和親對(duì)象是個(gè)殘疾皇子于置,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

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