Foursquare 長(zhǎng)達(dá) 11 小時(shí)的宕機(jī)
本文轉(zhuǎn)載自著名博客DBA Notes,F(xiàn)oursquare是目前最流行的LBS應(yīng)用,就像在MongoDB官網(wǎng)上看到的一樣,其底層應(yīng)用了MongoDB進(jìn)行一些重要數(shù)據(jù)的存儲(chǔ)。而最近的長(zhǎng)達(dá)11小時(shí)宕機(jī),正是由于MongoDB的問(wèn)題導(dǎo)致的。
原文鏈接:http://www.dbanotes.net/arch/foursquare_outage.html
前幾天 Foursquare 經(jīng)歷了長(zhǎng)達(dá) 11 個(gè)小時(shí)的宕機(jī),沒(méi)錯(cuò),11 個(gè)小時(shí)。網(wǎng)站官方的解釋是 Shard 負(fù)載不均勻造成后續(xù)的連鎖反應(yīng)。很多人都知道 Foursquare 在線的 DB 是 MongoDB,今天又看到 10gen (MongoDB的開(kāi)發(fā)與支持團(tuán)隊(duì))的 Eliot Horowitz 在得到 Foursquare 許可后,通過(guò)郵件組詳細(xì)介紹了宕機(jī)的過(guò)程:Foursquare outage post mortem,不用說(shuō),也有為 MongoDB 辟謠的意味在里面。
讀罷 10gen 團(tuán)隊(duì)的介紹(或者說(shuō)解釋)之后,發(fā)現(xiàn)這是一個(gè)很好的研究樣本。值得分享。
為了提高響應(yīng)速度,F(xiàn)oursquare 使用 MongoDB 存儲(chǔ) Check-in 的數(shù)據(jù)已經(jīng)有一段時(shí)間了。這部分?jǐn)?shù)據(jù)的數(shù)據(jù)庫(kù)起初跑在一個(gè) 66GB 內(nèi)存的 Amazon EC2 單實(shí)例上(全部在內(nèi)存里),兩個(gè)月前,出于對(duì)容量增長(zhǎng)的考慮,遷移到兩臺(tái) Shard 集群上。每個(gè) Shard 機(jī)器都是 66GB 內(nèi)存,為了冗余,每個(gè) Shard 都有復(fù)制到 Slave 實(shí)例。遷移的目標(biāo)是所有的 Check-in 數(shù)據(jù)都保存在內(nèi)存中。數(shù)據(jù)根據(jù) ID 分成 200 個(gè) Shard 分片,兩臺(tái)機(jī)器各占一般,也就說(shuō)聯(lián)機(jī)數(shù)據(jù)在每臺(tái)機(jī)器上各使用 33GB 的內(nèi)存。兩個(gè)月相安無(wú)事。
問(wèn)題來(lái)了,因?yàn)?Shard 算法導(dǎo)致的數(shù)據(jù)分散不均衡,其中一臺(tái)(Shard0)數(shù)據(jù)增長(zhǎng)到 67GB(另外一臺(tái) 50GB),超過(guò)了 66GB 的限制,讀寫(xiě)部分分散到磁盤上,性能急劇下降。從而,網(wǎng)站宕機(jī)。
首先嘗試增加第三臺(tái) Shard 機(jī)器,上線后開(kāi)始遷移,讀取從三臺(tái)進(jìn)行,Shard0 的數(shù)據(jù)遷移到 5% 的時(shí)候,但是寫(xiě)操作還是讓 Shard0 宕機(jī)了。這個(gè)時(shí)候發(fā)現(xiàn)Shard0 存在數(shù)據(jù)碎片(data fragmentation),即使數(shù)據(jù)遷移走,還是會(huì)占用原來(lái)的內(nèi)存。每個(gè)Check-in 文檔大約占用 300 字節(jié),而 MongoDB 是 4KB 的頁(yè)(Page),也就說(shuō)十幾個(gè)文檔會(huì)填滿一個(gè)頁(yè),而遷移 5% 反而造成了頁(yè)更加稀疏,并不是將頁(yè)全部刪除。
這個(gè)時(shí)候已經(jīng)到了第二天,隨著網(wǎng)站全面宕機(jī),技術(shù)團(tuán)隊(duì)開(kāi)始用 MongoDB 的 repairDatabase() 功能來(lái)對(duì)數(shù)據(jù)庫(kù)進(jìn)行壓縮,因?yàn)閿?shù)據(jù)庫(kù)太大和 EBS 慢,也因?yàn)?repairDatabase() 不能充分利用多核CPU 的能力,這個(gè)過(guò)程耗費(fèi)了 4 個(gè)小時(shí)。之后這 5% 的內(nèi)存空間終于釋放出來(lái),系統(tǒng)重新上線。
隨著 Shard0 修復(fù),第三臺(tái)成功上線,進(jìn)而添加了更多的 Shard 服務(wù)器,現(xiàn)在數(shù)據(jù)已經(jīng)更加的均衡,通過(guò)在Slave上運(yùn)行 repairDatabase(),然后將其切換到 Master ,每臺(tái) Shard 內(nèi)存占用縮減到 20GB左右。整個(gè)故障時(shí)間已經(jīng)延續(xù)了 11 小時(shí)之多。
產(chǎn)生問(wèn)題的主要原因就是系統(tǒng)過(guò)載,前面介紹每臺(tái) Shard 承載原來(lái) 50% 的壓力,到了問(wèn)題發(fā)生的時(shí)候,單臺(tái) Shard 的負(fù)載已經(jīng)超過(guò) Shard 之前的系統(tǒng)負(fù)載,這時(shí)候已經(jīng)積重難返了,在容量的臨界點(diǎn)增加新系統(tǒng)資源,必然導(dǎo)致更多的停機(jī)時(shí)間。暴露了 Foursquare 團(tuán)隊(duì)在容量規(guī)劃方面的不足之處,或許也因?yàn)闃I(yè)務(wù)增長(zhǎng)太快了吧。另外,內(nèi)存碎片化的問(wèn)題在沒(méi)有宕機(jī)之前,技術(shù)團(tuán)隊(duì)?wèi)?yīng)該沒(méi)考慮過(guò)這個(gè)問(wèn)題,如果文檔的大小超過(guò) 4K,碎片化問(wèn)題就不嚴(yán)重了,這是特定應(yīng)用場(chǎng)景造成的特定問(wèn)題。10Gen 現(xiàn)在已經(jīng)著手研究如何進(jìn)在線壓縮(online compaction)。再次,Shard 鍵值的順序和插入順序是不同的,這造成了遷移數(shù)據(jù)的時(shí)候 Chunk 的遷移不是連續(xù)的。
這個(gè)過(guò)程給我們的啟示是:最近 NoSQL 已經(jīng)成為一個(gè)熱詞,類似 MongoDB 這樣的新事物當(dāng)然值得嘗試,但是不能冒進(jìn),因?yàn)轳{馭起來(lái)并非易事。僅僅能夠使用是不夠的,系統(tǒng)沒(méi)出問(wèn)題一切都好,一旦出了異常,有足夠的技術(shù)力量(設(shè)想一下 Foursquare 得不到 10gen 團(tuán)隊(duì)的支持會(huì)如何?) 支持么?在極端情況下如何控制? 如果回答不了這個(gè)問(wèn)題,那么還應(yīng)該暫緩。最好的辦法就是…”等待”。
給我的另一個(gè)感慨是 Amazon 在云計(jì)算領(lǐng)域已經(jīng)真的成為一個(gè)贏家,而且越來(lái)越得到 Web 2.0 Startup的信賴。前面說(shuō)的 66GB 內(nèi)存,應(yīng)該指的是EC2 的 “High-Memory Double Extra Large Instance”,可提供的最大內(nèi)存是 68.4 GB 。CPU 和內(nèi)存能力都是可以接受的,存儲(chǔ)方面的性能似乎還有點(diǎn)不足,也就是其中的 EBS ,指的是 Amazon Elastic Block storage。
|