http://www.36dsj.com/archives/40584數據庫
譯者:伯樂在線-塔塔網絡
網址:http://blog.jobbole.com/69344/架構
LinkedIn是當今最流行的專業社交網站之一,本文描述了LinkedIn是如何管理數據的。如你對文中的觀點有異議亦或文中有遺漏的部分請隨時告訴我。app
下面是一些數據用例,可能咱們在瀏覽LinkedIn網頁時都已經看到過了。框架
使人震驚的是,若是咱們使用較好的寬帶,這些頁面能夠在數毫秒內完成加載!讓咱們向LinkedIn工程師團隊致敬!分佈式
像其它初創公司同樣,LinkedIn 早期也是經過單個的RDBMS (關係型數據庫管理系統)的幾張表來保存用戶資料和人脈關係。是否是很原始?後來這個RDMBS擴展出兩個額外的數據庫系統,其中一個用來支撐用戶我的資料的全文搜索,另外一個用來實現社交圖。這兩個數據庫經過Databus來取得最新數據。Databus是一個變化捕捉系統,它的主要目標就是捕捉那些來至可信源(像Oracle)中數據集的變動,而且把這些變化更新到附加數據庫系統中。工具
可是,沒過多久這種架構就已經很難知足網站的數據需求了。由於按照Brewerd的CAP理論想要同時知足下面的條件看似不太可能:oop
一致性:全部應用在同一時刻看到相同的數據網站
可用性:保證每一個請求都能收到應答,不管成功或失敗設計
分區容錯性:部分系統的消息丟失或失敗不影響系統系統總體的正常運行
根據上面的法則,LinkedIn工程師團隊實現了他們稱做爲時間線一致性(或者說近線系統的最終一致性,下面會解釋)以及另外兩個特性:可用性和分區容錯性。下面介紹目前LinkedIn的數據架構。
若是要支撐在不到一秒鐘內處理數百萬用戶的相關事務,上面的數據架構已經明顯不足了。所以,LinkedIn 工程師團隊提出了三段式(three-phase)數據架構,由在線、離線以及近線數據系統組成。整體上講,LinkedIn數據被存儲在以下幾種不一樣形式的數據系統中(看下面的圖):
RDBMS
RDBMS
Caching
基於Lucene的索引
圖:LinkedIn數據庫系統包括了DataBus、NoSQL、RDBMS以及Indexes
上面提到的數據存儲庫被歸爲三種不一樣類型的系統,下面會逐一解釋:
在線系統處理用戶的實時互動;主數據庫像Oracle就屬於這一類別。主數據存儲用來支撐用戶的寫操做和少許的讀操做。以Orcale爲例,Oracle master會執行全部的寫操做。最近,LinkedIn正在開發另外一個叫作「Espresso」的數據系統來知足日益複雜的數據需求,而這些數據看似不該從像Oracle這類的RDBMS中獲取。他們可否淘汰全部或大部分的Oracle並將數據徹底轉移到像Espresso這類的NoSQL數據存儲系統中去?讓咱們拭目以待。
Espresso是一個支持水平擴展、索引、時間線一致性、基於文檔且高可用的NoSQL數據倉庫,旨在代替支撐公司網頁操做所使用的傳統Oracle數據庫。設計它的初衷是爲了提升LinkedIn的InMail消息服務的可用性。目前有以下一些應用在使用Espresso做爲可信源系統。可以看到NoSQL數據存儲是若是被用來處理如此衆多應用的數據需求非常神奇!
離線系統主要包括Hadoop和一個Teradata數據倉庫,用來執行批處理和分析類的工做。之因此被稱爲離線是由於它對數據執行的的批處理操做。 Apache Azkaban被用來管理Hadoop和ETL任務,這些任務從主可信源系統獲取數據後交由map-reduce處理,處理結果被保存在HDFS,而後通知’消費者‘(例如:Voldemart)經過合適的方式來獲取這些數據並切換索引來保證能獲取到最新的數據。
近線系統的目標是爲了實現時間線一致性(或最終一致性),它處理相似’你可能認識的人(只讀數據集)‘、搜索以及社交圖這些功能,這些功能的數據會持續更新,但它們對延遲性的要求並不像在線系統那樣高。下面是幾種不一樣類型的近線系統:
Voldemart,一個Key-Value存儲系統,爲系統中的只讀頁面提供服務。Voldemart的數據來源於Hadoop框架(Hadoop Azkaban:編排Hadoop map-reduce任務的執行計劃)。這就是近線系統,它們從相似Hadoop的離線系統獲取數據。下面這些頁面的數據都是來自於Voldemart:
下面是幾種不一樣的索引,這些索引由Databus-一個變化數據捕捉系統-來更新的:
供SeaS(Search-as-a-Service)使用的’成員搜索索引‘。當你在LinkedIn上搜索不一樣的成員時,這些數據就是來自於搜索索引。一般這個功能對招聘人員的幫助很大。
社交圖索引幫助在人們的人脈關係中顯示成員以及關係。經過這個索引用戶幾乎能夠實時的獲得網絡關係的變化。
經過讀複製集獲取到的成員資料數據。這些數據會被’標準化服務‘訪問。讀複製集是對源數據庫的複製,這樣能使源數據庫的更新同步到這些複製集上面。增長讀複製集的最主要緣由是可以經過將讀操查詢分散到讀複製集上來減輕源數據庫(執行用戶發起的寫操做)的壓力。
下圖展現了數據變化捕獲事件是如何利用Databus更新到近線系統的:
假如你更新了你我的資料中的最新技能和職位。你還接受了一個鏈接請求。那麼在系統內部到底發生了什麼:
若是要設計一個像LinkedIn.com同樣的支持數據一致性、高擴展性且高可用性的數據架構,能夠借鑑下面的經驗:
數據庫讀寫分離:你應當計劃兩種數據庫,一種用來執行寫操做的能夠稱爲「可信源」系統,另外一種執行讀操做的能夠稱爲派生數據庫系統。這裏的經驗法則就是將由用戶發起的寫操做和用戶讀操做使用的數據庫區分開來。
派生數據庫系統:用戶的讀操做應該被分配到派生數據庫或者讀複製集上去。而派生數據庫系統則能夠創建在下面的系統之上:
NoSQL數據存儲,例如:Voldemart、Redis、Cassandra、MongoDB等。
對於用戶的讀操做,應該儘可能從主可信源數據庫系統建立索引或者基於key-value的數據(來源於Hadoop map-reduce之類的系統),而且將每次由用戶發起的被寫入主可信源系統的變動一併更新到這些索引或派生數據(key-value)。
爲確保派生數據庫系統的數據是最新的,你能夠選擇應用複寫(application-dual writes),即在應用層同時寫入主數據庫和派生數據庫系統,或日誌挖掘(讀取經過批處理任務獲得的主數據存儲系統的事務提交日誌)。
建立派生數據時,你能夠針對主數據集或者變動數據集執行基於Hadoop的map-reduce任務,而後更新HDFS而且通知派生數據存儲系統(相似Voldemart的NoSQL存儲)來取走數據。
對於數據一致性來講,你能夠以將這些數據存儲庫建立爲分佈式系統,集羣中的每一個節點又都包含主從節點。全部節點均可以建立水平擴展的數據Shards。
爲了保證這些分佈式數據存儲系統正常運行時間最大化,你可使用像Apache Helix這一類的集羣管理工具。