這是一篇老帖子了,我是來學習的。原文在這裏:http://jm-blog.aliapp.com/?p=3483。問題是圖片都沒有了。我費了很大功夫才把原文的圖片給找回來。排版以後從新發布一遍。
淘寶的notify是一個很是有特點的消息中間件。它用創新地方式解決了分佈式事務的問題,用相對較低的成本,實現了跨micro service的最終一致性。這種把最終一致性用application queue而不是database replication queue的方式來實現,把IT技術層面的跨業務的事務變成一個業務層面的單據傳遞的概念,很是值得推廣。算法
綜述
消息中間件是一種由消息傳送機制或消息隊列模式組成的最典型的中間件技術。經過消息中間件,應用程序或組件之間能夠進行可靠的異步通信來下降系統之間的耦合度,從而提升整個系統的可擴展性和可用性。sql
Notify是淘寶自主研發的一套消息服務引擎,是支撐雙11最爲核心的系統之一,在淘寶和支付寶的核心交易場景中都有大量使用。消息系統的核心做用就是三點:解耦,異步和並行。下面讓我以一個實際的例子來講明一下解耦異步和並行分別所表明的具體意義吧:數據庫
假設咱們有這麼一個應用場景,爲了完成一個用戶註冊淘寶的操做,可能須要將用戶信息寫入到用戶庫中,而後通知給紅包中心給用戶發新手紅包,而後還須要通知支付寶給用戶準備對應的支付寶帳號,進行合法性驗證,告知sns系統給用戶導入新的用戶等10步操做。
那麼針對這個場景,一個最簡單的設計方法就是串行的執行整個流程,如圖3-1所示:編程
這種方式的最大問題是,隨着後端流程愈來愈多,每步流程都須要額外的耗費不少時間,從而會致使用戶更長的等待延遲。天然的,咱們能夠採用並行的方式來完成業務,可以極大的減小延遲,如圖3-2所示。後端
但並行之後又會有一個新的問題出現了,在用戶註冊這一步,系統並行的發起了4個請求,那麼這四個請求中,若是通知SNS這一步須要的時間很長,好比須要10秒鐘的話,那麼就算是發新手包,準備支付寶帳號,進行合法性驗證這幾個步驟的速度再快,用戶也仍然須要等待10秒之後才能完成用戶註冊過程。由於只有當全部的後續操做所有完成的時候,用戶的註冊過程纔算真正的「完成」了。用戶的信息狀態纔是完整的。而若是這時候發生了更嚴重的事故,好比發新手紅包的全部服務器由於業務邏輯bug致使down機,那麼由於用戶的註冊過程尚未徹底完成,業務流程也就是失敗的了。這樣明顯是不符合實際的須要的,隨着下游步驟的逐漸增多,那麼用戶等待的時間就會愈來愈長,而且更加嚴重的是,隨着下游系統愈來愈多,整個系統出錯的機率也就愈來愈大。緩存
經過業務分析咱們可以得知,用戶的實際的核心流程其實只有一個,就是用戶註冊。然後續的準備支付寶,通知sns等操做雖然必需要完成,但倒是不須要讓用戶等待的。
這種模式有個專業的名詞,就叫最終一致。爲了達到最終一致,咱們引入了MQ系統。業務流程以下:安全
主流程如圖3-3所示:服務器
圖3-3-用戶註冊流程-引入MQ系統-主流程app
異步流程如圖3-4所示:
圖3-4-用戶註冊流程-引入MQ系統-異步流程負載均衡
核心原理
Notify在設計思路上與傳統的MQ有必定的不一樣,他的核心設計理念是
下面就請隨我一塊兒,進入到咱們的消息系統內部來看看他設計的核心原理
爲了消息堆積而設計系統在市面上的大部分MQ產品,大部分的核心場景就是點對點的消息傳輸通道,而後很是激進的使用內存來提高總體的系統性能,這樣作雖然標稱的tps都能達到很高,但這種設計的思路是很難符合大規模分佈式場景的實際須要的。
在實際的分佈式場景中,這樣的系統會存在着較大的應用場景瓶頸,在後端有大量消費者的前提下,消費者出現問題是個很是常見的狀況,而消息系統則必須可以在後端消費不穩定的狀況下,仍然可以保證用戶寫入的正常而且TPS不降,是個很是考驗消息系統能力的實際場景。
也由於如此,在Notify的總體設計中,咱們最優先考慮的就是消息堆積問題,在目前的設計中咱們使用了持久化磁盤的方式,在每次用戶發消息到Notify的時候都將消息先落盤,而後再異步的進行消息投遞,而沒有采用激進的使用內存的方案來加快投遞速度。
這種方式,雖然系統性能在峯值時比目前市面的MQ效率要差一些,可是做爲整個業務邏輯的核心單元,穩定,安全可靠是系統的核心訴求。
無單點,可自由擴展的設計
圖3-5展現了組成Notify整個生態體系的有五個核心的部分。
在雙11的整個準備過程當中,Notify都承載了很是巨大的壓力,由於咱們的核心假定就是後端系統必定會掛,而咱們須要可以承載整個交易高峯內的全部消息都會堆積在數據庫內的實際場景。
在屢次壓測中,咱們的系統表現仍是很是穩定的,以60w/s的寫入量堆積4.5億消息的時候,整個系統表現很是淡定可靠。在真正的大促到來時,咱們的後端系統響應效率好於預期,因此咱們很輕鬆的就知足了用戶全部消息投遞請求,比較好的知足了用戶的實際須要。
METAQ是一款徹底的隊列模型消息中間件,服務器使用Java語言編寫,可在多種軟硬件平臺上部署。客戶端支持Java、C++編程語言,已於2012年3月對外開源,開源地址是:http://metaq.taobao.org/。MetaQ大約經歷了下面3個階段
在2011年1月份發佈了MetaQ 1.0版本,從Apache Kafka衍生而來,在內部主要用於日誌傳輸。
在2012年9月份發佈了MetaQ 2.0版本,解決了分區數受限問題,在數據庫binlog同步方面獲得了普遍的應用。
在2013年7月份發佈了MetaQ 3.0版本,MetaQ開始普遍應用於訂單處理,cache同步、流計算、IM實時消息、binlog同步等領域。MetaQ3.0版本已經開源,參見這裏
綜上,MetaQ借鑑了Kafka的思想,並結合互聯網應用場景對性能的要求,對數據的存儲結構進行了全新設計。在功能層面,增長了更適合大型互聯網特點的功能點。
MetaQ簡介
圖3-6-MetaQ總體結構
如圖3-6所示,MetaQ對外提供的是一個隊列服務,內部實現也是徹底的隊列模型,這裏的隊列是持久化的磁盤隊列,具備很是高的可靠性,而且充分利用了操做系統cache來提升性能。
MetaQ存儲結構
MetaQ的存儲結構是根據阿里大規模互聯網應用需求,徹底從新設計的一套存儲結構,使用這套存儲結構能夠支持上萬的隊列模型,而且能夠支持消息查詢、分佈式事務、定時隊列等功能,如圖3-7所示。
圖3-7-MetaQ存儲體系
MetaQ單機上萬隊列
MetaQ內部大部分功能都靠隊列來驅動,那麼必須支持足夠多的隊列,才能更好的知足業務需求,如圖所示,MetaQ能夠在單機支持上萬隊列,這裏的隊列所有爲持久化磁盤方式,從而對IO性能提出了挑戰。MetaQ是這樣解決的
Message所有寫入到一個獨立的隊列,徹底的順序寫
Message在文件的位置信息寫入到另外的文件,串行方式寫。
經過以上方式,既作到數據可靠,又能夠支持更多的隊列,如圖3-8所示。
圖3-8-MetaQ單機上萬隊列
MetaQ與Notify區別
Notify 交易消息轉 MetaQ 方案改進
MetaQ 交易集羣主要是 Notify 交易消息的一個鏡像,舊有的方案是經過 Notify-Client 訂閱 Notify 交易消息,而後再轉投到 MetaQ 集羣,這個方案的缺點:1. 經過消息訂閱的方式給 Notify 集羣帶來比較大的壓力 2. 一旦 MetaQ 集羣處理不及時會給 Notify 形成消息的堆積,從而帶來連鎖不良效應。新的方案則是從Notify DB直接拉取binlog到MetaQ,它帶來的優點: 1. 解放 NotifyServer 集羣的壓力;2. 經過 binlog 批量處理能夠提高系統的吞吐量。
交易集羣低延遲優化
天貓直播間,旨在經過實時獲取活動當天的交易數據,經過實時流計算的方式,及時、準確的展現各業務數據。它的特色就是數據全而準確、實時性要求較高。而在全鏈路壓測過程當中發現從 Notify Mysql binlog 獲取數據時,出現較大的延遲,最嚴重的延遲高達4h+,這顯然是不合系統需求的。基於這些問題,咱們在 Notify Mysql 端作了不少的優化:
Mysql 數據庫實例擴容,從而提升集羣的總體吞吐量;
對 binlog 的存放位置進行優化,將數據存儲以及 binlog 存儲進行分離,從而發揮 DB 的最大寫性能;
因爲 MySQL 的 binlog 操做存在鎖操做,優化了 MySQL 生成 binlog 的配置,保證了拉 binlog 無延時。
針對不一樣集羣運行參數調優
根據業務的特色,對不一樣集羣的運行參數調優,如批量拉取大小,刷盤方式,數據有效期等等;同時對io調度、虛擬內存等參數進行調優,以提供更爲高效的堆積。
監控與實時告警
任何一個值得信賴的系統,最低限度是須要作到及時發現並處理異常,在第一時間排除故障發生的可能,從而提升產品的可用性。在雙十一活動以前,咱們實現了由 MetaQ 系統內部,根據集羣狀態,各消息的業務數據指標進行監控統計並主動告警,同時還能經過 Diamond 作到動態調整,從而提升監控的及時性以及靈活性。
回顧雙十一活動當日,淘寶消息寫入總量112億,消息投遞總量220億,支付寶消息寫入總量24億,消息投遞總量24億。其中實時直播間集羣消息寫入峯值爲13.1w,消息投遞峯值爲27.8w。
從整體上看,咱們的前期準備仍是比較充分的,MetaQ 各集羣在高峯期表現穩定,全天表現很平穩,個別訂閱組對消息進行重溯,部分消息有少許的堆積,但都沒有對系統形成影響,效果仍是很是好的。75%的交易在聚石塔上完成,實時直播間交易統計延遲在1s左右,加減庫存作到零超賣。
目前分佈式消息中間件產品已經服務於整個集團,支持了阿里集團各個公司的500多個業務應用系統。每日處理海量消息超350億次,保證全部交易數據高可靠,高性能,分佈式事務處理,是中間件團隊最老牌的中間件產品之一。
資料來源:http://club.alibabatech.org/resource_detail.htm?topicId=61
業務操做和消息存儲都在本地事務域進行,不存在跨資源的事務。
提交/回滾消息有可能失敗,系統會處於短暫的不一致狀態
Broker會主動發送Check消息,確認消息是否提交或回滾
最終一致
將分佈式事務分解在兩個本地事務中
客戶端須要付出的代價
實現CheckMessageListener接口
原帖連接:http://jm-blog.aliapp.com/?p=3405&utm_source=tuicool
雙十二大促是淘寶集市的年終促銷活動,活動當天掃描首頁二維碼贈送一注彩票的活動更是讓你們「玩」了一把。面對瞬間的數倍於往常的峯值,如何讓用戶有一個良好的體驗,如何保證系統的穩定運行,讓咱們來揭祕這一切。
概括一下系統須要作到以下幾點:
系統結構圖
大致分爲兩個部分:活動系統,彩票系統,他們之間經過消息驅動。
活動系統裏面只更新一個彩票分配的狀態,數據更新成功就返回給用戶,邏輯足夠簡單能保證RT很是短。彩票系統負責真正的彩票出票和更新用戶狀態等一些耗時操做。
用戶在首頁掃描二維碼發起對活動系統的請求,活動系統更新彩票分配狀態,產生一條消息,當即返回並。彩票系統收到這個消息完成後續出票等一些的業務操做。整個過程是經過MetaQ提供的消息服務驅動完成。活動的時候會有大量的請求涌進活動系統,會產生大量的消息,預估qps達到24w;而且消息不可丟失,確保用戶都能領到一注彩票;活動系統,彩票系統業務複雜度相差較大,處理能力也相差較大,可能會出現大量的堆積;爲了讓用戶有個較好的體驗,消息的消費也須要足夠的及時。綜上對MetaQ有這麼一些挑戰:
下面介紹一下MetaQ如何作到這些的。
MetaQ簡介
METAQ是一款徹底的隊列模型消息中間件,服務器使用Java語言編寫,可在多種軟硬件平臺上部署。客戶端支持Java、C++編程語言,已於2012年3月對外開源,開源地址。MetaQ的設計目標是高吞吐量,高效堆積。徹底的隊列模型還提供了順序消息,消息回溯等一些特性。
基本概念
MetaQ對外提供的是一個隊列服務,內部實現也是徹底的隊列模型,這裏的隊列是持久化的磁盤隊列,具備很是高的可靠性,而且充分利用了操做系統cache來提升性能。這些特性都源於存儲層的設計。
MetaQ存儲結構
MetaQ的存儲結構是根據阿里大規模互聯網應用需求,徹底從新設計的一套存儲結構,使用這套存儲結構能夠支持上萬的隊列模型,而且能夠支持消息查詢、分佈式事務、定時隊列等功能,如圖3所示。
存儲層能夠大體分爲數據文件(CommitLog)和索引文件兩部分。數據文件保存了全部的消息的內容,索引文件保存了消息所在數據文件的偏移量。消息數據不區分Topic,順序的append到CommitLog,索引文件按照Topic-Partition維度組織,不一樣分區的消息append到不一樣索引隊列裏面。
消息寫入
客戶端發送一條消息,數據首先會寫到文件緩存中,同時派發一個寫索引請求;異步的構建消息索引。
消息讀取
客戶端讀取消息,根據索引的位置找到須要讀取的消息的物理位置和消息長度,從CommitLog中讀取數據,經過文件緩存來加速消息的讀取。一般熱數據都在緩存中,無需IO操做;非熱數據,會觸發缺頁中斷,數據從磁盤加載到文件緩存中,直接寫到socket緩衝區,避免數據進入Java堆。
數據刷盤
刷盤後數據最終持久化到磁盤。刷盤方式分爲兩種方式:同步刷盤,數據寫入緩存後當即刷盤,確保數據落盤後返回客戶端,MetaQ在同步刷盤過程當中也作了必定優化避免過多的性能損失;異步刷盤,數據批量定時的刷到磁盤。
數據清理
消息數據按照文件有效期定時作清理。
數據複製
數據可靠性要求很高的應用,可經過數據複製保證數據的可靠。MetaQ提供兩種數據同步的方式:同步雙寫,數寫入到主機後會同時寫到備機,主備都寫成功才返回客戶端成功,主備間數據無延遲,MetaQ有一套本身的主備間高效數據複製方案;異步複製,數據寫到主機後返回客戶端成功,主備間異步同步,主備間存在必定的延遲。
MetaQ單機上萬隊列
MetaQ的大部分功能都是靠隊列來驅動,以文件的方式存儲,經過內存映射對數據進行操做。全部的消息都是順序的寫到數據文件(CommitLog),徹底順序的寫入,避免隨機IO;消息索引按照Topic和Partition的維度區分串行的寫到索引文件。經過這種這種組織方式能夠實現單機上萬隊列,如圖4所示。
數據流圖
消息數據首先寫入到Java堆,而後在寫入到文件緩存,在根據具體的刷盤策略Flush到磁盤;消費消息的時候若是是熱數據則直接從系統緩存寫到socket發到遠端;若是非熱數據則由系統產生缺頁中斷將數據從磁盤加載到系統緩存在寫到socket,數據不進應用程序內存空間。內存的管理,頁面的換入換出都是由OS來管理的。同時消息的拉取也是批量的,一次處理多條數據,儘可能減小往返的時間。
MetaQ性能依賴於系統內存分配,磁盤IO的有效利用,因此咱們也對操做系統內存分配,髒頁會寫策略,以及IO調度算法作了一些調優,讓資源的分配耗時趨於平穩,堆積的時候保持較高的吞吐量。
負載均衡
發送端負載
默認發送端經過輪詢的方式向broker寫消息,如圖6所示;也能夠自行指定消息發到哪裏。
消費端負載
默認是消費集羣機器均分全部的消費隊列。餘下的部分由靠前的消費者消費,如圖7所示。消費端負載均很也能夠定製,如同機房優先等。
另推薦:http://www.infoq.com/cn/news/2014/03/interview-alibaba-wangjingyu?utm_...