Kafka能解決什么問題?
以銀行的金融系統(tǒng)為例疤祭,
銀行金融系統(tǒng)每天有大量的交易發(fā)生盼产,這些交易很多需要進(jìn)行實(shí)時(shí)的檢查與處理,比如一筆交易發(fā)生勺馆,這筆交易是否是欺詐交易戏售,這筆交易是否已經(jīng)達(dá)到限額了侨核,相關(guān)用戶是否在黑名單中,交易結(jié)果聯(lián)動短信灌灾、Email等渠道通知用戶……等等搓译,也許一筆簡單的交易,就要與反欺詐系統(tǒng)锋喜、黑名單系統(tǒng)侥衬、限額或授信管控系統(tǒng)、短信郵件系統(tǒng)進(jìn)行通訊跑芳。
這些還不是全部轴总,銀行金融系統(tǒng)在進(jìn)行運(yùn)行時(shí),如果出現(xiàn)了問題博个,需要日志及時(shí)定位問題怀樟;為了及時(shí)發(fā)現(xiàn)問題,要將處理結(jié)果實(shí)施發(fā)送監(jiān)控平臺盆佣;為了預(yù)防突發(fā)事件發(fā)生往堡,還需要備份系統(tǒng)做高可用處理。這就仍然需要與日志系統(tǒng)共耍、監(jiān)控系統(tǒng)虑灰、備份系統(tǒng)進(jìn)行通訊。
最重要的是痹兜,上面這些處理必須在極短時(shí)間內(nèi)完成穆咐,否則用戶就會感到有卡頓,影響體驗(yàn)字旭。
怎么解決這些問題呢对湃?將交易處理相關(guān)的系統(tǒng)全部直連起來,似乎是個(gè)辦法:
但明顯不是一個(gè)好辦法遗淳,你將面臨極高的后續(xù)維護(hù)成本:
于是拍柒,消息分發(fā)處理的概念出現(xiàn)了,我們在各個(gè)系統(tǒng)之間搭建一個(gè)消息分發(fā)的總控系統(tǒng)屈暗,連接這個(gè)總控系統(tǒng)的主要有兩方:
1拆讯、消息供應(yīng)方(Producer):他們會產(chǎn)生消息,并將消息送給消息分發(fā)系統(tǒng)养叛。
2种呐、消息消費(fèi)方(Comsumer):他們需要最新的消息以進(jìn)行自身功能的處理,他們會從消息分發(fā)系統(tǒng)拿消息一铅。
上方的Producers會產(chǎn)生很多的消息和信息送給kafka陕贮。
kafka會把這些消息存儲下來堕油。
下方的Consumers會從kafka獲取它所需要的數(shù)據(jù)潘飘,然后自行處理肮之,比如Consumers可能會降消息存儲到hadoop、cassandra卜录、HBase戈擒。
什么是 Kafka?
眾所周知艰毒,Kafka 是 LinkedIn 公司內(nèi)部孵化的項(xiàng)目筐高。
根據(jù)查閱到的公開信息顯示,LinkedIn 最開始有強(qiáng)烈的數(shù)據(jù)強(qiáng)實(shí)時(shí)處理方面的需求丑瞧,其內(nèi)部的諸多子系統(tǒng)要執(zhí)行多種類型的數(shù)據(jù)處理與分析柑土,主要包括業(yè)務(wù)系統(tǒng)和應(yīng)用程序性能監(jiān)控,以及用戶行為數(shù)據(jù)處理等绊汹。
當(dāng)時(shí)他們碰到的主要問題包括:數(shù)據(jù)正確性不足稽屏。因?yàn)閿?shù)據(jù)的收集主要采用輪詢(Polling)的方式,如何確定輪詢的間隔時(shí)間就變成了一個(gè)高度經(jīng)驗(yàn)化的事情西乖。雖然可以采用一些類似于啟發(fā)式算法(Heuristic)來幫助評估間隔時(shí)間值狐榔,但一旦指定不當(dāng),必然會造成較大的數(shù)據(jù)偏差获雕。系統(tǒng)高度定制化薄腻,維護(hù)成本高。各個(gè)業(yè)務(wù)子系統(tǒng)都需要對接數(shù)據(jù)收集模塊届案,引入了大量的定制開銷和人工成本庵楷。為了解決這些問題,LinkedIn 工程師嘗試過使用 ActiveMQ 來解決這些問題楣颠,但效果并不理想嫁乘。顯然需要有一個(gè)“大一統(tǒng)”的系統(tǒng)來取代現(xiàn)有的工作方式,而這個(gè)系統(tǒng)就是 Kafka球碉。
關(guān)于Kafka 的命名蜓斧,作者之一 Jay Kreps 曾經(jīng)談原因:
因?yàn)?Kafka 系統(tǒng)的寫性能很強(qiáng),所以找了個(gè)作家的名字來命名似乎是一個(gè)好主意睁冬。大學(xué)期間我上了很多文學(xué)課挎春,非常喜歡 Franz Kafka 這個(gè)作家,另外為開源軟件起這個(gè)名字聽上去很酷豆拨。
Kafka的基本原理
通過這張圖我們來捋一捋相關(guān)的概念及之間的關(guān)系:
如果看到這張圖你很懵逼直奋,木有關(guān)系!
我們先來分析相關(guān)概念
Producer:Producer即生產(chǎn)者,消息的產(chǎn)生者,是消息的入口权旷。
kafka cluster:Broker:Broker是kafka實(shí)例埂软,每個(gè)服務(wù)器上有一個(gè)或多個(gè)kafka的實(shí)例瘟仿,我們姑且認(rèn)為每個(gè)broker對應(yīng)一臺服務(wù)器床未。每個(gè)kafka集群內(nèi)的broker都有一個(gè)不重復(fù)的編號风响,如圖中的broker-0镰禾、broker-1等……
Topic:消息的主題船逮,可以理解為消息的分類顾腊,kafka的數(shù)據(jù)就保存在topic。在每個(gè)broker上都可以創(chuàng)建多個(gè)topic挖胃。
Partition:Topic的分區(qū)杂靶,每個(gè)topic可以有多個(gè)分區(qū),分區(qū)的作用是做負(fù)載酱鸭,提高kafka的吞吐量吗垮。同一個(gè)topic在不同的分區(qū)的數(shù)據(jù)是不重復(fù)的,partition的表現(xiàn)形式就是一個(gè)一個(gè)的文件夾凹髓!
Replication:每一個(gè)分區(qū)都有多個(gè)副本抱既,副本的作用是做備胎。當(dāng)主分區(qū)(Leader)故障的時(shí)候會選擇一個(gè)備胎(Follower)上位扁誓,成為Leader防泵。在kafka中默認(rèn)副本的最大數(shù)量是10個(gè),且副本的數(shù)量不能大于Broker的數(shù)量蝗敢,follower和leader絕對是在不同的機(jī)器捷泞,同一機(jī)器對同一個(gè)分區(qū)也只可能存放一個(gè)副本(包括自己)。
Message:每一條發(fā)送的消息主體寿谴。
Consumer:消費(fèi)者锁右,即消息的消費(fèi)方,是消息的出口讶泰。
Consumer Group:我們可以將多個(gè)消費(fèi)組組成一個(gè)消費(fèi)者組咏瑟,在kafka的設(shè)計(jì)中同一個(gè)分區(qū)的數(shù)據(jù)只能被消費(fèi)者組中的某一個(gè)消費(fèi)者消費(fèi)。同一個(gè)消費(fèi)者組的消費(fèi)者可以消費(fèi)同一個(gè)topic的不同分區(qū)的數(shù)據(jù)痪署,這也是為了提高kafka的吞吐量码泞!
Zookeeper:kafka集群依賴zookeeper來保存集群的的元信息,來保證系統(tǒng)的可用性狼犯。
發(fā)送數(shù)據(jù)
我們看上面的架構(gòu)圖中余寥,producer就是生產(chǎn)者,是數(shù)據(jù)的入口悯森。注意看圖中的紅色箭頭宋舷,Producer在寫入數(shù)據(jù)的時(shí)候永遠(yuǎn)的找leader,不會直接將數(shù)據(jù)寫入follower瓢姻!那leader怎么找呢祝蝠?
寫入的流程又是什么樣的呢?我們看下圖:
發(fā)送的流程就在圖中已經(jīng)說明了,就不單獨(dú)在文字列出來了绎狭!需要注意的一點(diǎn)是细溅,消息寫入leader后,follower是主動的去leader進(jìn)行同步的坟岔!producer采用push模式將數(shù)據(jù)發(fā)布到broker,每條消息追加到分區(qū)中摔桦,順序?qū)懭氪疟P社付,所以保證同一分區(qū)內(nèi)的數(shù)據(jù)是有序的!寫入示意圖如下:
搭建使用
首先下載 kafka和zookeeper的安裝包?
kafka集群的數(shù)據(jù)同步是依賴 zookeeper的邻耕,先啟動 zookeeper鸥咖。
解壓?
tar -xvf apache-zookeeper-3.5.7-bin.tar.gz
配置文件,安裝包 里面 有一個(gè)默認(rèn)的配置文件?zoo_sample.cfg,直接使用里面的配置項(xiàng)即可
cp conf/zoo_sample.cfg conf/zoo.cfg
啟動 zookeeper
./bin/zkServer.sh start
通過ps查看 zookeeper已經(jīng)啟動
Kafka
解壓
tar -xvf kafka_2.11-2.4.0.tgz
這里需要修改?config/server.properties 里面的幾個(gè)配置項(xiàng)
listeners=PLAINTEXT://192.168.157.133:9092
advertised.listeners=PLAINTEXT://192.168.157.133:9092
zookeeper.connect=localhost:2181
auto.create.topics.enable=false
unclean.leader.election.enable=false
auto.leader.rebalance.enable=false
這里解釋一下這幾個(gè)配置項(xiàng)的參數(shù)
門牌號
listeners:學(xué)名叫監(jiān)聽器兄世,格式一般為”listener_name://host_name:port“啼辣,其實(shí)就是告訴外部連接者要通過什么協(xié)議訪問指定主機(jī)名和端口開放的 Kafka 服務(wù)。
掛上招牌
advertised.listeners:和 listeners 相比多了個(gè) advertised御滩。Advertised 的含義表示宣稱的鸥拧、公布的,就是說這組監(jiān)聽器是 Broker 用于對外發(fā)布的削解。
不能自立為王
auto.create.topics.enable: 是否允許自動創(chuàng)建 Topic
一般正式環(huán)境富弦,還是最好不要允許自動創(chuàng)建比較好,想象使用kafka一個(gè)topic名字拼錯了氛驮,沒有報(bào)錯腕柜,而是去自動新建了一個(gè)topic,久而久之矫废,出現(xiàn)了很多莫名其妙的topic盏缤。
寧缺毋濫
unclean.leader.election.enable:是否允許 Unclean Leader 選舉??
kafka有很多的副本用來備份信息,所有的副本中只有一個(gè)Leader 副本對外提供服務(wù)蓖扑,F(xiàn)ollower同步一份數(shù)據(jù)唉铜。
那么問題來了,這些副本都有資格競爭 Leader 嗎律杠?顯然不是打毛,只有保存數(shù)據(jù)比較多的那些副本才有資格競選,那些落后進(jìn)度太多的副本沒資格做這件事俩功。
好了幻枉,現(xiàn)在出現(xiàn)這種情況了:假設(shè)那些保存數(shù)據(jù)比較多的副本都掛了怎么辦?我們還要不要進(jìn)行 Leader 選舉了诡蜓?
此時(shí)這個(gè)參數(shù)就派上用場了熬甫。如果設(shè)置成 false,那么就堅(jiān)持之前的原則蔓罚,堅(jiān)決不能讓那些落后太多的副本競選 Leader椿肩。
江山不易改
auto.leader.rebalance.enable:表示關(guān)閉定期進(jìn)行 Leader 選舉
換一次 Leader 代價(jià)很高的瞻颂,原本向 A 發(fā)送請求的所有客戶端都要切換成向 B 發(fā)送請求,而且這種換 Leader 本質(zhì)上沒有任何性能收益郑象,因此我建議你在生產(chǎn)環(huán)境中把這個(gè)參數(shù)設(shè)置成 false贡这。
Python demo