Facebook技術(shù)總監(jiān):如何管理10億用戶的數(shù)據(jù)?
2013年01月28日 16:47
騰訊科技訊 (迭影) 北京時(shí)間1月28日消息,F(xiàn)acebook用戶數(shù)量,已經(jīng)突破10億大關(guān)。Facebook在發(fā)展期間,所實(shí)現(xiàn)的技術(shù)成就,成為了IT行業(yè)工程師關(guān)注的話題。究竟Facebook取得了哪些技術(shù)成就呢?Facebook前工程部門(mén)總監(jiān),在問(wèn)答網(wǎng)站Quora上,對(duì)這一問(wèn)題作出回答。無(wú)論對(duì)于IT行業(yè)的投資者還是使用者,這些回答都有著指導(dǎo)意義。
以下是文章全文:
我在Facebook的基礎(chǔ)架構(gòu)軟件開(kāi)發(fā)團(tuán)隊(duì),工作了5年,并且參與了多數(shù)項(xiàng)目的開(kāi)發(fā)。我認(rèn)為在Facebook時(shí),最偉大的成就是Memcache/MySQL集群。一年前,我離開(kāi)Facebook的時(shí)候,這個(gè)集群中已經(jīng)擁有超過(guò)1萬(wàn)億對(duì)象(沒(méi)錯(cuò)是萬(wàn)億),每秒請(qǐng)求數(shù)量超過(guò)10億,處理時(shí)間通常不超過(guò)1毫秒。這一集群,在多個(gè)數(shù)據(jù)中心之間,保持了良好的一致性,并且很少出現(xiàn)停機(jī)的情況。
實(shí)際上,我們?nèi)〉玫恼嬲删?,與Memcache和MySQL并沒(méi)有多大的關(guān)系——隨著時(shí)間的推移,這些都將會(huì)被新的“技術(shù)”所取代,但是這里真正重要的技術(shù),是讓數(shù)量如此龐大的機(jī)器,快速、可靠的協(xié)同工作。這并不同于通常意義上,人們?cè)谠儐?wèn)“你用的是什么樣的技術(shù)?”時(shí),所指代的東西,但是這一方面確實(shí)會(huì)出現(xiàn)很多有趣的創(chuàng)新。
這包括算法方面的技巧,如分片(Shard)、分區(qū)(Partition)、緩存數(shù)據(jù),以及保持分布式數(shù)據(jù)的一致等。雖然像“部署和監(jiān)控”這樣的事情,聽(tīng)上去似乎有些很普通,但是當(dāng)一切到了Facebook這樣大的規(guī)模,就變的不再簡(jiǎn)單。
以下是我們面臨的一些具體的挑戰(zhàn):
1. 數(shù)據(jù)中心間的一致性
Facebook是一個(gè)實(shí)時(shí)的應(yīng)用程序,這也就意味著,無(wú)論世界哪一個(gè)角落的數(shù)據(jù)發(fā)生改變,都需要立即顯示到所有其他的地方。因此這對(duì)一致性有著令人驚訝的高要求。
常常有人說(shuō),“哦,F(xiàn)acebook只是一個(gè)讓人覺(jué)得挺有趣的社交網(wǎng)站,一致性并沒(méi)有那么重要?!钡侨绻畔⒊霈F(xiàn)的時(shí)間順序有問(wèn)題,或者有的消息會(huì)憑空消失,那么這些情況就很容易惹惱用戶。以下是我們?cè)?007年,創(chuàng)建首個(gè)地理分布數(shù)據(jù)中心時(shí)的老博客:《Scaling Out Facebook》
現(xiàn)在回頭看,雖然這個(gè)方案聽(tīng)起來(lái)有些嚴(yán)格,但是它真的很有用,而且?guī)椭屛覀冞_(dá)到了現(xiàn)在這個(gè)巨大得規(guī)模。而現(xiàn)在的設(shè)置顯然已經(jīng)變得更為復(fù)雜。
2. 網(wǎng)絡(luò)流
Facebook的頁(yè)面,需要很多小塊的數(shù)據(jù),而這些往往并不容易聚集。所以我們經(jīng)??吹降囊粋€(gè)模式,是一臺(tái)服務(wù)器,會(huì)從大量其他的服務(wù)器處,要求大量小的對(duì)象。而這里的問(wèn)題在于,如果所有的服務(wù)器都在同時(shí)進(jìn)行回復(fù),你就會(huì)通過(guò)請(qǐng)求服務(wù)器的rack switch和網(wǎng)絡(luò)適配器(NIC)突然獲得大量的數(shù)據(jù)包,然后就會(huì)有數(shù)據(jù)包被丟棄。這就是學(xué)術(shù)文獻(xiàn)中所謂的“TCP incast”,而我們解決這個(gè)的方法,是對(duì)機(jī)器上發(fā)送的請(qǐng)求進(jìn)行截流。
而當(dāng)故障(failure)出現(xiàn)的時(shí)候,網(wǎng)絡(luò)問(wèn)題往往會(huì)變得更加糟糕。大多數(shù)軟件在沒(méi)有從另一個(gè)服務(wù)器獲得回應(yīng)時(shí),都會(huì)重新發(fā)送另外一個(gè)數(shù)據(jù)包。不幸的是,大多數(shù)時(shí)候,沒(méi)有獲得回復(fù)的原因,恰恰是另外一個(gè)服務(wù)器已經(jīng)過(guò)載。因此,當(dāng)一個(gè)服務(wù)器過(guò)載嚴(yán)重,而無(wú)法作出及時(shí)回復(fù)時(shí)由于大量請(qǐng)求會(huì)重新發(fā)送,它的數(shù)據(jù)流量會(huì)瞬時(shí)增長(zhǎng)一倍。
我們投入了大量的時(shí)間用于算法研究,并希望無(wú)縫處理“重試”(retry)可以解決的小問(wèn)題,但是也需要確保不會(huì)在出現(xiàn)大故障的時(shí)候失去控制,因?yàn)槟菚r(shí)候重試只會(huì)讓事情變得更糟。
3. 高速緩存配置
這里有很多東西需要平衡——如果你有大的對(duì)象,你希望通過(guò)機(jī)器進(jìn)行傳遞開(kāi),這樣你就可以進(jìn)行并行處理;但是如果是小的對(duì)象,你則希望它們可以同時(shí)出現(xiàn),這樣在RPC調(diào)用會(huì)給你帶來(lái)多個(gè)對(duì)象。而Facebook需要的往往是后者,因此我們?cè)诟纳啤懊縍PC對(duì)象數(shù)量”方面,使用了很多的技巧。
很多情況都需要分離不同工作負(fù)載的對(duì)象,進(jìn)行不同的調(diào)整。我們還花了大量的的時(shí)間,搞清楚是什么內(nèi)存之中最具有成本效益的東西,以及何時(shí)非規(guī)范化能有用(實(shí)踐中的大多數(shù)時(shí)候,非規(guī)范化并沒(méi)有什么實(shí)質(zhì)性的幫助)。
4. 失敗處理
正如前面網(wǎng)絡(luò)部分所提到的,有的時(shí)候一些方法能夠解決小問(wèn)題,但往往會(huì)讓大問(wèn)題變得更糟。例如,我有一個(gè)算法,給隨機(jī)服務(wù)器發(fā)送請(qǐng)求,如果它沒(méi)有得到答復(fù),就會(huì)把請(qǐng)求重新發(fā)送到另一個(gè)不同的隨機(jī)服務(wù)器上,直到它得到一個(gè)答復(fù)才會(huì)停止。如果你只有一兩個(gè)機(jī)器出現(xiàn)問(wèn)題的時(shí)候,這種方法顯然會(huì)表現(xiàn)很好。但是如果你一半的機(jī)器都出現(xiàn)問(wèn)題,那么就成了一場(chǎng)災(zāi)難。
這時(shí),所有其他的機(jī)器的負(fù)荷都會(huì)突然加倍,而如果一半的機(jī)器都出現(xiàn)問(wèn)題,很有可能意味著有著負(fù)載已經(jīng)過(guò)高。這時(shí)候,你需要做的事情,是檢測(cè)過(guò)載情況,并且減少負(fù)載。重要的是,要記住計(jì)算機(jī)科學(xué)意義上的實(shí)時(shí)系統(tǒng),意味著:一個(gè)遲到的回應(yīng),就是一個(gè)錯(cuò)誤的回應(yīng)。
放棄一個(gè)請(qǐng)求的時(shí)候,人們往往會(huì)感覺(jué)不好,不過(guò)這往往是最好的處理方式——在出現(xiàn)問(wèn)題的時(shí)候,最大化正確答案的數(shù)量才是最正確的。
另一種常見(jiàn)的模式是,當(dāng)有些東西變慢的時(shí)候,就建立一個(gè)較大的隊(duì)列(queue),然后讓所有事情慢下來(lái),減少負(fù)載。這可以是一個(gè)很棘手的算法,因?yàn)槟憧赡茉谡2僮髦幸残枰粋€(gè)深隊(duì)列,來(lái)處理瞬間突發(fā)流量。
5. 提升Memcache和MySQL
我們討論到數(shù)據(jù)庫(kù)/緩存集群的時(shí)候,人們總會(huì)想到Memecache和MySQL。我們?cè)贛emcache方面做了大量的工作,以提升吞吐量——大量的分析和解決方法,這大多數(shù)都是在網(wǎng)絡(luò)棧中。因此很多這樣的工作,實(shí)際上是在Linux內(nèi)核中發(fā)生的。
在MySQL中,則是關(guān)于以一種合理的方式,獲得磁盤(pán)上的數(shù)據(jù),并且把內(nèi)存中最有用的東西放到緩存里。馬克·卡拉漢(Mark Callaghan)的博客中,有著大量的信息:《高可用性MySQL》( http://mysqlha.blogspot.com/)。
6. Meta
在這篇文章中,我記錄了我們所遵循的原則:《讓Facebook的用戶超過(guò)5億》
(編輯:Stev)