ISR 是什么
ISR 的全稱叫做: In-Sync Replicas (同步副本集), 可以理解為和 leader 保持同步的所有副本的集合。ISR 動態維護了一個和 leader 副本保持同步副本集合,ISR 中的副本全部都和 leader 的數據保持同步。
設一個場景,有6個分區集合,分別為 [0,1,2,3,4,5],其中 leader-replica 是 0
其中 [1,2,3] 作為 follower 和 leader 的數據保持同步,而 [4,5] 未能和 leader 保持同步,那么此時,ISR=[0,1,2,3],OSR=[4,5]
如果此時副本 4 追上了 leader-replica,也就是和 leader 保持到了同步,那么此時,ISR=[0,1,2,3,4],OSR=[5]
ISR 的作用
我們知道了與 leader 保持同步的副本集后,可以做到哪些事情?
- 當我們生產消息的時候,到底要寫入多少副本才能算成功呢?
- 當 leader 掛了之后,我們應該選擇哪個 follower 來成為新的 leader 呢?
通過 ISR 就可以知曉了哪些 follower 與 leader 保持著同步,在寫入消息的時候,設置寫入處于 ISR 中所有的副本才算成功,在進行 leader 切換的時候,就可以從 ISR 中選擇對應的 follower 成為新的 leader。
ISR 的作用是通過副本機制實現消息高可靠,服務高可用時,不可缺少的一環;這也是為什么講到副本不得不提到 ISR 的原因。
總結
- ISR 機制通過副本冗余機制,提供了 kafka 消息的高可靠性。
- ISR 機制可以做到故障轉移,保障服務的可用性。
- ISR 平衡了主從架構下,復制方案的選擇(同步 / 異步 / 少數服從多數),讓使用者根據參數自行選擇。
為什么要設計 ISR 機制
在一些中間件中,都有副本的概念,不同場景下寫入數據時,要求寫入副本的個數也不盡相同。例如 zk 中要求寫入的節點個數大于一半才算成功,或者有些要求高可靠性的場景,規定寫入所有副本才能算成功。
而 kafka 的 ISR 可以允許生產消息時,根據自己的業務場景自行配置 ACK 確認機制達到想要的效果:
- acks=0:生產者發了就算完了,后續成不成功我都不管,這種設置下消息的高可靠性幾乎沒有保障,但是卻有著極大的吞吐量
- acks=1:消息寫入主節點就算成功,這種設置,可以保障一定的高可靠性,也具有不錯的吞吐量
- acks=-1或all:消息必須寫入 ISR 中所有的副本才算成功,這種設置下,就能提供較高的高可靠性,但是吞吐量就相對較低
ISR 雖然是動態伸縮的,可能會出現 follower 全部都掛了的情況,如果 ISR 中只剩下 leader,那么此時設置 acks=all 就等價于 acks=1 了。這樣就會對高可靠性要求的場景產生危險。
kafka 提供了 min.insync.replicas 參數配置,這個參數可以配置最少 ISR 中需要多少個副本,才能繼續提供寫服務。如果設置為 2,一旦 ISR 中的個數小于 2,那么就不再提供寫服務,犧牲一定的可用性,來保障這種高可靠的場景需求。
總結
ISR 機制的存在是 kafka 為了平衡可靠性和可用性,不指定提供高可靠或者高可用的服務,而是將決定權交給了使用者,讓使用者通過參數來控制,到底要實現什么程度的高可靠與高可用。