kafka 串讲:架构模型、角色功能梳理
kafka 串講:架構模型、角色功能梳理
kafka 的 what why how,先有一個粗略宏觀的理解
rabbitmq、各種 mq 的技術選型、橫向對比
首先,kafka 是一個消息中間件。我們從一個本質的點聊起,我們有一個系統 service,如果這兩個服務之間直接調用的話,它們之間會相互約束,耦合性比較強,而且未來的拓展不好,一方有調整的時候,另一方會受到影響。
這時候我們加入一個消息系統,一方發送消息,另一方去取,就起到了我們所謂的消峰填谷以及解耦的效果。
現在我們聊的是消息的中間件,其實中間件包括很多,包括有存儲的,有緩存的,他們的作用都有一個相通性,就是他們最終都會與分布式掛鉤。
那說道中間件,會有幾個詞匯的需求:可靠的、可擴展的、高性能的等等,關于分布式對中間件大概有這么幾個要求。在 redis 中,我們會有 AKF 微服務劃分原則,那 kafka 和 AKF 劃分有什么聯系呢,等待會兒我講完看一下效果吧,如果講的不明白的話,后面排一個分布式系統劃分分享。
我們先舉一個簡單的例子,然后去挑這個例子的毛病,把毛病挑出來之后,我們就知道為什么 kafka 會被設計成現在這個樣子了。
現在我們假設,整家公司只有一個系統。所有消息被調用的時候,都被打到同一個單機隊列中,這個時候確實能夠達到我們常說的削峰填谷的作用,但是隨著我們業務的增大,并發量的隨之增大,這個單機的隊列它會有單點問題,會有性能問題。這也是我們在使用很多技術的時候通常會遇到的兩個問題。這是兩個獨立的問題,這兩個問題我們可以獨立的解決,解決方案也可以獨立的應用,但很多時候我們會把他們整合應用。所以繼續往下講你們應該能找到這種感覺。
性能問題
我們要先解決性能問題,因為 kafka 的關鍵詞里面,先是 topic,然后是 partition,再是副本。
性能問題是怎么解決的?以 AKF 的角度來說,它有三個維度:
x 軸解決的是單點問題,是高可用的,y 軸解決的是業務劃分的,z 軸解決的是分片、分治的。先把這個圖放在這里,然后我們再細講。
那我們如何把這三個軸對應到 kafka 的特性上,首先 y 軸將消息按業務劃分,比如在一個電商系統,可以把訂單拆出一個隊列、用戶行為拆成一個隊列、廣告推薦拆成一個隊列。這樣劃分之后,不同業務的生產和消費都不會相互影響,業務之間的隔離性會比較好。而且按照業務劃分之后,不同的業務數據會被部署在整個 kafka 集群中的不同的節點上,每個節點只關注自己的一套東西的話,資源的利用率會高。因此如果將我們上面說道的單機版的這個消息隊列從邏輯上進行拆分的話,第一個拆出來的就是 topic,我們說的 y 軸其實就是 topic。你可以把 topic 就理解成是業務。
但是如果這么劃分的話,假設說我的用戶行為日志存在某個 topic 中,如果我的日志量太大了,如果全部存放在一個節點(中的一個進程)上的話,工作起來 IO 上會受限,而且單看自己它會有一個性能瓶頸。那怎么解決這個性能瓶頸,當我們已經進行過業務拆分之后,怎么再進行更細粒度的拆分,這時候就是我們的 partition。在一個 topic 下,會有多個 partition。
我們這個講法可能會比較墨跡,是因為比較注重思路的推導這個過程,其實很多地方都有 AKF 這個思想,不僅是 kafka,還有 redis 也會涉及到 AKF,那在我們出去面試的時候,如果抓住這個內容的話,分布式和微服務都可以在這里面去聊。
那另外一個就是 partition,分區的概念。這個分區其實作用的就是我們的 z 軸,因為在業務使用的時候,假如說我們希望用 kafka 去存 用戶行為日志,我們會期望把這些日志由一個變成多個,由多臺機器,更大的能力去承載它。一般我們聊到 z 軸的時候,z 軸其實是對 y 軸一個細分,那細分的時候,可以使用的手段可以是 range,hash,或者是做一個映射,拆解的方案會有很多。
還是拿剛才推薦系統中收集用戶行為的例子來說,我要把所有的用戶行為日志打散到多臺里面去,這個多臺應該怎么打才合適?也就是說,當使用的數據從一個線性的隊列散落到多個地方的時候,如何去保證前面的生產最后消費的數據的一致性?就是說,在以前沒有分區的概念的時候,數據長什么樣,我只需要按順序一個一個推進來,這邊取到的就是原有的樣子。一旦一變多,會帶來一致性的問題,那我們的生產方和消費方,如何組建這個先后關系,保證它仍然是有序的?
在 AKF z 軸劃分的時候,如果你學過大數據,也可以引入分治這個概念了,大數據必然會有分治,也就是 map 階段,map by key,也會有聚集 reduce,就是相同的數據要打到一起去,然后收集起來進行后續的處理,其實 kafka 中依然是這個原理。在生產用戶行為日志的時候,有 展現,點擊,收藏 三種不同的用戶行為,只要他們各自有自己的順序。也就是在分而治之的時候,將無關的打開,分散出去,將有關的放在一起,一定要保證順序。
所以這時候,z 軸應該如何實現?要規劃好整個數據路由,將無關的數據放在不同的 partition 中,這樣我們就達到了一個后續無關數據的并行度。
無關的數據是可以并行計算的,如果有關的話,我們會需要在他們之間加上一個分布式鎖,或者通過 log id 等方式去保證他們的順序性,這樣會變得很慢,所謂的并發最終還會退化為串行。所以我們希望將并行最大化,將無關的數據分散到不同的分區里,以追求并發、并行處理,有關聯的數據,一定要按照原有順序發送到同一個分區里。
topic 是邏輯概念,partition 是最后物理的對應,一個 topic 下面有 partition 1,2,3…
然后我們看到還有一個 x 軸,這個 x 軸什么意思,x 軸做的是可靠性的保證。現在通過 y 軸和 z 軸,將這些消息打散到不同的分區了,實現的是計算的并行,提升了性能,但是這個時候,如果某一個分區消失了,掛掉了,這時候你堆積的消息會丟失,這時候需要我們給它做副本。在做副本的時候,我們橫向走下這個過程。
無論 redis 也好,kafka 也好, 你像純內存的 redis,它必須有一個持久化,他會認為磁盤是自己可靠性的來源,如果不在單機的維度,而是看集群的維度的話,單物理節點可能也會丟失,會掛,這時候為了解決節點的問題,我們還需要網絡的維度提供可靠性,那 redis 就會有單機的持久化、網絡的持久化,基于網絡的主從復制集群。那他的主從復制集群就來自于它的 x 軸。其實 kafka 也一樣,kafka 分區的數據會持久化到磁盤當中去,而且利用順序讀寫這種高性能的磁盤 IO,x軸一般是出主機的、異地的備份,因為如果將全量備份放在同一個節點上意義不大。
x 軸的拆分會比較容易出現數據一致性、數據的同步問題,會有一系列分布式集群下的解決方案,比如 mysql 會有讀寫分離的策略,為了解決一致性和復雜性上的痛點,kafka 做了一個決策就是只允許在主片上增刪改,從片只允許讀。
**由單機到分布式,或者說由傳統到中間件,基本都是按照這個思路來設計的。**我們用到的各種分布式中間件的實現,和 AKF 這一側是有必然的這么一個參照和關聯的關系的。
這些都是方法論,來推導出 kafka 中有 topic,partition,有序性的這些概念,然后我們再把有序性做一個延伸:下面我們來講 offset
我們知道,分區內部是有序的(純隊列),分區外部是無序的,那這個順序是怎么得到的?我們用 partition1 做一個簡單的描述。假設我們的上游發來三個消息,msg 1,2,3,這三個消息會按照接收的順序存在 kafka 隊列中。當消費者來消費的時候,每個消費者會維護一個自己消費到的位置,也就是 offset。
The offset is a simple integer number that is used by Kafka to maintain the current position of a consumer. That’s it. The current offset is a pointer to the last record that Kafka has already sent to a consumer in the most recent poll. So, the consumer doesn’t get the same record twice because of the current offset.
Offsets in Kafka are stored as messages in a separate topic named ‘__consumer_offsets’ . Each consumer commits a message into the topic at periodic intervals.
上面的例子中,只有一個 topic 和這個 topic 下的兩個 partition,實際上企業中會有很多個 topic,每個業務下都會有很多 topic,每個 topic 下會有幾百個 partition,如何去管理這些分布式的東西的一致性?在經驗中,主從是管理成本最低的,它的協調成本會比主主要低,這樣會引發一系列分布式協調的問題,包括選主,包括如何保證數據的一致性,常用的解決方案有 zookeeper,或者 etcd。那我們的 kafka 會依賴 zookeeper,主要是依賴它的分布式協調,不過要注意千萬不要把 zookeeper 當做是分布式存儲來使用。
kafka 對 zookeeper 的依賴
kafka 的 broker 依賴于 zookeeper
- 使用 zk 存儲 broker 的元數據,將 broker 當做是一個進程。
- 使用到 zk 的選舉機制
總結
以上是生活随笔為你收集整理的kafka 串讲:架构模型、角色功能梳理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 没有 root 权限如何使用 pip?H
- 下一篇: leetcode 415. 字符串相加(