天天看點

【面經】面試官問我:如果讓你設計一個高并發的消息中間件,你會怎麼做?

消息中間件涉及的知識點

要想設計一個具有高并發的消息中間件,那麼首先就要了解下消息中間件涉及哪些具體的知識點。通常,設計一個良好的消息中間件需要了解的知識點如下:

  • 生産者消費者模型。
  • 支援分布式架構。
  • 資料的高可用。
  • 消息資料不丢失。

接下來,我們就針對消息中間件來分别談談這些技術點。

生産者消費者模型

相信很多小夥伴對于生産者和消費者模型都比較了解了,簡單的說:就是消息中間件能夠使其他應用來生産消息,也能夠使其他應用來消費相應的消息。

對于生産者和消費者模型,我們需要考慮的問題點就比較多了。接下來,我就一步步來引導大家進行思考。

首先,我們來思考這樣一個問題:如果生産者生産了消息,那麼消息中間件應該怎樣存儲相應的資料呢?存儲在記憶體? 存儲在磁盤?還是同時存儲在記憶體和磁盤中呢?

如果是将消息資料同時存儲在記憶體和磁盤中,我們又該如何處理這些資料呢?是生産者将消息投遞到消息中間件之後,我們就立刻将資料寫入磁盤?還是說資料先駐留到記憶體,然後每隔一段時間刷到磁盤上?如果是每隔一段時間刷到磁盤上,那我們又要考慮磁盤檔案的切分問題,也就是說,需要将分成多少個磁盤檔案?(總不能把所有的資料放到一個磁盤檔案中吧)。如果是需要切分成多個磁盤檔案,那切分的規則又是什麼呢?

上面這些問題都是我們在設計一個消息中間件時需要考慮的問題。然而,這還隻是一小部分問題。如果想在面試時脫穎而出,那就還需要繼續往下看,還有一些重要的問題點需要注意。

如果檔案按照一定的規則切分到多個磁盤檔案中了,那是不是還需要一些對于中繼資料的管理來辨別資料的具體消息(就像是Hadoop中的NameNode節點中存儲着DataNode的中繼資料資訊,NameNode節點通過這些中繼資料資訊就能夠更好的管理DataNode節點)?這些中繼資料可以包括:消息資料的偏移量、也可以是消息資料的唯一ID。

考慮完資料的存儲問題,我們還需要考慮的是:消息中間件是如何将資料投遞到對應的消費者的?

在設計生産者和消費者時,還一個很重要的問題需要我們考慮:我們在設計消息中間件時,采用的消費模式是什麼?會不會将資料均勻的配置設定給消費者?還是會通過一些其他的規則将資料投遞到消費者?

支援分布式架構

如果你設計的消息中間件,每天會承載TB級别的資料高并發和高吞吐量的寫入操作。這裡,我們就需要考慮将消息中間件設計成分布式架構。

在設計分布式架構時,我們還需要考慮将要存儲的比較大的資料,做分片存儲,資料分片等操作。

除了這些,我們還需要考慮另外一個核心問題:對消息中間件,需要支援自動擴容操作。

是否支援資料分片?如何實作資料分片的擴容和自動資料負載均衡遷移?

資料的高可用

一般網際網路應用的高可用,是通過本地堆記憶體,和一份資料在不同的伺服器上都搞一個副本。此時,任何一個存儲節點當機。

在現實中,資料的高可用,需要一些理論的支援。

消息資料不丢失

此時,我們就需要提供手動ACK的機制,也就是說:當消費者真正消費消息完畢後,向消息中間件傳回“ 處理完成” 的辨別。

但是,細化的話,這裡,我們就需要兩套ACK機制:

  • 一種ACK對應的是生産端。如果一直沒有接收到ACK消息,則需要通過生産者重新發送消息
  • 另一種ACK對應的是消費端。一旦消費處理成功一條消息了,必須傳回一個ack給消息中間件,然後消息中間件才能删除這條消息。否則一旦消費者當機,就必須重發這條消息給其他的消費者執行個體,保證消息一定會被處理成功。

今天,我們沒有聊具體的業務點,而是從整體上考慮:如果實作一個消息中間件,需要我們注意的各項知識點和專業技能!好了!

繼續閱讀