
先從數(shù)據(jù)庫(kù)說(shuō)起。
我們都知道,數(shù)據(jù)庫(kù)中的數(shù)據(jù),只要應(yīng)用程序員不主動(dòng)刪除,就可以任意次讀寫(xiě),多少次都行。數(shù)據(jù)庫(kù)還對(duì)外提供了很漂亮的接口——SQL ——讓程序員操作數(shù)據(jù)。
但是數(shù)據(jù)庫(kù)不擅長(zhǎng)做“通知”(人家也不是干這種事的):例如,程序A向數(shù)據(jù)庫(kù)插入了一條數(shù)據(jù), 然后程序B想知道這次數(shù)據(jù)更新,然后做點(diǎn)事情。
這種"通知"的事情,一種辦法是用輪詢實(shí)現(xiàn), 程序B不斷地查數(shù)據(jù)庫(kù),看看有沒(méi)有新數(shù)據(jù)的到來(lái), 但是這種方法效率很低。
更直接的辦法是讓?xiě)?yīng)用程序之間直接交互,例如程序A調(diào)用程序B的RESTful API。
但問(wèn)題是程序B如果暫時(shí)不可用,程序A就會(huì)比較悲催,怎么辦呢?等一會(huì)兒再試? 如果程序B還不行,那就循環(huán)再試。調(diào)用方的責(zé)任太大。
于是消息隊(duì)列(MQ)就出現(xiàn)了,程序A把數(shù)據(jù)往消息隊(duì)列中一扔,完事走人,程序B想什么時(shí)候讀就什么時(shí)候讀,極其靈活。
所以MQ的重要功能就是解耦,讓兩個(gè)系統(tǒng)可以獨(dú)立運(yùn)行,異步操作,互不影響。
MQ還有一個(gè)好處就是允許程序A瘋狂地向其中放消息,程序B 可以慢悠悠地處理,這就起到了“消峰”的效果。
可是傳統(tǒng)的MQ也有問(wèn)題,通常情況下,一個(gè)消息確認(rèn)被讀取以后,就會(huì)被刪除。如果來(lái)了一個(gè)新的程序C,也想讀之前的消息,或者說(shuō)之前一段時(shí)間的消息,傳統(tǒng)MQ表示無(wú)能無(wú)力。
能不能把數(shù)據(jù)庫(kù)的特點(diǎn)和MQ的特點(diǎn)結(jié)合起來(lái)呢?
消息可以持久化,讓多個(gè)程序都可以讀取,并且還支持發(fā)布-訂閱這種模式。
Kafka出現(xiàn)了,它也是一個(gè)消息隊(duì)列,但是它能保存很長(zhǎng)一段時(shí)間的消息(因?yàn)樵谟脖P(pán)上),隊(duì)列中每個(gè)消息都有一個(gè)編號(hào)1,2,3,4.... ,這樣就支持多個(gè)程序來(lái)讀取。
只要記錄下每個(gè)程序都讀到了哪個(gè)編號(hào), 這個(gè)程序可以斷開(kāi)和Kafka的連接,這個(gè)程序可以崩潰,下一次就可以接著讀。
新的消費(fèi)者程序可以隨意加入讀取,不影響其他消費(fèi)者程序, 是不是很爽?
例如:程序B讀到了編號(hào)為3的消息, 程序C讀到了編號(hào)為5的消息, 這時(shí)候來(lái)了一個(gè)新的程序D,可以從頭開(kāi)始讀。
這其實(shí)和數(shù)據(jù)庫(kù)復(fù)制有點(diǎn)像:Kafka維護(hù)者“主數(shù)據(jù)庫(kù)”, 每個(gè)消費(fèi)者程序都是“從數(shù)據(jù)庫(kù)”, 只要記住編號(hào),消息都可以從“主數(shù)據(jù)庫(kù)”復(fù)制到“從數(shù)據(jù)庫(kù)”。
當(dāng)然,Kafka做的遠(yuǎn)不止于此,它還充分利用硬盤(pán)順序化讀取速度快的特性,再加上分區(qū),備份等高可用特性, 一個(gè)高吞吐量的分布式發(fā)布訂閱消息系統(tǒng)就誕生了。
Kafka的這些高級(jí)特性, 我們下一次詳細(xì)講吧。
寫(xiě)在最后
- 第一:看完點(diǎn)贊,感謝您對(duì)作者的認(rèn)可;
- ...
- 第二:隨手轉(zhuǎn)發(fā),分享知識(shí),讓更多人學(xué)習(xí)到;
- ...
- 第三:記得點(diǎn)關(guān)注,每天更新的?。。?/strong>
- ...