流
某一個(gè)時(shí)間點(diǎn)開始,產(chǎn)生數(shù)據(jù),并延伸到時(shí)間盡頭,無法預(yù)測(cè)下一條數(shù)據(jù)何時(shí)到達(dá)。比如鼠標(biāo)點(diǎn)擊事件clickEvent(x,y,timestamp),就是以時(shí)間戳為維度的一個(gè)流。理論上,流可以抽象世間萬物。高等數(shù)學(xué)里的級(jí)數(shù)就是一條完美的流。

流包含以下特性
- 有序。銀行帳戶操作為例,先存錢再取錢才認(rèn)為是合法操作。
- 不可變。當(dāng)事件發(fā)生了就不可能被改變,一個(gè)訂單取消了不等于訂單完全消失了,而是添加一個(gè)取消事件到數(shù)據(jù)流上,記錄對(duì)先前訂單的取消操作。如果你熟悉數(shù)據(jù)庫(kù)的binlog的話,你插入一條數(shù)據(jù)之后再刪除它,在數(shù)據(jù)庫(kù)里這條數(shù)據(jù)消失了,但是做主從備份或者數(shù)據(jù)回滾時(shí),插入和刪除操作都保留在log中。在這次一意義上,binlog其實(shí)就是一個(gè)數(shù)據(jù)流。
- 可重復(fù)播放(kafka支持)。支持重新處理一個(gè)很久以前(幾個(gè)月或者幾年)的流的能力,不管是出于糾錯(cuò),還是應(yīng)用新的數(shù)據(jù)分析方法,還是再次確認(rèn)分析結(jié)果。
三種編程模式
流處理其實(shí)是編程模式的一種。
- 請(qǐng)求-響應(yīng)模式。超低延遲,幾毫秒,往往是阻塞的,發(fā)出請(qǐng)求并等待返回結(jié)果。
- 批處理模式。高延遲,高吞吐量。比如hadoop任務(wù)在某個(gè)時(shí)間點(diǎn)被調(diào)度,讀入大量數(shù)據(jù),處理后輸出,最新輸出都是在下次任務(wù)完成之后。
- 流處理。在前兩種模式中取的這種方案。實(shí)際應(yīng)用往往不需要在幾毫秒之內(nèi)返回結(jié)果,但也不能容忍隔天的結(jié)果反饋周期。
Kafka stream不需要back pressure
流的產(chǎn)生和消費(fèi)往往是解耦合的(實(shí)現(xiàn)上都是異步線程),如果數(shù)據(jù)消費(fèi)的速度小于產(chǎn)生的速度,消息在流緩沖區(qū)中累積,直到緩沖區(qū)溢出。為了解決這個(gè)問題就有了back pressure,目的是用來控制流的產(chǎn)生速度。由于Kafka生產(chǎn)者和消費(fèi)者完全分離,并將消息持久化到磁盤中,相當(dāng)于一個(gè)中間buffer(唯一上限是磁盤空間),當(dāng)生產(chǎn)者產(chǎn)生消息超過消費(fèi)者消費(fèi)時(shí),消息累積到partition末尾,消費(fèi)者自己維護(hù)消費(fèi)位置的offset,以追趕生產(chǎn)者,Kafka流處理不存在back pressure問題。

處理流里邊的數(shù)據(jù)和處理其他數(shù)據(jù)是完全類似的,你首先讀數(shù)據(jù),然后處理(轉(zhuǎn)換,整合,過濾等等),最后存儲(chǔ)到某個(gè)地方。然而流處理有它獨(dú)有的概念來抽象。
時(shí)間
比如我們想計(jì)算每5分鐘的股票平均價(jià)格,但是消息的生產(chǎn)者因?yàn)榫W(wǎng)絡(luò)故障停機(jī)了2個(gè)小時(shí),當(dāng)生產(chǎn)者再次重啟時(shí),過去兩個(gè)小時(shí)的數(shù)據(jù)會(huì)推送到流中,然而我們的流處理程序已經(jīng)跑完,結(jié)果已經(jīng)發(fā)布。為了避免上述情況,我們應(yīng)該單獨(dú)維護(hù)流中每一個(gè)事件的發(fā)生時(shí)刻,讓分析結(jié)果不依賴于流的處理時(shí)間,而是由事件產(chǎn)生的時(shí)間決定。
三種時(shí)間(依次遞增):
- 事件發(fā)生時(shí)間。最關(guān)鍵的時(shí)間,流處理邏輯依賴的時(shí)間。比如股票價(jià)格變動(dòng),發(fā)生的時(shí)間(時(shí)刻),又比如用戶提交訂單的時(shí)間。
- 存儲(chǔ)時(shí)間。事件以消息的形式存儲(chǔ)在持久化設(shè)備的時(shí)間。往往與流處理無關(guān)。
- 處理時(shí)間。消息被處理時(shí)的時(shí)間。