Partition
Parition是物理上的概念,每個Topic包含一個或多個Partition.
Kafka通過Zookeeper管理集群配置,選舉leader,以及在Consumer Group發(fā)生變化時進行rebalance。Producer使用push模式將消息發(fā)布到broker,Consumer使用pull模式從broker訂閱并消費消息。
分片:為了提升性能,為每個topic建多個partition,每個Partition在物理上對應一個文件夾,該文件夾下存儲這個Partition的所有消息和索引文件。若創(chuàng)建topic1和topic2兩個topic,且分別有13個和19個分區(qū),則整個集群上會相應會生成共32個文件夾(本文所用集群共8個節(jié)點,此處topic1和topic2 replication-factor均為1)
消息持久化文件結構:
$KAFKA_HOME/config/server.properties
# The minimum age of a log file to be eligible for deletion
log.retention.hours=168
# The maximum size of a log segment file. When this size is reached a new log segment will be created.
log.segment.bytes=1073741824
# The interval at which log segments are checked to see if they can be deleted according to the retention policies
log.retention.check.interval.ms=300000
# If log.cleaner.enable=true is set the cleaner will be enabled and individual logs can then be marked for log compaction.
log.cleaner.enable=false
#新建topic默認的partion數(shù)量
num.partitions=10
副本:
消費者組:
如果需要實現(xiàn)廣播,只要每個Consumer有一個獨立的Group就可以了。要實現(xiàn)單播只要所有的Consumer在同一個Group里。用Consumer Group還可以將Consumer進行自由的分組而不需要多次發(fā)送消息到不同的Topic。
與rocketmq機制有點不同,嚴格來說只是對應了rocketmq的集群消費模式
push模式很難適應消費速率不同的消費者,因為消息發(fā)送速率是由broker決定的。push模式的目標是盡可能以最快速度傳遞消息,但是這樣很容易造成Consumer來不及處理消息,典型的表現(xiàn)就是拒絕服務以及網(wǎng)絡擁塞。而pull模式則可以根據(jù)Consumer的消費能力以適當?shù)乃俾氏M消息。
對于Kafka而言,pull模式更合適。pull模式可簡化broker的設計,Consumer可自主控制消費消息的速率,同時Consumer可以自己控制消費方式——即可批量消費也可逐條消費,同時還能選擇不同的提交方式從而實現(xiàn)不同的傳輸語義。
kafka的高可用
復制replication
一個topic有多個partition,為了盡可能的發(fā)揮負載均衡的作用,那partion就要大于broker的數(shù)據(jù),然后盡可能的均衡分布到每臺broker上。
同一個partion有多個副本,分布在不同的機器上。當然不能再同一個broker上,一掛全掛玩毛線。
Kafka分配Replica的算法如下:
將所有Broker(假設共n個Broker)和待分配的Partition排序
將第i個Partition分配到第(i mod n)個Broker上
將第i個Partition的第j個Replica分配到第((i + j) mod n)個Broker上
leader選舉機制
為了保證數(shù)據(jù)一致性,必須在這些replica中選出leader
rocketmq是寫死的master 、slave ,簡單粗暴好用。
zookeeper保存了集群狀態(tài)信息,有多少topic 路由 分區(qū)信息 副本信息 分區(qū)leader信息
和大部分分布式系統(tǒng)一樣,Kafka處理失敗需要明確定義一個Broker是否“活著”。對于Kafka而言,Kafka存活包含兩個條件,一是它必須維護與Zookeeper的session(這個通過Zookeeper的Heartbeat機制來實現(xiàn))。二是Follower必須能夠及時將Leader的消息復制過來,不能“落后太多”
ISR(即in-sync Replica)
Kafka在Zookeeper中動態(tài)維護了一個ISR(in-sync replicas),這個ISR里的所有Replica都跟上了leader,只有ISR里的成員才有被選為Leader的可能。在這種模式下,對于f+1個Replica,一個Partition能在保證不丟失已經commit的消息的前提下容忍f個Replica的失敗。在大多數(shù)使用場景中,這種模式是非常有利的。事實上,為了容忍f個Replica的失敗,Majority Vote和ISR在commit前需要等待的Replica數(shù)量是一樣的,但是ISR需要的總的Replica的個數(shù)幾乎是Majority Vote的一半。
leader選舉不是通過zookeeper,而是在所有broker中選擇一個controller。所有Partition的Leader選舉都由controller決定
ontroller會將Leader的改變直接通過RPC的方式(比Zookeeper Queue的方式更高效)通知需為此作出響應的Broker。同時controller也負責增刪Topic以及Replica的重新分配。
controller怎么failover
controller掛了后,大家競選,zookeeper選出其中一個,更新集群狀態(tài)信息
Partition重新分配
什么時候觸發(fā)?
consumer怎么集群消費
以partition為單位,統(tǒng)一個consumergroup,每個consumer負責其中一部分。
當有新的consumer節(jié)點加入、或刪除時,需要重新分配
rebalance
目前,最新版(0.8.2.1)Kafka的Consumer Rebalance的控制策略是由每一個Consumer通過在Zookeeper上注冊Watch完成的。每個Consumer被創(chuàng)建時會觸發(fā)Consumer Group的Rebalance,具體啟動流程如下:
High Level Consumer啟動時將其ID注冊到其Consumer Group下,在Zookeeper上的路徑為/consumers/[consumer group]/ids/[consumer id]
在/consumers/[consumer group]/ids上注冊Watch
在/brokers/ids上注冊Watch
如果Consumer通過Topic Filter創(chuàng)建消息流,則它會同時在/brokers/topics上也創(chuàng)建Watch
強制自己在其Consumer Group內啟動Rebalance流程