LinkedIn.com 資料用例
下面是一些資料用例,可能我們在瀏覽 LinkedIn 網頁時都已經看到過了。
- 更新後的個人資料後幾乎可以實時的出現在招聘搜尋頁面
- 更新後的個人資料後幾乎可以實時的出現在人脈網頁
- 分享一個更新,可以近實時的出現在新聞 feed
- 頁面然後會更新到其他只讀頁面,像”你可能認識的人“、”看過我資料的人“、”相關搜尋“等。
令人震驚的是,如果我們使用較好的寬頻,這些頁面可以在數毫秒內完成載入!讓我們向LinkedIn 工程師團隊致敬!
早期的 LinkedIn 資料架構
像其它初創公司一樣,LinkedIn 早期也是通過單個的 RDBMS (關係型資料庫管理系統)的幾張表來儲存使用者資料和人脈關係。是不是很原始?後來這個 RDMBS 擴充套件出兩個額外的資料庫系統,其中一個用來支撐使用者個人資料的全文搜尋,另一個用來實現社交圖。這兩個資料庫通過 Databus 來取得最新資料。Databus 是一個變化捕捉系統,它的主要目標就是捕捉那些來至可信源(像 Oracle)中資料集的變更,並且把這些變化更新到附加資料庫系統中。
但是,沒過多久這種架構就已經很難滿足網站的資料需求了。因為按照 Brewerd 的 CAP 理論想要同時滿足下面的條件看似不太可能:
- 一致性:所有應用在同一時刻看到相同的資料
- 可用性:保證每個請求都能收到應答,無論成功或失敗
- 分割槽容錯性:部分系統的訊息丟失或失敗不影響系統系統整體的正常執行
根據上面的法則,LinkedIn 工程師團隊實現了他們稱作為時間線一致性(或者說近線系統的最終一致性,下面會解釋)以及另外兩個特性:可用性和分割槽容錯性。下面介紹目前 LinkedIn 的資料架構。
LinkedIn 如今的資料架構
如果要支撐在不到一秒鐘內處理數百萬使用者的相關事務,上面的資料架構已經明顯不足了。因此,LinkedIn 工程師團隊提出了三段式(three-phase)資料架構,由線上、離線以及近線資料系統組成。總體上講,LinkedIn 資料被儲存在如下幾種不同形式的資料系統中(看下面的圖):
RDBMS
- Oracle
- MySQL(作為 Espresso 的底層資料儲存)
RDBMS
- Espresso(LinkedIn 自己開發的文件型 NoSQL 資料儲存系統)
- Voldemart (分散式 Key-value 儲存系統)
- HDFS (存放 Hadoop map-reduce 任務的資料)
Caching
- Memcached
基於 Lucene 的索引
- 存放查詢、關係圖等功能資料的 Lucene 索引
- Espresso 使用的索引
圖: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 上搜尋不同的成員時,這些資料就是來自於搜尋索引。通常這個功能對招聘人員的幫助很大。
- 社交圖索引幫助在人們的人脈關係中顯示成員以及關係。通過這個索引使用者幾乎可以實時的得到網路關係的變化。
- 通過讀複製集獲取到的成員資料資料。這些資料會被’標準化服務‘訪問。讀複製集是對源資料庫的複製,這樣能使源資料庫的更新同步到這些複製集上面。增加讀複製集的最主要原因是能夠通過將讀操查詢分散到讀複製集上來減輕源資料庫(執行使用者發起的寫操作)的壓力。
用資料用例來展示它們是如何工作的
假如你更新了你個人資料中的最新技能和職位。你還接受了一個連線請求。那麼在系統內部到底發生了什麼:
- 將更新寫入 Oracle Master 資料庫
- 然後 Databus 做了如下一系列奇妙的工作來實現時間線一致性:
- 將資料變更,如最新技能和職位資訊,更新到標準化服務。
- 將上面提到的變更更新到搜尋索引服務。
- 將關係變更更新到圖索引服務。
資料架構經驗
如果要設計一個像 LinkedIn.com 一樣的支援資料一致性、高擴充套件性且高可用性的資料架構,可以借鑑下面的經驗
- 資料庫讀寫分離:你應當計劃兩種資料庫,一種用來執行寫操作的可以稱為“可信源”系統,另一種執行讀操作的可以稱為派生資料庫系統。這裡的經驗法則就是將由使用者發起的寫操作和使用者讀操作使用的資料庫區分開來。
- 派生資料庫系統:使用者的讀操作應該被分配到派生資料庫或者讀複製集上去。而派生資料庫系統則可以建立在下面的系統之上:1.Lucene 索引 2.NoSQL 資料儲存,例如:Voldemart、Redis、Cassandra、MongoDB 等。
- 對於使用者的讀操作,應該儘量從主可信源資料庫系統建立索引或者基於 key-value 的資料(來源於 Hadoop map-reduce 之類的系統),並且將每次由使用者發起的被寫入主可信源系統的變更一併更新到這些索引或派生資料(key-value)。
- 為確保派生資料庫系統的資料是最新的,你可以選擇應用複寫(application-dual writes),即在應用層同時寫入主資料庫和派生資料庫系統,或日誌挖掘(讀取通過批處理任務得到的主資料儲存系統的事務提交日誌)。
- 建立派生資料時,你可以針對主資料集或者變更資料集執行基於 Hadoop 的 map-reduce 任務,然後更新HDFS並且通知派生資料儲存系統(類似 Voldemart 的 NoSQL 儲存)來取走資料。
- 對於資料一致性來說,你可以以將這些資料儲存庫建立為分散式系統,叢集中的每個節點又都包含主從節點。所有節點都可以建立水平擴充套件的資料 Shards。
- 為了保證這些分散式資料儲存系統正常執行時間最大化,你可以使用像 Apache Helix 這一類的叢集管理工具。