Kafka史上最詳細(xì)原理總結(jié)下

Kafka史上最詳細(xì)原理總結(jié)分為上下兩部分,承上啟下

Kafka史上最詳細(xì)原理總結(jié)上

Kafka史上最詳細(xì)原理總結(jié)下

本篇為Kafka史上最詳細(xì)原理總結(jié)下,承接Kafka史上最詳細(xì)原理總結(jié)上

3.Partition Replication原則

Kafka高效文件存儲(chǔ)設(shè)計(jì)特點(diǎn)

  • Kafka把topic中一個(gè)parition大文件分成多個(gè)小文件段,通過多個(gè)小文件段,就容易定期清除或刪除已經(jīng)消費(fèi)完文件,減少磁盤占用。
  • 通過索引信息可以快速定位message和確定response的最大大小。
  • 通過index元數(shù)據(jù)全部映射到memory,可以避免segment file的IO磁盤操作。
  • 通過索引文件稀疏存儲(chǔ),可以大幅降低index文件元數(shù)據(jù)占用空間大小。

1. Kafka集群partition replication默認(rèn)自動(dòng)分配分析

下面以一個(gè)Kafka集群中4個(gè)Broker舉例,創(chuàng)建1個(gè)topic包含4個(gè)Partition,2 Replication;數(shù)據(jù)Producer流動(dòng)如圖所示:

(1)

image

(2)當(dāng)集群中新增2節(jié)點(diǎn),Partition增加到6個(gè)時(shí)分布情況如下:

image

副本分配邏輯規(guī)則如下:

  • 在Kafka集群中,每個(gè)Broker都有均等分配Partition的Leader機(jī)會(huì)。
  • 上述圖Broker Partition中,箭頭指向?yàn)楦北荆訮artition-0為例:broker1中parition-0為Leader,Broker2中Partition-0為副本。
  • 上述圖種每個(gè)Broker(按照BrokerId有序)依次分配主Partition,下一個(gè)Broker為副本,如此循環(huán)迭代分配,多副本都遵循此規(guī)則。

副本分配算法如下:

  • 將所有N Broker和待分配的i個(gè)Partition排序.
  • 將第i個(gè)Partition分配到第(i mod n)個(gè)Broker上.
  • 將第i個(gè)Partition的第j個(gè)副本分配到第((i + j) mod n)個(gè)Broker上.

4.Kafka Broker一些特性

4.1 無狀態(tài)的Kafka Broker :

1. Broker沒有副本機(jī)制,一旦broker宕機(jī),該broker的消息將都不可用。

2. Broker不保存訂閱者的狀態(tài),由訂閱者自己保存。

3. 無狀態(tài)導(dǎo)致消息的刪除成為難題(可能刪除的消息正在被訂閱),kafka采用基于時(shí)間的SLA(服務(wù)水平保證),消息保存一定時(shí)間(通常為7天)后會(huì)被刪除。

4. 消息訂閱者可以rewind back到任意位置重新進(jìn)行消費(fèi),當(dāng)訂閱者故障時(shí),可以選擇最小的offset進(jìn)行重新讀取消費(fèi)消息。

4.2 message的交付與生命周期 :

1. 不是嚴(yán)格的JMS, 因此kafka對消息的重復(fù)、丟失、錯(cuò)誤以及順序型沒有嚴(yán)格的要求。(這是與AMQ最大的區(qū)別)

2. kafka提供at-least-once delivery,即當(dāng)consumer宕機(jī)后,有些消息可能會(huì)被重復(fù)delivery。

3. 因每個(gè)partition只會(huì)被consumer group內(nèi)的一個(gè)consumer消費(fèi),故kafka保證每個(gè)partition內(nèi)的消息會(huì)被順序的訂閱。

4. Kafka為每條消息為每條消息計(jì)算CRC校驗(yàn),用于錯(cuò)誤檢測,crc校驗(yàn)不通過的消息會(huì)直接被丟棄掉。

4.3 壓縮

Kafka支持以集合(batch)為單位發(fā)送消息,在此基礎(chǔ)上,Kafka還支持對消息集合進(jìn)行壓縮,Producer端可以通過GZIP或Snappy格式對消息集合進(jìn)行壓縮。Producer端進(jìn)行壓縮之后,在Consumer端需進(jìn)行解壓。壓縮的好處就是減少傳輸?shù)臄?shù)據(jù)量,減輕對網(wǎng)絡(luò)傳輸?shù)膲毫Γ趯Υ髷?shù)據(jù)處理上,瓶頸往往體現(xiàn)在網(wǎng)絡(luò)上而不是CPU。

那么如何區(qū)分消息是壓縮的還是未壓縮的呢,Kafka在消息頭部添加了一個(gè)描述壓縮屬性字節(jié),這個(gè)字節(jié)的后兩位表示消息的壓縮采用的編碼,如果后兩位為0,則表示消息未被壓縮。

4.4 消息可靠性

在消息系統(tǒng)中,保證消息在生產(chǎn)和消費(fèi)過程中的可靠性是十分重要的,在實(shí)際消息傳遞過程中,可能會(huì)出現(xiàn)如下三中情況:

  • 一個(gè)消息發(fā)送失敗

  • 一個(gè)消息被發(fā)送多次

  • 最理想的情況:exactly-once ,一個(gè)消息發(fā)送成功且僅發(fā)送了一次

有許多系統(tǒng)聲稱它們實(shí)現(xiàn)了exactly-once,但是它們其實(shí)忽略了生產(chǎn)者或消費(fèi)者在生產(chǎn)和消費(fèi)過程中有可能失敗的情況。比如雖然一個(gè)Producer成功發(fā)送一個(gè)消息,但是消息在發(fā)送途中丟失,或者成功發(fā)送到broker,也被consumer成功取走,但是這個(gè)consumer在處理取過來的消息時(shí)失敗了。

從Producer端看:Kafka是這么處理的,當(dāng)一個(gè)消息被發(fā)送后,Producer會(huì)等待broker成功接收到消息的反饋(可通過參數(shù)控制等待時(shí)間),如果消息在途中丟失或是其中一個(gè)broker掛掉,Producer會(huì)重新發(fā)送(我們知道Kafka有備份機(jī)制,可以通過參數(shù)控制是否等待所有備份節(jié)點(diǎn)都收到消息)。

從Consumer端看:前面講到過partition,broker端記錄了partition中的一個(gè)offset值,這個(gè)值指向Consumer下一個(gè)即將消費(fèi)message。當(dāng)Consumer收到了消息,但卻在處理過程中掛掉,此時(shí)Consumer可以通過這個(gè)offset值重新找到上一個(gè)消息再進(jìn)行處理。Consumer還有權(quán)限控制這個(gè)offset值,對持久化到broker端的消息做任意處理。

4.5 備份機(jī)制

備份機(jī)制是Kafka0.8版本的新特性,備份機(jī)制的出現(xiàn)大大提高了Kafka集群的可靠性、穩(wěn)定性。有了備份機(jī)制后,Kafka允許集群中的節(jié)點(diǎn)掛掉后而不影響整個(gè)集群工作。一個(gè)備份數(shù)量為n的集群允許n-1個(gè)節(jié)點(diǎn)失敗。在所有備份節(jié)點(diǎn)中,有一個(gè)節(jié)點(diǎn)作為lead節(jié)點(diǎn),這個(gè)節(jié)點(diǎn)保存了其它備份節(jié)點(diǎn)列表,并維持各個(gè)備份間的狀體同步。下面這幅圖解釋了Kafka的備份機(jī)制:

image

4.6 Kafka高效性相關(guān)設(shè)計(jì)

4.6.1 消息的持久化

Kafka高度依賴文件系統(tǒng)來存儲(chǔ)和緩存消息(AMQ的nessage是持久化到mysql數(shù)據(jù)庫中的),因?yàn)橐话愕娜苏J(rèn)為磁盤是緩慢的,這導(dǎo)致人們對持久化結(jié)構(gòu)具有競爭性持懷疑態(tài)度。其實(shí),磁盤的快或者慢,這決定于我們?nèi)绾问褂么疟P。因?yàn)榇疟P線性寫的速度遠(yuǎn)遠(yuǎn)大于隨機(jī)寫。線性讀寫在大多數(shù)應(yīng)用場景下是可以預(yù)測的。

4.6.2 常數(shù)時(shí)間性能保證

每個(gè)Topic的Partition的是一個(gè)大文件夾,里面有無數(shù)個(gè)小文件夾segment,但partition是一個(gè)隊(duì)列,隊(duì)列中的元素是segment,消費(fèi)的時(shí)候先從第0個(gè)segment開始消費(fèi),新來message存在最后一個(gè)消息隊(duì)列中。對于segment也是對隊(duì)列,隊(duì)列元素是message,有對應(yīng)的offsite標(biāo)識(shí)是哪個(gè)message。消費(fèi)的時(shí)候先從這個(gè)segment的第一個(gè)message開始消費(fèi),新來的message存在segment的最后。

消息系統(tǒng)的持久化隊(duì)列可以構(gòu)建在對一個(gè)文件的讀和追加上,就像一般情況下的日志解決方案。它有一個(gè)優(yōu)點(diǎn),所有的操作都是常數(shù)時(shí)間,并且讀寫之間不會(huì)相互阻塞。這種設(shè)計(jì)具有極大的性能優(yōu)勢:最終系統(tǒng)性能和數(shù)據(jù)大小完全無關(guān),服務(wù)器可以充分利用廉價(jià)的硬盤來提供高效的消息服務(wù)。

事實(shí)上還有一點(diǎn),磁盤空間的無限增大而不影響性能這點(diǎn),意味著我們可以提供一般消息系統(tǒng)無法提供的特性。比如說,消息被消費(fèi)后不是立馬被刪除,我們可以將這些消息保留一段相對比較長的時(shí)間(比如一個(gè)星期)。

5.Kafka 生產(chǎn)者-消費(fèi)者

 消息系統(tǒng)通常都會(huì)由生產(chǎn)者,消費(fèi)者,Broker三大部分組成,生產(chǎn)者會(huì)將消息寫入到Broker,消費(fèi)者會(huì)從Broker中讀取出消息,不同的MQ實(shí)現(xiàn)的Broker實(shí)現(xiàn)會(huì)有所不同,不過Broker的本質(zhì)都是要負(fù)責(zé)將消息落地到服務(wù)端的存儲(chǔ)系統(tǒng)中。具體步驟如下:
  1. 生產(chǎn)者客戶端應(yīng)用程序產(chǎn)生消息:

    1. 客戶端連接對象將消息包裝到請求中發(fā)送到服務(wù)端

    2. 服務(wù)端的入口也有一個(gè)連接對象負(fù)責(zé)接收請求,并將消息以文件的形式存儲(chǔ)起來

    3. 服務(wù)端返回響應(yīng)結(jié)果給生產(chǎn)者客戶端

  2. 消費(fèi)者客戶端應(yīng)用程序消費(fèi)消息:

    1. 客戶端連接對象將消費(fèi)信息也包裝到請求中發(fā)送給服務(wù)端

    2. 服務(wù)端從文件存儲(chǔ)系統(tǒng)中取出消息

    3. 服務(wù)端返回響應(yīng)結(jié)果給消費(fèi)者客戶端

    4. 客戶端將響應(yīng)結(jié)果還原成消息并開始處理消息

                                                                        圖4-1 客戶端和服務(wù)端交互
      

5.1 Producers

Producers直接發(fā)送消息到broker上的leader partition,不需要經(jīng)過任何中介或其他路由轉(zhuǎn)發(fā)。為了實(shí)現(xiàn)這個(gè)特性,kafka集群中的每個(gè)broker都可以響應(yīng)producer的請求,并返回topic的一些元信息,這些元信息包括哪些機(jī)器是存活的,topic的leader partition都在哪,現(xiàn)階段哪些leader partition是可以直接被訪問的。

Producer客戶端自己控制著消息被推送到哪些partition。實(shí)現(xiàn)的方式可以是隨機(jī)分配、實(shí)現(xiàn)一類隨機(jī)負(fù)載均衡算法,或者指定一些分區(qū)算法。Kafka提供了接口供用戶實(shí)現(xiàn)自定義的partition,用戶可以為每個(gè)消息指定一個(gè)partitionKey,通過這個(gè)key來實(shí)現(xiàn)一些hash分區(qū)算法。比如,把userid作為partitionkey的話,相同userid的消息將會(huì)被推送到同一個(gè)partition。

以Batch的方式推送數(shù)據(jù)可以極大的提高處理效率,kafka Producer 可以將消息在內(nèi)存中累計(jì)到一定數(shù)量后作為一個(gè)batch發(fā)送請求。Batch的數(shù)量大小可以通過Producer的參數(shù)控制,參數(shù)值可以設(shè)置為累計(jì)的消息的數(shù)量(如500條)、累計(jì)的時(shí)間間隔(如100ms)或者累計(jì)的數(shù)據(jù)大小(64KB)。通過增加batch的大小,可以減少網(wǎng)絡(luò)請求和磁盤IO的次數(shù),當(dāng)然具體參數(shù)設(shè)置需要在效率和時(shí)效性方面做一個(gè)權(quán)衡。

Producers可以異步的并行的向kafka發(fā)送消息,但是通常producer在發(fā)送完消息之后會(huì)得到一個(gè)future響應(yīng),返回的是offset值或者發(fā)送過程中遇到的錯(cuò)誤。這其中有個(gè)非常重要的參數(shù)“acks”,這個(gè)參數(shù)決定了producer要求leader partition 收到確認(rèn)的副本個(gè)數(shù),如果acks設(shè)置數(shù)量為0,表示producer不會(huì)等待broker的響應(yīng),所以,producer無法知道消息是否發(fā)送成功,這樣有可能會(huì)導(dǎo)致數(shù)據(jù)丟失,但同時(shí),acks值為0會(huì)得到最大的系統(tǒng)吞吐量。

若acks設(shè)置為1,表示producer會(huì)在leader partition收到消息時(shí)得到broker的一個(gè)確認(rèn),這樣會(huì)有更好的可靠性,因?yàn)榭蛻舳藭?huì)等待直到broker確認(rèn)收到消息。若設(shè)置為-1,producer會(huì)在所有備份的partition收到消息時(shí)得到broker的確認(rèn),這個(gè)設(shè)置可以得到最高的可靠性保證。

Kafka 消息有一個(gè)定長的header和變長的字節(jié)數(shù)組組成。因?yàn)閗afka消息支持字節(jié)數(shù)組,也就使得kafka可以支持任何用戶自定義的序列號(hào)格式或者其它已有的格式如Apache Avro、protobuf等。Kafka沒有限定單個(gè)消息的大小,但我們推薦消息大小不要超過1MB,通常一般消息大小都在1~10kB之前。

發(fā)布消息時(shí),kafka client先構(gòu)造一條消息,將消息加入到消息集set中(kafka支持批量發(fā)布,可以往消息集合中添加多條消息,一次行發(fā)布),send消息時(shí),producer client需指定消息所屬的topic。

5.2 Consumers

Kafka提供了兩套consumer api,分為high-level api和sample-api。Sample-api 是一個(gè)底層的API,它維持了一個(gè)和單一broker的連接,并且這個(gè)API是完全無狀態(tài)的,每次請求都需要指定offset值,因此,這套API也是最靈活的。

在kafka中,當(dāng)前讀到哪條消息的offset值是由consumer來維護(hù)的,因此,consumer可以自己決定如何讀取kafka中的數(shù)據(jù)。比如,consumer可以通過重設(shè)offset值來重新消費(fèi)已消費(fèi)過的數(shù)據(jù)。不管有沒有被消費(fèi),kafka會(huì)保存數(shù)據(jù)一段時(shí)間,這個(gè)時(shí)間周期是可配置的,只有到了過期時(shí)間,kafka才會(huì)刪除這些數(shù)據(jù)。(這一點(diǎn)與AMQ不一樣,AMQ的message一般來說都是持久化到mysql中的,消費(fèi)完的message會(huì)被delete掉)

High-level API封裝了對集群中一系列broker的訪問,可以透明的消費(fèi)一個(gè)topic。它自己維持了已消費(fèi)消息的狀態(tài),即每次消費(fèi)的都是下一個(gè)消息。

High-level API還支持以組的形式消費(fèi)topic,如果consumers有同一個(gè)組名,那么kafka就相當(dāng)于一個(gè)隊(duì)列消息服務(wù),而各個(gè)consumer均衡的消費(fèi)相應(yīng)partition中的數(shù)據(jù)。若consumers有不同的組名,那么此時(shí)kafka就相當(dāng)與一個(gè)廣播服務(wù),會(huì)把topic中的所有消息廣播到每個(gè)consumer。

High level api和Low level api是針對consumer而言的,和producer無關(guān)。

High level api是consumer讀的partition的offsite是存在zookeeper上。High level api 會(huì)啟動(dòng)另外一個(gè)線程去每隔一段時(shí)間,offsite自動(dòng)同步到zookeeper上。換句話說,如果使用了High level api, 每個(gè)message只能被讀一次,一旦讀了這條message之后,無論我consumer的處理是否ok。High level api的另外一個(gè)線程會(huì)自動(dòng)的把offiste+1同步到zookeeper上。如果consumer讀取數(shù)據(jù)出了問題,offsite也會(huì)在zookeeper上同步。因此,如果consumer處理失敗了,會(huì)繼續(xù)執(zhí)行下一條。這往往是不對的行為。因此,Best Practice是一旦consumer處理失敗,直接讓整個(gè)conusmer group拋Exception終止,但是最后讀的這一條數(shù)據(jù)是丟失了,因?yàn)樵趜ookeeper里面的offsite已經(jīng)+1了。等再次啟動(dòng)conusmer group的時(shí)候,已經(jīng)從下一條開始讀取處理了。

Low level api是consumer讀的partition的offsite在consumer自己的程序中維護(hù)。不會(huì)同步到zookeeper上。但是為了kafka manager能夠方便的監(jiān)控,一般也會(huì)手動(dòng)的同步到zookeeper上。這樣的好處是一旦讀取某個(gè)message的consumer失敗了,這條message的offsite我們自己維護(hù),我們不會(huì)+1。下次再啟動(dòng)的時(shí)候,還會(huì)從這個(gè)offsite開始讀。這樣可以做到exactly once對于數(shù)據(jù)的準(zhǔn)確性有保證。

對于Consumer group:

1. 允許consumer group(包含多個(gè)consumer,如一個(gè)集群同時(shí)消費(fèi))對一個(gè)topic進(jìn)行消費(fèi),不同的consumer group之間獨(dú)立消費(fèi)。

2. 為了對減小一個(gè)consumer group中不同consumer之間的分布式協(xié)調(diào)開銷,指定partition為最小的并行消費(fèi)單位,即一個(gè)group內(nèi)的consumer只能消費(fèi)不同的partition。

image

Consumer與Partition的關(guān)系:

  • 如果consumer比partition多,是浪費(fèi),因?yàn)閗afka的設(shè)計(jì)是在一個(gè)partition上是不允許并發(fā)的,所以consumer數(shù)不要大于partition數(shù)

  • 如果consumer比partition少,一個(gè)consumer會(huì)對應(yīng)于多個(gè)partitions,這里主要合理分配consumer數(shù)和partition數(shù),否則會(huì)導(dǎo)致partition里面的數(shù)據(jù)被取的不均勻

  • 如果consumer從多個(gè)partition讀到數(shù)據(jù),不保證數(shù)據(jù)間的順序性,kafka只保證在一個(gè)partition上數(shù)據(jù)是有序的,但多個(gè)partition,根據(jù)你讀的順序會(huì)有不同

  • 增減consumer,broker,partition會(huì)導(dǎo)致rebalance,所以rebalance后consumer對應(yīng)的partition會(huì)發(fā)生變化

  • High-level接口中獲取不到數(shù)據(jù)的時(shí)候是會(huì)block的

負(fù)載低的情況下可以每個(gè)線程消費(fèi)多個(gè)partition。但負(fù)載高的情況下,Consumer 線程數(shù)最好和Partition數(shù)量保持一致。如果還是消費(fèi)不過來,應(yīng)該再開 Consumer 進(jìn)程,進(jìn)程內(nèi)線程數(shù)同樣和分區(qū)數(shù)一致。

消費(fèi)消息時(shí),kafka client需指定topic以及partition number(每個(gè)partition對應(yīng)一個(gè)邏輯日志流,如topic代表某個(gè)產(chǎn)品線,partition代表產(chǎn)品線的日志按天切分的結(jié)果),consumer client訂閱后,就可迭代讀取消息,如果沒有消息,consumer client會(huì)阻塞直到有新的消息發(fā)布。consumer可以累積確認(rèn)接收到的消息,當(dāng)其確認(rèn)了某個(gè)offset的消息,意味著之前的消息也都已成功接收到,此時(shí)broker會(huì)更新zookeeper上地offset registry。

5.3 高效的數(shù)據(jù)傳輸

  1. 發(fā)布者每次可發(fā)布多條消息(將消息加到一個(gè)消息集合中發(fā)布), consumer每次迭代消費(fèi)一條消息。

  2. 不創(chuàng)建單獨(dú)的cache,使用系統(tǒng)的page cache。發(fā)布者順序發(fā)布,訂閱者通常比發(fā)布者滯后一點(diǎn)點(diǎn),直接使用Linux的page cache效果也比較后,同時(shí)減少了cache管理及垃圾收集的開銷。

  3. 使用sendfile優(yōu)化網(wǎng)絡(luò)傳輸,減少一次內(nèi)存拷貝。

6.Kafka 與 Zookeeper

6.1 Zookeeper 協(xié)調(diào)控制

  1. 管理broker與consumer的動(dòng)態(tài)加入與離開。(Producer不需要管理,隨便一臺(tái)計(jì)算機(jī)都可以作為Producer向Kakfa Broker發(fā)消息)

  2. 觸發(fā)負(fù)載均衡,當(dāng)broker或consumer加入或離開時(shí)會(huì)觸發(fā)負(fù)載均衡算法,使得一

    個(gè)consumer group內(nèi)的多個(gè)consumer的消費(fèi)負(fù)載平衡。(因?yàn)橐粋€(gè)comsumer消費(fèi)一個(gè)或多個(gè)partition,一個(gè)partition只能被一個(gè)consumer消費(fèi))

  3. 維護(hù)消費(fèi)關(guān)系及每個(gè)partition的消費(fèi)信息。

6.2 Zookeeper上的細(xì)節(jié):

  1. 每個(gè)broker啟動(dòng)后會(huì)在zookeeper上注冊一個(gè)臨時(shí)的broker registry,包含broker的ip地址和端口號(hào),所存儲(chǔ)的topics和partitions信息。

  2. 每個(gè)consumer啟動(dòng)后會(huì)在zookeeper上注冊一個(gè)臨時(shí)的consumer registry:包含consumer所屬的consumer group以及訂閱的topics。

  3. 每個(gè)consumer group關(guān)聯(lián)一個(gè)臨時(shí)的owner registry和一個(gè)持久的offset registry。對于被訂閱的每個(gè)partition包含一個(gè)owner registry,內(nèi)容為訂閱這個(gè)partition的consumer id;同時(shí)包含一個(gè)offset registry,內(nèi)容為上一次訂閱的offset。

原文出處:

Kafka史上最詳細(xì)原理總結(jié)

Kafka史上最詳細(xì)原理總結(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,667評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,635評論 2 380

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

  • 本文轉(zhuǎn)載自http://dataunion.org/?p=9307 背景介紹Kafka簡介Kafka是一種分布式的...
    Bottle丶Fish閱讀 5,491評論 0 34
  • 目標(biāo) 高吞吐量來支持高容量的事件流處理 支持從離線系統(tǒng)加載數(shù)據(jù) 低延遲的消息系統(tǒng) 持久化 依賴文件系統(tǒng),持久化到本...
    jiangmo閱讀 1,313評論 0 4
  • 背景介紹 Kafka簡介 Kafka是一種分布式的,基于發(fā)布/訂閱的消息系統(tǒng)。主要設(shè)計(jì)目標(biāo)如下: 以時(shí)間復(fù)雜度為O...
    高廣超閱讀 12,869評論 8 167
  • 一、為什么需要消息系統(tǒng) 1.解耦: 允許你獨(dú)立的擴(kuò)展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。 2.冗...
    java成功之路閱讀 1,493評論 0 3
  • 我們從來不缺浪漫的基因,這點(diǎn)在華夏先民中體現(xiàn)更甚!女媧補(bǔ)天,飛龍盤天,夸父逐日,后羿射日,嫦娥奔月,吳剛伐桂……中...
    Dr茶葉閱讀 300評論 0 1