大数据技术之 Kafka (第 3 章 Kafka 架构深入 ) Kafka 生产者
3.2.1 分區(qū)策略?
1)分區(qū)的原因?
(1)方便在集群中擴展,每個 Partition 可以通過調整以適應它所在的機器,而一個 topic又可以有多個 Partition 組成,因此整個集群就可以適應任意大小的數(shù)據(jù)了;?
(2)可以提高并發(fā),因為可以以 Partition 為單位讀寫了。?
2)分區(qū)的原則?
我們需要將 producer 發(fā)送的數(shù)據(jù)封裝成一個 ProducerRecord 對象。?
?
(1)指明 partition 的情況下,直接將指明的值直接作為 partiton 值;?
(2)沒有指明 partition 值但有 key 的情況下,將 key 的 hash 值與 topic 的 partition?數(shù)進行取余得到 partition 值;?
(3)既沒有 partition 值又沒有 key 值的情況下,第一次調用時隨機生成一個整數(shù)(后面每次調用在這個整數(shù)上自增),將這個值與 topic 可用的 partition 總數(shù)取余得到 partition?值,也就是常說的 round-robin 算法。?
3.2.2 數(shù)據(jù)可靠性保證?
為保證 producer 發(fā)送的數(shù)據(jù),能可靠的發(fā)送到指定的 topic,topic 的每個 partition 收到
producer 發(fā)送的數(shù)據(jù)后,都需要向 producer 發(fā)送 ack(acknowledgement 確認收到),如果
producer 收到 ack,就會進行下一輪的發(fā)送,否則重新發(fā)送數(shù)據(jù)。?
1)副本數(shù)據(jù)同步策略??
?Kafka 選擇了第二種方案,原因如下:?
1.同樣為了容忍 n 臺節(jié)點的故障,第一種方案需要 2n+1 個副本,而第二種方案只需要 n+1個副本,而 Kafka 的每個分區(qū)都有大量的數(shù)據(jù),第一種方案會造成大量數(shù)據(jù)的冗余。?
2.雖然第二種方案的網絡延遲會比較高,但網絡延遲對 Kafka 的影響較小。?
2)ISR?
?采用第二種方案之后,設想以下情景:leader 收到數(shù)據(jù),所有 follower 都開始同步數(shù)據(jù),但有一個 follower,因為某種故障,遲遲不能與 leader 進行同步,那 leader 就要一直等下去,直到它完成同步,才能發(fā)送 ack。這個問題怎么解決呢???Leader 維護了一個動態(tài)的 in-sync replica set (ISR),意為和 leader 保持同步的 follower 集合。當 ISR 中的 follower 完成數(shù)據(jù)的同步之后,leader 就會給 follower 發(fā)送 ack。如果 follower長時間未 向 leader 同 步 數(shù) 據(jù) , 則 該 follower 將 被 踢 出 ISR , 該 時 間 閾 值 由replica.lag.time.max.ms 參數(shù)設定。Leader 發(fā)生故障之后,就會從 ISR 中選舉新的 leader。?
3)ack 應答機制?
對于某些不太重要的數(shù)據(jù),對數(shù)據(jù)的可靠性要求不是很高,能夠容忍數(shù)據(jù)的少量丟失,所以沒必要等 ISR 中的 follower 全部接收成功。?所以 Kafka 為用戶提供了三種可靠性級別,用戶根據(jù)對可靠性和延遲的要求進行權衡,選擇以下的配置。?
acks 參數(shù)配置:?
acks:?
0:producer 不等待 broker 的 ack,這一操作提供了一個最低的延遲,broker 一接收到還沒有寫入磁盤就已經返回,當 broker 故障時有可能丟失數(shù)據(jù);?
1:producer 等待 broker 的 ack,partition 的 leader 落盤成功后返回 ack,如果在 follower同步成功之前 leader 故障,那么將會丟失數(shù)據(jù);?
acks = 1 數(shù)據(jù)丟失案例
-1(all):producer 等待 broker 的 ack,partition 的 leader 和 follower 全部落盤成功后才返回 ack。但是如果在 follower 同步完成后,broker 發(fā)送 ack 之前,leader 發(fā)生故障,那么會造成數(shù)據(jù)重復。?
acks = -1 數(shù)據(jù)重復案例
4)故障處理細節(jié)?
? ? Log文件中的HW和LEO
LEO:指的是每個副本最大的 offset;?
HW:指的是消費者能見到的最大的 offset,ISR 隊列中最小的 LEO。?
(1)follower 故障?
follower 發(fā)生故障后會被臨時踢出 ISR,待 該 follower 恢復后,follower 會讀取本地磁盤記錄的上次的 HW,并將 log 文件高于 HW 的部分截取掉,從 HW 開始向 leader 進行同步。等該 follower 的 LEO 大于等于該 Partition 的 HW,即 follower 追上 leader 之后,就可以重新加入 ISR 了。?
(2)leader 故障?
leader 發(fā)生故障之后,會從 ISR 中選出一個新的 leader,之后,為保證多個副本之間的數(shù)據(jù)一致性,其余的 follower 會先將各自的 log 文件高于 HW 的部分截掉,然后從新的 leader同步數(shù)據(jù)。?
注意:這只能保證副本之間的數(shù)據(jù)一致性,并不能保證數(shù)據(jù)不丟失或者不重復。?
3.2.3 Exactly Once 語義?
將服務器的 ACK 級別設置為-1,可以保證 Producer 到 Server 之間不會丟失數(shù)據(jù),即 At? Least Once 語義。相對的,將服務器 ACK 級別設置為 0,可以保證生產者每條消息只會被發(fā)送一次,即 At Most Once 語義。?At Least Once 可以保證數(shù)據(jù)不丟失,但是不能保證數(shù)據(jù)不重復;相對的,At Least Once可以保證數(shù)據(jù)不重復,但是不能保證數(shù)據(jù)不丟失。但是,對于一些非常重要的信息,比如說交易數(shù)據(jù),下游數(shù)據(jù)消費者要求數(shù)據(jù)既不重復也不丟失,即 Exactly Once 語義。在 0.11 版本以前的 Kafka,對此是無能為力的,只能保證數(shù)據(jù)不丟失,再在下游消費者對數(shù)據(jù)做全局去重。對于多個下游應用的情況,每個都需要單獨做全局重,這就對性能造成了很大影響。?0.11 版本的 Kafka,引入了一項重大特性:冪等性。所謂的冪等性就是指 Producer 不論向 Server 發(fā)送多少次重復數(shù)據(jù),Server 端都只會持久化一條。冪等性結合 At Least Once 語義,就構成了 Kafka 的 Exactly Once 語義。即:?
At Least Once + 冪等性 = Exactly Once?
要啟用冪等性,只需要將 Producer 的參數(shù)中 enable.idompotence 設置為 true 即可。Kafka的冪等性實現(xiàn)其實就是將原來下游需要做的去重放在了數(shù)據(jù)上游。開啟冪等性的 Producer 在初始化的時候會被分配一個 PID,發(fā)往同一 Partition 的消息會附帶 Sequence Number。而Broker 端會對<PID, Partition, SeqNumber>做緩存,當具有相同主鍵的消息提交時,Broker 只會持久化一條。?但是 PID 重啟就會變化,同時不同的 Partition 也具有不同主鍵,所以冪等性無法保證跨分區(qū)跨會話的 Exactly Once。?
總結一句話:這個冪等性只能解決單次會話數(shù)據(jù)不重復,根據(jù)這個PID?Partition??SeqNumber三個條件確定是不是同一條數(shù)據(jù),來保證數(shù)據(jù)不重復
總結
以上是生活随笔為你收集整理的大数据技术之 Kafka (第 3 章 Kafka 架构深入 ) Kafka 生产者的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2017-9-17pat甲级 C
- 下一篇: zcmu-1176