由內搜推送思考Kafka 的原理

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

  因爲內搜推送信息是到一個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來保存)。

  來了公司發現不少東西都停留理論層面,須要學習和實踐的還有不少,但願本身能不斷進步吧。

相關文章
相關標籤/搜索