sendfile“零拷貝”趟紊、mmap內(nèi)存映射、DMA

KAFKA推送消息用到了sendfile碰酝,落盤技術(shù)用到了mmap霎匈,DMA貫穿其中。

先說說零拷貝

零拷貝并不是不需要拷貝砰粹,而是減少不必要的拷貝次數(shù)唧躲。通常是說在IO讀寫過程中。

實(shí)際上碱璃,零拷貝是有廣義和狹義之分弄痹,目前我們通常聽到的零拷貝,包括上面這個(gè)定義減少不必要的拷貝次數(shù)都是廣義上的零拷貝嵌器。其實(shí)了解到這點(diǎn)就足夠了肛真。

我們知道,減少不必要的拷貝次數(shù)爽航,就是為了提高效率蚓让。那零拷貝之前,是怎樣的呢讥珍?

聊聊傳統(tǒng)IO流程

比如:讀取文件历极,再用socket發(fā)送出去

傳統(tǒng)方式實(shí)現(xiàn):

先讀取、再發(fā)送衷佃,實(shí)際經(jīng)過1~4四次copy趟卸。

1、第一次:將磁盤文件氏义,讀取到操作系統(tǒng)內(nèi)核緩沖區(qū)锄列;

2、第二次:將內(nèi)核緩沖區(qū)的數(shù)據(jù)惯悠,copy到application應(yīng)用程序的buffer邻邮;

3、第三步:將application應(yīng)用程序buffer中的數(shù)據(jù)克婶,copy到socket網(wǎng)絡(luò)發(fā)送緩沖區(qū)(屬于操作系統(tǒng)內(nèi)核的緩沖區(qū))筒严;

4丹泉、第四次:將socket buffer的數(shù)據(jù),copy到網(wǎng)卡鸭蛙,由網(wǎng)卡進(jìn)行網(wǎng)絡(luò)傳輸嘀掸。

傳統(tǒng)方式,讀取磁盤文件并進(jìn)行網(wǎng)絡(luò)發(fā)送规惰,經(jīng)過的四次數(shù)據(jù)copy是非常繁瑣的。實(shí)際IO讀寫泉蝌,需要進(jìn)行IO中斷歇万,需要CPU響應(yīng)中斷(帶來上下文切換),盡管后來引入DMA來接管CPU的中斷請(qǐng)求勋陪,但四次copy是存在“不必要的拷貝”的贪磺。(什么是DMA?

其實(shí)DMA技術(shù)很容易理解诅愚,本質(zhì)上寒锚,DMA技術(shù)就是我們在主板上放?塊獨(dú)立的芯片。在進(jìn)行內(nèi)存和I/O設(shè)備的數(shù)據(jù)傳輸?shù)臅r(shí)候违孝,我們不再通過CPU來控制數(shù)據(jù)傳輸,而直接通過 DMA控制器(DMA?Controller,簡稱DMAC)川无。這塊芯片务荆,我們可以認(rèn)為它其實(shí)就是一個(gè)協(xié)處理器(Co-Processor))

重新思考傳統(tǒng)IO方式,會(huì)注意到實(shí)際上并不需要第二個(gè)和第三個(gè)數(shù)據(jù)副本校坑。應(yīng)用程序除了緩存數(shù)據(jù)并將其傳輸回套接字緩沖區(qū)之外什么都不做拣技。相反,數(shù)據(jù)可以直接從讀緩沖區(qū)傳輸?shù)教捉幼志彌_區(qū)耍目。

顯然膏斤,第二次和第三次數(shù)據(jù)copy 其實(shí)在這種場景下沒有什么幫助反而帶來開銷,這也正是零拷貝出現(xiàn)的意義邪驮。

這種場景:是指讀取磁盤文件后莫辨,不需要做其他處理,直接用網(wǎng)絡(luò)發(fā)送出去耕捞。試想衔掸,如果讀取磁盤的數(shù)據(jù)需要用程序進(jìn)一步處理的話,必須要經(jīng)過第二次和第三次數(shù)據(jù)copy俺抽,讓應(yīng)用程序在內(nèi)存緩沖區(qū)處理敞映。

為什么Kafka這么快

kafka作為MQ也好,作為存儲(chǔ)層也好磷斧,無非是兩個(gè)重要功能振愿,一是Producer生產(chǎn)的數(shù)據(jù)存到broker捷犹,二是 Consumer從broker讀取數(shù)據(jù);我們把它簡化成如下兩個(gè)過程:

1冕末、網(wǎng)絡(luò)數(shù)據(jù)持久化到磁盤 (Producer 到 Broker)

2萍歉、磁盤文件通過網(wǎng)絡(luò)發(fā)送(Broker 到 Consumer)

下面,先給出“kafka用了磁盤档桃,還速度快”的結(jié)論

1枪孩、順序讀寫

磁盤順序讀或?qū)懙乃俣?00M/s,能夠發(fā)揮磁盤最大的速度藻肄。

隨機(jī)讀寫蔑舞,磁盤速度慢的時(shí)候十幾到幾百K/s。這就看出了差距嘹屯。

kafka將來自Producer的數(shù)據(jù)攻询,順序追加在partition,partition就是一個(gè)文件州弟,以此實(shí)現(xiàn)順序?qū)懭搿?/p>

Consumer從broker讀取數(shù)據(jù)時(shí)钧栖,因?yàn)樽詭Я似屏浚又洗巫x取的位置繼續(xù)讀婆翔,以此實(shí)現(xiàn)順序讀拯杠。

順序讀寫,是kafka利用磁盤特性的一個(gè)重要體現(xiàn)浙滤。

2阴挣、零拷貝 sendfile(in,out)

數(shù)據(jù)直接在內(nèi)核完成輸入和輸出,不需要拷貝到用戶空間再寫出去纺腊。

kafka數(shù)據(jù)寫入磁盤前畔咧,數(shù)據(jù)先寫到進(jìn)程的內(nèi)存空間。

3揖膜、mmap文件映射

虛擬映射只支持文件誓沸;

在進(jìn)程 的非堆內(nèi)存開辟一塊內(nèi)存空間,和OS內(nèi)核空間的一塊內(nèi)存進(jìn)行映射壹粟,

kafka數(shù)據(jù)寫入拜隧、是寫入這塊內(nèi)存空間,但實(shí)際這塊內(nèi)存和OS內(nèi)核內(nèi)存有映射趁仙,也就是相當(dāng)于寫在內(nèi)核內(nèi)存空間了洪添,且這塊內(nèi)核空間、內(nèi)核直接能夠訪問到雀费,直接落入磁盤干奢。

這里,我們需要清楚的是:內(nèi)核緩沖區(qū)的數(shù)據(jù)盏袄,flush就能完成落盤忿峻。

我們來重點(diǎn)探究 kafka兩個(gè)重要過程薄啥、以及是如何利用兩個(gè)零拷貝技術(shù)sendfile和mmap的。

網(wǎng)絡(luò)數(shù)據(jù)持久化到磁盤 (Producer 到 Broker)

傳統(tǒng)方式實(shí)現(xiàn):

先接收生產(chǎn)者發(fā)來的消息逛尚,再落入磁盤垄惧。

數(shù)據(jù)落盤通常都是非實(shí)時(shí)的,kafka生產(chǎn)者數(shù)據(jù)持久化也是如此绰寞。Kafka的數(shù)據(jù)并不是實(shí)時(shí)的寫入硬盤到逊,它充分利用了現(xiàn)代操作系統(tǒng)分頁存儲(chǔ)來利用內(nèi)存提高I/O效率。

對(duì)于kafka來說滤钱,Producer生產(chǎn)的數(shù)據(jù)存到broker蕾管,這個(gè)過程讀取到socket buffer的網(wǎng)絡(luò)數(shù)據(jù),其實(shí)可以直接在OS內(nèi)核緩沖區(qū)菩暗,完成落盤。并沒有必要將socket buffer的網(wǎng)絡(luò)數(shù)據(jù)旭蠕,讀取到應(yīng)用進(jìn)程緩沖區(qū)停团;在這里應(yīng)用進(jìn)程緩沖區(qū)其實(shí)就是broker,broker收到生產(chǎn)者的數(shù)據(jù)掏熬,就是為了持久化佑稠。

在此特殊場景下:接收來自socket buffer的網(wǎng)絡(luò)數(shù)據(jù),應(yīng)用進(jìn)程不需要中間處理旗芬、直接進(jìn)行持久化時(shí)舌胶。——可以使用mmap內(nèi)存文件映射疮丛。

Memory Mapped Files

簡稱mmap幔嫂,簡單描述其作用就是:將磁盤文件映射到內(nèi)存, 用戶通過修改內(nèi)存就能修改磁盤文件。

它的工作原理是直接利用操作系統(tǒng)的Page來實(shí)現(xiàn)文件到物理內(nèi)存的直接映射誊薄。完成映射之后你對(duì)物理內(nèi)存的操作會(huì)被同步到硬盤上(操作系統(tǒng)在適當(dāng)?shù)臅r(shí)候)履恩。

通過mmap,進(jìn)程像讀寫硬盤一樣讀寫內(nèi)存(當(dāng)然是虛擬機(jī)內(nèi)存)呢蔫,也不必關(guān)心內(nèi)存的大小有虛擬內(nèi)存為我們兜底切心。

使用這種方式可以獲取很大的I/O提升,省去了用戶空間到內(nèi)核空間復(fù)制的開銷片吊。

mmap也有一個(gè)很明顯的缺陷——不可靠绽昏,寫到mmap中的數(shù)據(jù)并沒有被真正的寫到硬盤,操作系統(tǒng)會(huì)在程序主動(dòng)調(diào)用flush的時(shí)候才把數(shù)據(jù)真正的寫到硬盤俏脊。Kafka提供了一個(gè)參數(shù)——producer.type來控制是不是主動(dòng)flush全谤;如果Kafka寫入到mmap之后就立即flush然后再返回Producer叫同步(sync);寫入mmap之后立即返回Producer不調(diào)用flush叫異步(async)联予。

Java NIO對(duì)文件映射的支持

Java NIO啼县,提供了一個(gè) MappedByteBuffer 類可以用來實(shí)現(xiàn)內(nèi)存映射材原。

MappedByteBuffer只能通過調(diào)用FileChannel的map()取得,再?zèng)]有其他方式季眷。

FileChannel.map()是抽象方法余蟹,具體實(shí)現(xiàn)是在 FileChannelImpl.c 可自行查看JDK源碼,其map0()方法就是調(diào)用了Linux內(nèi)核的mmap的API子刮。

使用 MappedByteBuffer類要注意的是:mmap的文件映射威酒,在full gc時(shí)才會(huì)進(jìn)行釋放。當(dāng)close時(shí)挺峡,需要手動(dòng)清除內(nèi)存映射文件葵孤,可以反射調(diào)用sun.misc.Cleaner方法。

磁盤文件通過網(wǎng)絡(luò)發(fā)送(Broker 到 Consumer)

傳統(tǒng)方式實(shí)現(xiàn):

先讀取磁盤橱赠、再用socket發(fā)送尤仍,實(shí)際也是進(jìn)過四次copy。

而 Linux 2.4+ 內(nèi)核通過 sendfile 系統(tǒng)調(diào)用狭姨,提供了零拷貝宰啦。磁盤數(shù)據(jù)通過 DMA 拷貝到內(nèi)核態(tài) Buffer 后,直接通過 DMA 拷貝到 NIC Buffer(socket buffer)饼拍,無需 CPU 拷貝赡模。這也是零拷貝這一說法的來源。除了減少數(shù)據(jù)拷貝外师抄,因?yàn)檎麄€(gè)讀文件 - 網(wǎng)絡(luò)發(fā)送由一個(gè) sendfile 調(diào)用完成漓柑,整個(gè)過程只有兩次上下文切換,因此大大提高了性能叨吮。零拷貝過程如下圖所示辆布。

相比于文章開始,對(duì)傳統(tǒng)IO 4步拷貝的分析茶鉴,sendfile將第二次谚殊、第三次拷貝,一步完成蛤铜。

其實(shí)這項(xiàng)零拷貝技術(shù)嫩絮,直接從內(nèi)核空間(DMA的)到內(nèi)核空間(Socket的)、然后發(fā)送網(wǎng)卡围肥。

應(yīng)用的場景非常多剿干,如Tomcat、Nginx穆刻、Apache等web服務(wù)器返回靜態(tài)資源等置尔,將數(shù)據(jù)用網(wǎng)絡(luò)發(fā)送出去,都運(yùn)用了sendfile氢伟。

簡單理解 sendfile(in,out)就是榜轿,磁盤文件讀取到操作系統(tǒng)內(nèi)核緩沖區(qū)后幽歼、直接扔給網(wǎng)卡,發(fā)送網(wǎng)絡(luò)數(shù)據(jù)谬盐。

Java NIO對(duì)sendfile的支持就是FileChannel.transferTo()/transferFrom()甸私。

fileChannel.transferTo( position, count, socketChannel);

把磁盤文件讀取OS內(nèi)核緩沖區(qū)后的fileChannel,直接轉(zhuǎn)給socketChannel發(fā)送飞傀;底層就是sendfile皇型。消費(fèi)者從broker讀取數(shù)據(jù),就是由此實(shí)現(xiàn)砸烦。

具體來看弃鸦,Kafka 的數(shù)據(jù)傳輸通過 TransportLayer 來完成,其子類 PlaintextTransportLayer 通過Java NIO 的 FileChannel 的 transferTo 和 transferFrom 方法實(shí)現(xiàn)零拷貝幢痘。

注: transferTo 和 transferFrom 并不保證一定能使用零拷貝唬格。實(shí)際上是否能使用零拷貝與操作系統(tǒng)相關(guān),如果操作系統(tǒng)提供 sendfile 這樣的零拷貝系統(tǒng)調(diào)用颜说,則這兩個(gè)方法會(huì)通過這樣的系統(tǒng)調(diào)用充分利用零拷貝的優(yōu)勢西轩,否則并不能通過這兩個(gè)方法本身實(shí)現(xiàn)零拷貝。

Kafka總結(jié)

總的來說Kafka快的原因:

1脑沿、partition順序讀寫,充分利用磁盤特性马僻,這是基礎(chǔ)庄拇;

2、Producer生產(chǎn)的數(shù)據(jù)持久化到broker韭邓,采用mmap文件映射措近,實(shí)現(xiàn)順序的快速寫入;

3女淑、Customer從broker讀取數(shù)據(jù)瞭郑,采用sendfile,將磁盤文件讀到OS內(nèi)核緩沖區(qū)后鸭你,直接轉(zhuǎn)到socket buffer進(jìn)行網(wǎng)絡(luò)發(fā)送屈张。

mmap 和 sendfile總結(jié)

1、都是Linux內(nèi)核提供袱巨、實(shí)現(xiàn)零拷貝的API阁谆;

2、sendfile 是將讀到內(nèi)核空間的數(shù)據(jù)愉老,轉(zhuǎn)到socket buffer场绿,進(jìn)行網(wǎng)絡(luò)發(fā)送;

3嫉入、mmap將磁盤文件映射到內(nèi)存焰盗,支持讀和寫璧尸,對(duì)內(nèi)存的操作會(huì)反映在磁盤文件上。

RocketMQ 在消費(fèi)消息時(shí)熬拒,使用了 mmap爷光。kafka 使用了 sendFile。

關(guān)于DMA

為什么那么快梦湘?一起來看Kafka的實(shí)現(xiàn)原理

1瞎颗、它究竟是怎么利用DMA的?

Kafka是一個(gè)用來處理實(shí)時(shí)數(shù)據(jù)的管道捌议,我們常常用它來做一個(gè)消息隊(duì)列哼拔,或者用來收集和落地海量的日志。作為一個(gè)處理實(shí)時(shí)數(shù)據(jù)和日志的管道瓣颅,瓶頸自然也在I/O層面倦逐。

2、Kafka里面兩種常用的海量數(shù)據(jù)傳輸?shù)那闆r是什么宫补?

Kafka里面會(huì)有兩種常用的海量數(shù)據(jù)傳輸?shù)那闆r檬姥。一種是從網(wǎng)絡(luò)絡(luò)中接收上游的數(shù)據(jù),然后需要落地到本地的磁盤上粉怕,確保數(shù)據(jù)不丟失健民。

另一種情況呢,則是從本地磁盤上讀取出來贫贝,通過網(wǎng)絡(luò)發(fā)送出去秉犹。

我們來看一看后一種情況,從磁盤讀數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上去稚晚。如果我們自己寫一個(gè)簡單的程序崇堵,最直觀的辦法,自然是用個(gè)一件讀操作客燕,從磁盤上把數(shù)據(jù)讀到內(nèi)存里面來鸳劳,

然后再用個(gè)Socket,把這些數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上去也搓。


3赏廓、我們只是要“搬運(yùn)”一份數(shù)據(jù),結(jié)果卻整整搬運(yùn)了四次

在這個(gè)過程中傍妒,數(shù)據(jù)一共發(fā)生了四次傳輸?shù)倪^程楚昭。其中兩次是DMA的傳輸,另外兩次拍顷,則是通過CPU控制的傳輸抚太。下面我們來具體看看這個(gè)過程。

第一次傳輸,是從硬盤上尿贫,讀到操作系統(tǒng)內(nèi)核的緩沖區(qū)里电媳。這個(gè)傳輸是通過DMA搬運(yùn)的。

第二次傳輸庆亡,需要從內(nèi)核緩沖區(qū)里面的數(shù)據(jù)匾乓,復(fù)制到我們應(yīng)用分配的內(nèi)存里面。這個(gè)傳輸是通過CPU搬運(yùn)的又谋。

第三次傳輸拼缝,要從我們應(yīng)用的內(nèi)存里面,再寫到操作系統(tǒng)的Socket的緩沖區(qū)里面去彰亥。這個(gè)傳輸咧七,還是由CPU搬運(yùn)的。

最后一次傳輸任斋,需要再從Socket的緩沖區(qū)里面继阻,寫到網(wǎng)卡的緩沖區(qū)里面去。這個(gè)傳輸又是通過DMA搬運(yùn)的废酷。


這個(gè)時(shí)候瘟檩,你可以回過頭看看這個(gè)過程。我們只是要“搬運(yùn)”?份數(shù)據(jù)澈蟆,結(jié)果卻整整搬運(yùn)了四次墨辛。而且這里面,從內(nèi)核的讀緩沖區(qū)傳輸?shù)綉?yīng)用的內(nèi)存里趴俘,

再從應(yīng)用的內(nèi)存里傳輸?shù)絊ocket的緩沖區(qū)里睹簇,其實(shí)都是把同一份數(shù)據(jù)在內(nèi)存里面搬運(yùn)來搬運(yùn)去,特別沒有效率哮幢。

4、我們就需要盡可能地減少數(shù)據(jù)搬運(yùn)的需求

像Kafka這樣的應(yīng)用場景志珍,其實(shí)一部分最終利用到的硬件資源橙垢,其實(shí)又都是在干這個(gè)搬運(yùn)數(shù)據(jù)的事兒。所以伦糯,我們就需要盡可能地減少數(shù)據(jù)搬運(yùn)的需求柜某。

事實(shí)上,Kafka做的事情就是敛纲,把這個(gè)數(shù)據(jù)搬運(yùn)的次數(shù)喂击,從上面的四次,變成了兩次淤翔,并且只有DMA來進(jìn)行數(shù)據(jù)搬運(yùn)翰绊,而不需要CPU。


Kafka的代碼調(diào)用了Java NIO庫,具體是FileChannel里面的transferTo方法监嗜。我們的數(shù)據(jù)并沒有讀到中間的應(yīng)用內(nèi)存里面谐檀,而是直接通過Channel,寫入到對(duì)應(yīng)的網(wǎng)絡(luò)設(shè)備里裁奇。

并且桐猬,對(duì)于Socket的操作,也不是寫入到Socket的Buffer里面刽肠,而是直接根據(jù)描述符(Descriptor)寫到到網(wǎng)卡的緩沖區(qū)里面溃肪。于是,在這個(gè)過程之中音五,我們只進(jìn)行了兩次數(shù)據(jù)傳輸惫撰。

5、同一份數(shù)據(jù)傳輸?shù)拇螖?shù)從四次變成了兩次


第一次放仗,是通過DMA润绎,從硬盤直接讀到操作系統(tǒng)內(nèi)核的讀緩沖區(qū)里面。第二次诞挨,則是根據(jù)Socket的描述符信息莉撇,直接從讀緩沖區(qū)里面,寫入到網(wǎng)卡的緩沖區(qū)里面惶傻。

這樣棍郎,我們同一份數(shù)據(jù)傳輸?shù)拇螖?shù)從四次變成了兩次,并且沒有通過CPU來進(jìn)行數(shù)據(jù)搬運(yùn)银室,所有的數(shù)據(jù)都是通過DMA來進(jìn)行傳輸?shù)摹?/p>

6涂佃、什么是零拷貝?

在這個(gè)方法里面蜈敢,我們沒有在內(nèi)存層面去“復(fù)制(Copy)”數(shù)據(jù)辜荠,所以這個(gè)方法,也被稱之為零拷貝(Zero-Copy)抓狭。IBM Developer Works里面有一篇文章伯病,專們寫過程序來測試過在同樣的硬件下,使用零拷貝能夠帶來的性能提升否过。我在這里放上這篇文章鏈接午笛。在這篇文章最后,你可以看到苗桂,無論傳輸數(shù)據(jù)量的大小药磺,傳輸同樣的數(shù)據(jù),使用了零拷貝能夠縮短65%的時(shí)間煤伟,大幅度提升了機(jī)器傳輸數(shù)據(jù)的吞吐量癌佩。想要深入了解零拷貝木缝,建議你可以仔細(xì)讀讀讀這篇文章。

DMA總結(jié)

講到這里驼卖,相信你對(duì)DMA的原理氨肌、作用和效果都有所理解了。那么酌畜,我們?起來回顧總結(jié)一下怎囚。、

如果我們始終讓CPU來進(jìn)行各種數(shù)據(jù)傳輸工作桥胞,會(huì)特別浪費(fèi)恳守。一方面,我們的數(shù)據(jù)傳輸工作用不到多少CPU核新的“計(jì)算”功能贩虾。另一方面催烘,CPU的運(yùn)轉(zhuǎn)速度也比I/O操作要快很多。

所以缎罢,我們希望能夠給CPU“減負(fù)”伊群。

于是,工程師們就在主板上放上了DMAC這樣一個(gè)協(xié)處理器芯片策精。通過這個(gè)芯片舰始,CPU只需要告訴DMAC,我們要傳輸什么數(shù)據(jù)咽袜,從哪里來丸卷,到哪里去,就可以放心離開了询刹。

后續(xù)的實(shí)際數(shù)據(jù)傳輸工作谜嫉,都會(huì)有DMAC來完成。隨著現(xiàn)代計(jì)算機(jī)各種外設(shè)硬件越來越多凹联,光一個(gè)通用的DMAC芯片不夠了沐兰,我們在各個(gè)外設(shè)上都加上了DMAC芯片,

使得CPU很少再需要關(guān)注數(shù)據(jù)傳輸?shù)墓ぷ髁恕?/p>

在我們實(shí)際的系統(tǒng)開發(fā)過程中蔽挠,利用好DMA的數(shù)據(jù)傳輸機(jī)制住闯,也可以大幅提升I/O的吞吐率。最典型的例子就是Kafka象泵。

傳統(tǒng)地從硬盤讀取數(shù)據(jù)寞秃,然后再通過網(wǎng)卡上向外發(fā)送斟叼,我們需要進(jìn)行四次數(shù)據(jù)傳輸偶惠,其中有兩次是發(fā)生在內(nèi)存里的緩沖區(qū)和對(duì)應(yīng)的硬件設(shè)備之間,我們沒法節(jié)省掉朗涩。

但是還有兩次忽孽,完全是通過CPU在內(nèi)存里面進(jìn)行數(shù)據(jù)復(fù)制。

在Kafka里,通過Java的NIO里面FileChannel的transferTo方法調(diào)用兄一,我們可以不用把數(shù)據(jù)復(fù)制到我們應(yīng)用程序的內(nèi)存里面厘线。通過DMA的方式,

我們可以把數(shù)據(jù)從內(nèi)存緩沖區(qū)直接寫到網(wǎng)卡的緩沖區(qū)里面出革。在使用了這樣的零拷貝的方法之后呢造壮,我們傳輸同樣數(shù)據(jù)的時(shí)間,可以縮減為原來的1/3骂束,相當(dāng)于提升了3倍的吞吐率耳璧。

這也是為什么,Kafka是目前實(shí)時(shí)數(shù)據(jù)傳輸管道的標(biāo)準(zhǔn)解決方案

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末展箱,一起剝皮案震驚了整個(gè)濱河市旨枯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌混驰,老刑警劉巖攀隔,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異栖榨,居然都是意外死亡昆汹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門治泥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筹煮,“玉大人,你說我怎么就攤上這事居夹“芰剩” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵准脂,是天一觀的道長劫扒。 經(jīng)常有香客問我,道長狸膏,這世上最難降的妖魔是什么沟饥? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮湾戳,結(jié)果婚禮上贤旷,老公的妹妹穿的比我還像新娘。我一直安慰自己砾脑,他們只是感情好幼驶,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著韧衣,像睡著了一般盅藻。 火紅的嫁衣襯著肌膚如雪购桑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天氏淑,我揣著相機(jī)與錄音勃蜘,去河邊找鬼。 笑死假残,一個(gè)胖子當(dāng)著我的面吹牛缭贡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辉懒,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼匀归,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耗帕?” 一聲冷哼從身側(cè)響起穆端,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仿便,沒想到半個(gè)月后体啰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗽仪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年荒勇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闻坚。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沽翔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窿凤,到底是詐尸還是另有隱情仅偎,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布雳殊,位于F島的核電站橘沥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏夯秃。R本人自食惡果不足惜座咆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仓洼。 院中可真熱鬧介陶,春花似錦、人聲如沸色建。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽镀岛。三九已至弦牡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間漂羊,已是汗流浹背驾锰。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留走越,地道東北人椭豫。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像旨指,于是被迫代替她去往敵國和親赏酥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345