分布式队列
轉載請注明出處:http://jameswxx.iteye.com/blog/2034111
??
本來只是想看下metaq的文檔,結果發現好亂,現在metaq其實有兩個大分支了,一個是莊曉丹維護的已開源的,另外一個是淘寶內部的,本質結構原理沒太大區別,只不過開源的已經去掉了對淘系相關的依賴。然后淘系的metaq已經到3.*版本了,但是文檔比較亂,深入到細節時,發現好亂,一個點有好幾種說法,火大,干脆自己看metaq的源碼,有點意思,做個筆記記錄下,怕我以后忘記了。有少量的章節和圖片從內網拿來的,大部分是自己寫的,記錄下幾個主要的點。
?
一:metaq是什么
metaq是一個分布式消息中間件,消息中間件是典型的生產者-消費者模型,核心作用是解耦,生產者和消費者彼此沒有直接依賴,同步化解成了異步。metaq并沒有遵循jms規范,jms規范體現在系統層面和api層面。
?
消費模型
例如jms定義了兩種消息傳遞方式:
?1 基于隊列的點對點消費模型
?2 基于發布/訂閱的消費模型
?Metaq只有發布訂閱的消費方式。
消息類型
JMS定義的消息類型有TextMessage、MapMessage、BytesMessage、StreamMessage、ObjectMessage。Metaq只有一種類型:Message。
消息持久性
JMS定義兩種持久性類型:
?PERSISTENT?? 指示JMS provider持久保存消息,以保證消息不會因為JMS provider的失敗而丟失。?
NON_PERSISTENT?不要求JMS provider持久保存消息。
?Metaq的消息都是持久性的
API
JMS定義了消息中間件的生產端api和消費端api,這些api都是約定的接口,都都被metaq無視了。
?
二:一些概念
消息生產者負責產生消息并發送消息到meta服務器
消息消費者
負責消息的消費,meta采用pull模型,由消費者主動從meta服務器拉取數據并解析成消息并消費
Topic
消息的主題,由用戶定義并在服務端配置。producer發送消息到某個topic下,consumer從某個topic下消費消息
分區
同一個topic下面還分為多個分區,如meta-test這個topic我們可以分為10個分區,分別有兩臺服務器提供,那么可能每臺服務器提供5個分 區,假設服務器分別為0和1,則所有分區為0-0、0-1、0-2、0-3、0-4、1-0、1-1、1-2、1-3、1-4
Message
消息,負載用戶數據并在生產者、服務端和消費者之間傳輸
Broker
就是meta的服務端或者說服務器,在消息中間件中也通常稱為broker。
消費者分組(Group)
消費者可以是多個消費者共同消費一個topic下的消息,每個消費者消費部分消息。這些消費者就組成一個分組,擁有同一個分組名稱,通常也稱為消費者集群
Offset
消息在broker上的每個分區都是組織成一個文件列表,消費者拉取數據需要知道數據在文件中的偏移量,這個偏移量就是所謂offset。Offset是絕對偏移量,服務器會將offset轉化為具體文件的相對偏移量
?
?
?
三:總體結構圖
?
?
?
?
?
四:消息存儲
消息中間件中消息堆積是很常見,這要求broker具有消息存儲的能力,消息存儲結構決定了消息的讀寫性能,對整體性能有很大影響,metaq是分布式的,多個borker可以為一個topic提供服務,一個topic下的消息分散存儲在多個broker,它們是多對多關系。如下圖
為什么要用分布式的消息隊列:
1. 消息的堆積需要分布存儲在內存或者硬盤
2. 異步解耦:
舉個例子:http://simple-is-better.com/news/466
?比如SNS網站的“新鮮事兒”系統,我發帖之后,會給所有關注我的人推送一條通知。乍一看沒什么難的,發帖之后找出關注我的人, 然后生成相應的消息記錄就行了。但問題是,100個人關注我,就要執行100條INSERT查詢,更要命的是,Web服務器是同步的, 這100條查詢執行完成之前,用戶是看不到結果的。
怎么辦呢,這時就輪到消息隊列上場了。發帖之后只需給隊列發送一條消息, 告訴隊列“我發帖子了”,然后把發帖的結果返回給用戶。 這時另一個叫做worker的進程會取出這條消息并執行那100條INSERT查詢。這樣,推送通知的操作在后臺異步執行, 用戶就能立即看到發帖結果。更精彩的是,可以運行多個worker實現分布式,多繁重的任務都不在話下了。
總結
- 上一篇: ssh能够连接而sftp不能连接的解决方
- 下一篇: open pwrite