1. 程式人生 > >由內搜推送思考Kafka 的原理

由內搜推送思考Kafka 的原理

默認 以及 自己 情況 雲服務 都是 推送 等等 中間

  剛入公司的兩周多,對CDX項目有了進一步的認識和理解,在這基礎上,也開始了解部門內部甚至公司提供的一些中間服務。CDX項目中涉及到的二方服務和三方服務很多,從之前寫過的SSO,Auth,到三方圖庫的各個接口,以及圖片存儲的雲服務Gift,以及今天說到的內搜系統。

  由於內搜推送信息是到一個kafka隊列中消費,雖然作為業務開發不涉及消息中間件的建設,但還是希望能了解內部選型的一些思想,一點一點學習和理解部門的各個服務。這裏我也參加了內部的一些分享,想說說自己對Kafka的初識吧。

  

首先是Kafka的官方介紹和原理:

  Apache Kafka是分布式發布-訂閱消息系統。它最初由LinkedIn公司開發,之後成為Apache項目的一部分。Kafka是一種快速、可擴展的、設計內在就是分布式的,分區的和可復制的提交日誌服務。

組成:

  • 話題(Topic):是特定類型的消息分類。

  • 生產者(Producer):是能夠發布消息到話題的任何對象,在內搜這個模型中,我們各個業務系統就是消息的生產者。

  • 服務代理(Broker):已發布的消息保存在一組服務器中,它們被稱為代理(Broker)或Kafka集群。

  • 消費者(Consumer):可以訂閱一個或多個話題,並從Broker,pull數據,從而消費這些已發布的消息,Kafka都是pull的方式,並且涉及到消費的機制,等一下說。

  • (Group): 包含多個消費者,但是默認情況下,在一個組內,同一個消息只會被一個Consumer消費。當然內搜的訂閱者應該只存在一個組中。

消息推送方式:Push,Pull

  這裏有一副對比圖很好的說明了兩種情況的優劣,Kafka是使用pull的方式。

技術分享

消費機制三種:

At most once—consumer先記錄log再消費,這樣消息可能會丟失造成沒有消費,但不會重復消費。

At least once—consumer先消費了再記錄log,這樣保證消息一定被消費,但有可能重復。(聽了EP的分享好像目前使用的是這種)

Exactly once—確保消費並且確保只消費一次,這種是最理想的狀態(同時處理消息並把result和log同時寫入)。

存儲策略:

1)kafka以topic來進行消息管理,每個topic包含多個partition,每個partition對應一個邏輯log,有多個segment組成。

2)每個segment中存儲多條消息,消息id由其邏輯位置決定,即從消息id可直接定位到消息的存儲位置,避免id到位置的額外映射。

3)每個part在內存中對應一個index,記錄每個segment中的第一條消息偏移。

4)發布者發到某個topic的消息會被均勻的分布到多個partition上(或根據用戶指定的路由規則進行分布),broker收到發布消息往對應partition的最後一個segment上添加該消息,當某個segment上的消息條數達到配置值或消息發布時間超過閾值時,segment上的消息會被flush到磁盤,只有flush到磁盤上的消息訂閱者才能訂閱到,segment達到一定的大小後將不會再往該segment寫數據,broker會創建新的segment。

上面這四條是標準的一個敘述,我想針對其中兩點進行說明:

1. partition路由分配規則:一種是輪詢方式,這樣會保證消息分部均勻,但是沒有邏輯上的區分;另外一種是指定路由規則(比如hash方法),這樣可以進行一定的映射,如將統一用戶的分到一片等等。

2.持久化方式:log分為.index和.log文件,文件都會有一個offset偏移量,記得聽人分享過,使用了linux內核sendFile函數直接進行隨機寫的操作,提高了效率。

  另外,關於Kafka與ZK的協調配置還需要我去學習(不過好像kafka的新版本offset是保存在自己服務器上的,不借助zk來保存)。

  來了公司發現很多東西都停留理論層面,需要學習和實踐的還有很多,希望自己能不斷進步吧。

由內搜推送思考Kafka 的原理