Redis cluster 原理

基本目標(biāo)與設(shè)計基本思想

Redis cluster 目標(biāo)

  1. 高性能超燃,并且能線性擴(kuò)展到1000個節(jié)點(diǎn)倘待。不需要代理,使用異步復(fù)制,值沒有合并的操作
  2. 可接受的寫安全
  3. 可用性

實現(xiàn)的子集

Redis cluster 實現(xiàn)了所有的single key 操作乞而,對于multi key操作的話肠骆,這些key必須在一個節(jié)點(diǎn)上面尖坤,redis cluster 通過 hash tags決定key存貯在哪個slot上面溪窒。

client 與server 在集群中的角色

節(jié)點(diǎn)首要功能是存貯數(shù)據(jù),集群狀態(tài)徘熔,映射key到相應(yīng)的節(jié)點(diǎn)门躯。自動發(fā)現(xiàn)其他節(jié)點(diǎn),發(fā)現(xiàn)失敗節(jié)點(diǎn)酷师,讓從變?yōu)橹鳌?/p>

為了完成以上功能讶凉,cluster使用tcp和二進(jìn)制協(xié)議(Redis Cluster Bus),節(jié)點(diǎn)間互聯(lián).node 同時使用gossip協(xié)議傳播信息山孔,包括節(jié)點(diǎn)的發(fā)現(xiàn)懂讯,發(fā)送ping包,Pub/Sub信息台颠。
因為節(jié)點(diǎn)并不代理請求轉(zhuǎn)發(fā)褐望,會返回MOVED和ASk錯誤,clients就可以直連到其他節(jié)點(diǎn)串前。client理論上面可以給任意節(jié)點(diǎn)發(fā)送請求瘫里,如果需要就重定向。但實際應(yīng)用中client存貯一個從key到node的map來提高性能荡碾。

寫安全

Redis cluster 使用異步復(fù)制的模式谨读,故障轉(zhuǎn)移的時候,被選為主的節(jié)點(diǎn)坛吁,會用自己的數(shù)據(jù)去覆蓋其他副本節(jié)點(diǎn)的數(shù)據(jù)劳殖。所以總有一個時間口會丟失數(shù)據(jù)。
下面一個例子會丟失數(shù)據(jù):

  1. 一個寫請求到master節(jié)點(diǎn)拨脉,master返回成功給client,但還沒異步寫個副本的時候哆姻,這時候master死掉了,如果一定時間不恢復(fù)玫膀,從升為主節(jié)點(diǎn)矛缨,數(shù)據(jù)就永遠(yuǎn)丟了。

  2. 理論上面丟失數(shù)據(jù)還有下面一種情況

master partition 變得不可用

它的一個從變?yōu)橹?/p>

一定時間之后,這個主又可用了

客戶端這時候還使用舊的的路由劳景,在這個主變?yōu)閺闹坝颍瑢懻埱蟮竭_(dá)這個主。

3盟广、可用性

假設(shè)n個主節(jié)點(diǎn),每個主下面掛載一個從瓮钥,掛掉一個筋量,集群仍然可用。掛點(diǎn)兩個碉熄,可用性是1 -(1/(n2 -1))(第一個節(jié)點(diǎn)掛掉后桨武,還剩下n2-1個節(jié)點(diǎn)),只有一個節(jié)點(diǎn)的主掛掉的可能性是 1/n*2 -1)

replicas migration 使可用性更高

4锈津、性能

reids cluster 不代理請求到正確的節(jié)點(diǎn)呀酸,而是告訴客戶端正確的節(jié)點(diǎn)

client 會保存一份最新的key與node映射,一般情況琼梆,會直接訪問到正確的節(jié)點(diǎn)性誉。

異步寫副本

一般的操作和單臺redis有相同的性能,一個有n個主節(jié)點(diǎn)的集群性能接近n*單個redis

綜上 高性能 線性擴(kuò)展 合理的寫安全 高可用 是rediscluser 的主要目標(biāo)

為什么避免數(shù)據(jù)合并

因為首先redis 存貯的數(shù)據(jù)量會特別大茎杂,如果合并需要更大的空間

Redis Cluseter 主要組件

key 分布模式

key空間分布被劃分為16384個slot,所以一個集群错览,主節(jié)點(diǎn)的個數(shù)最大為16384(一般建議master最大節(jié)點(diǎn)數(shù)為1000)

HASH_SLOT = CRC16(key) mod 16384

Keys hash tags

hash tag 是為了保證不同的key,可以分布到同一個slot上面,來執(zhí)行multi-key的操作

hash tag的規(guī)則是以第一個{開始煌往,到第一個}結(jié)尾倾哺,中間的內(nèi)容,來做hash刽脖。

例子

{user1000}.following 與 {user1000}.followers user1000作為key

foo{}{bar} 整個key

{{bar}} {bar 為key

{bar}{zap} bar 為key

Ruby Example

def HASH_SLOT(key)
s = key.index "{"
if s
    e = key.index "}",s+1
    if e && e != s+1
        key = key[s+1..e-1]
    end
end
crc16(key) % 16384
end`

Cluster nodes 屬性

$ redis-cli cluster nodes
d1861060fe6a534d42d8a19aeb36600e18785e04 127.0.0.1:6379 myself - 0 1318428930 1     connected 0-1364
3886e65cc906bfd9b1f7e7bde468726a052d1dae 127.0.0.1:6380 master - 1318428930     1318428931 2 connected 1365-2729
d289c575dcbc4bdd2931585fd4339089e461a27d 127.0.0.1:6381 master - 1318428931 1318428931 3 connected 2730-4095

從左到右依次為:node id, address:port, flags, last ping sent, last pong received, configuration epoch, link state, slots

其中node id是第一次啟動獲得的一個160字節(jié)的隨機(jī)字符串羞海,并把id保存在配置文件中,一直不會再變

Cluster bus

每個節(jié)點(diǎn)有一個額外的TCP端口曲管,這個端口用來和其他節(jié)點(diǎn)交換信息却邓。這個端口一般是在與客戶端鏈接端口上面加10000,比如客戶端端口為6379翘地,那么cluster bus的端口為16379.

node-to-node 交流是通過cluster bus與 cluster bus protocol進(jìn)行申尤。其中cluster bus protocol 是一個二進(jìn)制協(xié)議,因為官方不建議其他應(yīng)用與redis 節(jié)點(diǎn)進(jìn)行通信衙耕,所以沒有公開的文檔昧穿,要查看的話只能去看源碼。

cluster 拓?fù)?/h3>

Redis cluster 是一個網(wǎng)狀的橙喘,每一個節(jié)點(diǎn)通過tcp與其他每個節(jié)點(diǎn)連接时鸵。假如n個節(jié)點(diǎn)的集群,每個節(jié)點(diǎn)有n-1個出的鏈接,n-1個進(jìn)的鏈接饰潜。這些鏈接會一直存活初坠。假如一個節(jié)點(diǎn)發(fā)送了一個ping,很就沒收到pong,但還沒到時間把這個節(jié)點(diǎn)設(shè)為 unreachable,就會通過重連刷新鏈接彭雾。

Nodes handshake

node 會在cluster bus端口一直接受連接碟刺,回復(fù)ping,即使這個ping 的node是不可信的。但是其他的包會被丟掉薯酝,如果發(fā)送者不是cluster 一員半沽。

一個node有兩種方式接受其他其他node作為集群一員

  1. 如果一個節(jié)點(diǎn)發(fā)送MEET信息(METT 類似ping,但是強(qiáng)迫接受者,把它作為集群一員)吴菠。一個節(jié)點(diǎn)發(fā)送MEET信息者填,只有管理員通過命令行,運(yùn)行如下命令

    CLUSTER MEET ip port

  2. 如果這個節(jié)點(diǎn)已經(jīng)被一個節(jié)點(diǎn)信任做葵,那么也會被其他節(jié)點(diǎn)信任占哟。比如A 知道B,B知道C,B會發(fā)送gossip信息給A關(guān)于C的信息。A就會認(rèn)為C是集群一員酿矢,并與其建立連接榨乎。

這樣只要我們把節(jié)點(diǎn)加入到一個節(jié)點(diǎn),就會自動被其他節(jié)點(diǎn)自動發(fā)現(xiàn)棠涮。

Redirection and resharding

MOVED Redirection

客戶端可以自由的連接任何一個node,如果這個node 不能處理會返回一個MOVED的錯誤谬哀,類似下面這樣

GET x
-MOVED 3999 127.0.0.1:6381

描述了key 的hash slot,屬于哪個node

client 會維護(hù)一個hash slots到IP:port的映射

當(dāng)收到moved錯誤的時候,可以通過CLUSTER NODES或者CLUSTER SLOTS去刷新一遍整個client

Cluster live reconfiguration

cluster 支持運(yùn)行狀態(tài)下添加和刪除節(jié)點(diǎn)严肪。添加刪除節(jié)點(diǎn)抽象:把一部分hash slot從一個節(jié)點(diǎn)移動到另一個節(jié)點(diǎn)史煎。

  • 添加一個新節(jié)點(diǎn),hash slot 從一些節(jié)點(diǎn)移動到這個新節(jié)點(diǎn)
  • 移除一個節(jié)點(diǎn)驳糯,把這個節(jié)點(diǎn)的hash slot 移動到其他的節(jié)點(diǎn)
  • rebalance ,部分hash slot在節(jié)點(diǎn)間移動

所以篇梭,動態(tài)擴(kuò)容的核心就是在節(jié)點(diǎn)之間移動hash slot,hash slot 又是key的集合。所以reshare 就是把key從一個節(jié)點(diǎn)移動到其他節(jié)點(diǎn)酝枢。

redis 提供如下命令:

前兩個指令:ADDSLOTS和DELSLOTS恬偷,用于向當(dāng)前node分配或者移除slots,指令可以接受多個slot值帘睦。分配slots的意思是告知指定的master(即此指令需要在某個master節(jié)點(diǎn)執(zhí)行)此后由它接管相應(yīng)slots的服務(wù)袍患;slots分配后,這些信息將會通過gossip發(fā)給集群的其他nodes竣付。

ADDSLOTS指令通常在創(chuàng)建一個新的Cluster時使用诡延,一個新的Cluster有多個空的Masters構(gòu)成,此后管理員需要手動為每個master分配slots古胆,并將16384個slots分配完畢肆良,集群才能正常服務(wù)筛璧。簡而言之,ADDSLOTS只能操作那些尚未分配的(即不被任何nodes持有)slots惹恃,我們通常在創(chuàng)建新的集群或者修復(fù)一個broken的集群(集群中某些slots因為nodes的永久失效而丟失)時使用夭谤。為了避免出錯,Redis Cluster提供了一個redis-trib輔助工具巫糙,方便我們做這些事情朗儒。

DELSLOTS就是將指定的slots刪除,前提是這些slots必須在當(dāng)前node上参淹,被刪除的slots處于“未分配”狀態(tài)(當(dāng)然其對應(yīng)的keys數(shù)據(jù)也被clear)采蚀,即尚未被任何nodes覆蓋,這種情況可能導(dǎo)致集群處于不可用狀態(tài)承二,此指令通常用于debug,在實際環(huán)境中很少使用纲爸。那些被刪除的slots亥鸠,可以通過ADDSLOTS重新分配。

SETSLOT是個很重要的指令识啦,對集群slots進(jìn)行reshard的最重要手段负蚊;它用來將單個slot在兩個nodes間遷移。根據(jù)slot的操作方式颓哮,它有兩種狀態(tài)“MIGRATING”家妆、“IMPORTING”

1)MIGRATING:將slot的狀態(tài)設(shè)置為“MIGRATING”,并遷移到destination-node上冕茅,需要注意當(dāng)前node必須是slot的持有者伤极。在遷移期間,Client的查詢操作仍在當(dāng)前node上執(zhí)行姨伤,如果key不存在哨坪,則會向Client反饋“-ASK”重定向信息,此后Client將會把請求重新提交給遷移的目標(biāo)node乍楚。

2)IMPORTING:將slot的狀態(tài)設(shè)置為“IMPORTING”当编,并將其從source-node遷移到當(dāng)前node上,前提是source-node必須是slot的持有者徒溪。Client交互機(jī)制同上忿偷。

假如我們有兩個節(jié)點(diǎn)A、B臊泌,其中slot 8在A上鲤桥,我們希望將8從A遷移到B,可以使用如下方式:

1)在B上:CLUSTER SETSLOT 8 IMPORTING A

2)在A上:CLUSTER SETSLOT 8 MIGRATING B

在遷移期間缺虐,集群中其他的nodes的集群信息不會改變芜壁,即slot 8仍對應(yīng)A,即此期間,Client查詢?nèi)栽贏上:

1)如果key在A上存在慧妄,則有A執(zhí)行顷牌。

2)否則,將向客戶端返回ASK塞淹,客戶端將請求重定向到B窟蓝。

這種方式下,新key的創(chuàng)建就不會在A上執(zhí)行饱普,而是在B上執(zhí)行运挫,這也就是ASK重定向的原因(遷移之前的keys在A,遷移期間created的keys在B上)套耕;當(dāng)上述SET SLOT執(zhí)行完畢后谁帕,slot的狀態(tài)也會被自動清除,同時將slot遷移信息傳播給其他nodes冯袍,至此集群中slot的映射關(guān)系將會變更匈挖,此后slot 8的數(shù)據(jù)請求將會直接提交到B上。

動態(tài)分片的步驟:

  1. 在目標(biāo)節(jié)點(diǎn)設(shè)置為 SETSLOT <slot> IMPORTING <source-node-id>.
  2. 在原節(jié)點(diǎn) SETSLOT <slot> MIGRATING <destination-node-id>.
  3. CLUSTER GETKEYSINSLOT 獲得所有的key ,使用MIGRATE 從原節(jié)點(diǎn)遷移到目標(biāo)節(jié)點(diǎn)
  4. 在原節(jié)點(diǎn)或者目標(biāo)節(jié)點(diǎn) CLUSTER SETSLOT <slot> NODE <destination-node-id>

ASK重定向

在上文中康愤,我們已經(jīng)介紹了MOVED重定向儡循,ASK與其非常相似。在resharding期間征冷,為什么不能用MOVED择膝?MOVED意思為hash slots已經(jīng)永久被另一個node接管、接下來的相應(yīng)的查詢應(yīng)該與它交互检激,ASK的意思是當(dāng)前query暫時與指定的node交互肴捉;在遷移期間,slot 8的keys有可能仍在A上呵扛,所以Client的請求仍然需要首先經(jīng)由A每庆,對于A上不存在的,我們才需要到B上進(jìn)行嘗試今穿。遷移期間缤灵,Redis Cluster并沒有粗暴的將slot 8的請求全部阻塞、直到遷移結(jié)束蓝晒,這種方式盡管不再需要ASK腮出,但是會影響集群的可用性。

1)當(dāng)Client接收到ASK重定向芝薇,它僅僅將當(dāng)前query重定向到指定的node胚嘲;此后的請求仍然交付給舊的節(jié)點(diǎn)。

2)客戶端并不會更新本地的slots映射洛二,仍然保持slot 8與A的映射馋劈;直到集群遷移完畢攻锰,且遇到MOVED重定向。

一旦slot 8遷移完畢之后(集群的映射信息也已更新)妓雾,如果Client再次在A上訪問slot 8時娶吞,將會得到MOVED重定向信息,此后客戶端也更新本地的集群映射信息械姻。

客戶端首次鏈接以及重定向處理

可能有些Cluster客戶端的實現(xiàn)妒蛇,不會在內(nèi)存中保存slots映射關(guān)系(即nodes與slots的關(guān)系),每次請求都從聲明的楷拳、已知的nodes中绣夺,隨機(jī)訪問一個node,并根據(jù)重定向(MOVED)信息來尋找合適的node欢揖,這種訪問模式陶耍,通常是非常低效的。

當(dāng)然她混,Client應(yīng)該盡可能的將slots配置信息緩存在本地物臂,不過配置信息也不需要絕對的實時更新,因為在請求時偶爾出現(xiàn)“重定向”产上,Client也能兼容此次請求的正確轉(zhuǎn)發(fā),此時再更新slots配置蛾狗。(所以Client通常不需要間歇性的檢測Cluster中配置信息是否已經(jīng)更新)客戶端通常是全量更新slots配置:

  • 首次鏈接到集群的某個節(jié)點(diǎn)
  • 當(dāng)遇到MOVED重定向消息時

遇到MOVED時晋涣,客戶端僅僅更新特定的slot是不夠的,因為集群中的reshard通常會影響到多個slots沉桌⌒蝗担客戶端通過向任意一個nodes發(fā)送“CLUSTER NODES”或者“CLUSTER SLOTS”指令均可以獲得當(dāng)前集群最新的slots映射信息;“CLUSTER SLOTS”指令返回的信息更易于Client解析留凭。

slaves擴(kuò)展reads請求

通常情況下佃扼,read、write請求都將有持有slots的master節(jié)點(diǎn)處理蔼夜;因為redis的slaves可以支持read操作(前提是application能夠容忍stale數(shù)據(jù))兼耀,所以客戶端可以使用“READONLY”指令來擴(kuò)展read請求。

“READONLY”表明其可以訪問集群的slaves節(jié)點(diǎn)求冷,能夠容忍stale數(shù)據(jù)瘤运,而且此次鏈接不會執(zhí)行writes操作。當(dāng)鏈接設(shè)定為readonly模式后匠题,Cluster只有當(dāng)keys不被slave的master節(jié)點(diǎn)持有時才會發(fā)送重定向消息(即Client的read請求總是發(fā)給slave拯坟,只有當(dāng)此slave的master不持有slots時才會重定向,很好理解):
1)此slave的master節(jié)點(diǎn)不持有相應(yīng)的slots
2)集群重新配置韭山,比如reshard或者slave遷移到了其他master上郁季,此slave本身也不再支持此slot冷溃。

容錯

心跳與gossip消息

集群中的nodes持續(xù)的交換ping、pong數(shù)據(jù)梦裂,這兩種數(shù)據(jù)包的結(jié)構(gòu)一樣似枕,同樣都攜帶集群的配置信息,唯一不同的就是message中的type字段塞琼。

通常菠净,一個node發(fā)送ping消息,那么接收者將會反饋pong消息彪杉;不過有時候并非如此毅往,比如當(dāng)集群中添加新的node時,接收者會將pong信息發(fā)給其他的nodes派近,而不是直接反饋給發(fā)送者攀唯。這樣的好處是會將配置盡快的在cluster傳播。

通常一個node每秒都會隨機(jī)向幾個nodes發(fā)送ping渴丸,所以無論集群規(guī)模多大侯嘀,每個nodes發(fā)送的ping數(shù)據(jù)包的總量是恒定的。每個node都確保盡可能半個NODE_TIMEOUT時間內(nèi)谱轨,向那些尚未發(fā)送過ping或者未接收到它們的pong消息的nodes發(fā)送ping戒幔。在NODE_TIMEOUT逾期之前,nodes也會嘗試與那些通訊異常的nodes重新建立TCP鏈接土童,確保不能僅僅因為當(dāng)前鏈接異常而認(rèn)為它們就是不可達(dá)的诗茎。

當(dāng)NODE_TIMEOUT值較小、集群中nodes規(guī)模較大時献汗,那么全局交換的信息量也會非常龐大敢订,因為每個node都盡力在半個NODE_TIMEOUT時間內(nèi),向其他nodes發(fā)送ping罢吃。比如有100個nodes楚午,NODE_TIMEOUT為60秒,那么每個node在30秒內(nèi)向其他99各nodes發(fā)送ping尿招,平均每秒3.3個消息矾柜,那么整個集群全局就是每秒330個消息。這些消息量就谜,并不會對集群的帶寬帶來不良問題把沼。

心跳包的內(nèi)容

心跳數(shù)據(jù)包的內(nèi)容

  • node ID
  • currentEpoch和configEpoch
  • node flags:比如表示此node是maste、slave等
  • hash slots:發(fā)送者持有的slots
  • TCP port
  • state (down or ok)
  • master node ID (如果是從節(jié)點(diǎn))

ping和pong數(shù)據(jù)包中也包含gossip部分吁伺,這部分信息告訴接受者饮睬,當(dāng)前節(jié)點(diǎn)持有其他節(jié)點(diǎn)的狀態(tài),不過它只包含sender已知的隨機(jī)幾個nodes篮奄,nodes的數(shù)量根據(jù)集群規(guī)模的大小按比例計算捆愁。

gossip部分包含了

  • Node ID
  • IP and port of the node
  • Node flags

失敗檢測

集群失效檢測就是割去,當(dāng)某個master或者slave不能被大多數(shù)nodes可達(dá)時,用于故障遷移并將合適的slave提升為master昼丑。當(dāng)slave提升未能有效實施時呻逆,集群將處于error狀態(tài)且停止接收Client端查詢。

每個node持有其已知nodes的列表包括flags菩帝,有2個flag狀態(tài):PFAIL和FAIL咖城;PFAIL表示“可能失效”,是一種尚未完全確認(rèn)的失效狀態(tài)(即某個節(jié)點(diǎn)或者少數(shù)masters認(rèn)為其不可達(dá))呼奢。FAIL表示此node已經(jīng)被集群大多數(shù)masters判定為失效(大多數(shù)master已認(rèn)定為不可達(dá)宜雀,且不可達(dá)時間已達(dá)到設(shè)定值,需要failover)握础。

nodes的ID辐董、ip+port、flags禀综,那么接收者將根據(jù)sender的視圖简烘,來判定節(jié)點(diǎn)的狀態(tài),這對故障檢測定枷、節(jié)點(diǎn)自動發(fā)現(xiàn)非常有用孤澎。

PFAIL flag:

當(dāng)node不可達(dá)的時間超過NODE_TIMEOUT,這個節(jié)點(diǎn)就被標(biāo)記為PFAIL(Possible failure),master和slave都可以標(biāo)記其他節(jié)點(diǎn)為PFAIL欠窒。所謂不可達(dá)亥至,就是當(dāng)“active ping”(發(fā)送ping且能受到pong)尚未成功的時間超過NODE_TIMEOUT,因此我們設(shè)定的NODE_TIMEOUT的值應(yīng)該比網(wǎng)絡(luò)交互往返的時間延遲要大一些(通常要大的多贱迟,以至于交互往返時間可以忽略)。為了避免誤判絮供,當(dāng)一個node在半個NODE_TIMEOUT時間內(nèi)仍未能pong衣吠,那么當(dāng)前node將會盡力嘗試重新建立連接進(jìn)行重試,以排除pong未能接收

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末壤靶,一起剝皮案震驚了整個濱河市缚俏,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贮乳,老刑警劉巖忧换,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異向拆,居然都是意外死亡亚茬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門浓恳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刹缝,“玉大人碗暗,你說我怎么就攤上這事∩液唬” “怎么了言疗?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長颂砸。 經(jīng)常有香客問我噪奄,道長,這世上最難降的妖魔是什么人乓? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任勤篮,我火速辦了婚禮,結(jié)果婚禮上撒蟀,老公的妹妹穿的比我還像新娘叙谨。我一直安慰自己,他們只是感情好保屯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布手负。 她就那樣靜靜地躺著,像睡著了一般姑尺。 火紅的嫁衣襯著肌膚如雪竟终。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天切蟋,我揣著相機(jī)與錄音统捶,去河邊找鬼。 笑死柄粹,一個胖子當(dāng)著我的面吹牛喘鸟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播驻右,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼什黑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了堪夭?” 一聲冷哼從身側(cè)響起愕把,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎森爽,沒想到半個月后恨豁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爬迟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年橘蜜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片付呕。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡扮匠,死狀恐怖捧请,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情棒搜,我是刑警寧澤疹蛉,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站力麸,受9級特大地震影響可款,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜克蚂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一闺鲸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧埃叭,春花似錦摸恍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至类早,卻和暖如春媚媒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涩僻。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工缭召, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人逆日。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓嵌巷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親室抽。 傳聞我的和親對象是個殘疾皇子搪哪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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