首席工程師揭秘:LinkedIn大資料後臺是如何運作的

來源:互聯網
上載者:User

編者按: Jay Kreps是來自LinkedIn的首席工程師,他表示日誌幾乎在電腦產生的時候就存在,除了可用在分散式運算或者抽象分散式運算模型內部之外,還有廣泛的用途。 本文中他講述的日誌的原理和通過把日誌用做單獨服務來實現資料整合、即時資料處理以及分散式系統設計。 文章內容非常乾貨,值得學習。

以下是原文:

我在六年前的一個令人興奮的時刻加入到LinkedIn公司。 從那個時候開始我們就破解單一的、集中式資料庫的限制,並且啟動到特殊的分散式系統套件的轉換。 這是一件令人興奮的事情:我們構建、部署,而且直到今天仍然在運行的分散式圖形資料庫、分散式搜索後端、Hadoop安裝以及第一代和第二代鍵值資料存儲。

從這一切裡我們體會到的最有益的事情是我們構建的許多東西的核心裡都包含一個簡單的理念:日誌。 有時候也稱作預先寫入日誌或者提交日誌或者事務日誌,日誌幾乎在電腦產生的時候就存在,同時它還是許多分散式資料系統和即時應用結構的核心。

不懂得日誌,你就不可能完全懂得資料庫,NoSQL存儲,鍵值存儲,複製,paxos,Hadoop,版本控制以及幾乎所有的軟體系統;然而大多數軟體工程師對它們不是很熟悉。 我願意改變這種現狀。 在這篇博客文章裡,我將帶你流覽你必須瞭解的有關日誌的所有的東西,包括日誌是什麼,如何在資料整合、即時處理和系統構建中使用日誌等。

第一部分:日誌是什麼?

日誌是一種簡單的不能再簡單的存儲抽象。 它是一個只能增加的,完全按照時間排序的一系列記錄。 日誌看起來如下:

我們可以給日誌的末尾添加記錄,並且可以從左至右讀取日誌記錄。 每一條記錄都指定了一個唯一的有一定順序的日誌記錄號碼。

日誌記錄的排序是由「時間」來確定的,這是因為位於左邊的日誌記錄比位於右邊的要早些。 日誌記錄號碼可以看作是這條日誌 記錄的「時間戳記」。 在一開始就把這種排序說成是按時間排序顯得有點多餘 ,不過 ,與任何一個具體的物理時鐘相比,時間 屬性是非常便於使用的屬性。 在我們運行多個分散式系統的時候,這個屬性就顯得非常重要。

對於這篇討論的目標而言,日誌記錄的內容和格式不怎麼重要。 另外提醒一下,在完全耗盡存儲空間的情況下,我們不可能 再給日誌添加記錄。 稍後我們將會提到這個問題。

日誌並不是完全不同于檔或者資料表的。 檔是由一系列位元組組成,表是由一系列記錄組成,而日誌實際上只是按照時間順序存儲記錄的 一種資料表或者檔。

此時,你可能奇怪為什麼要討論這麼簡單的事情呢? 不同環境下的一個只可增加的有一定順序的日誌記錄是怎樣與資料系統關聯起來的呢? 答案是日誌有其特定的應用目標:它記錄了什麼時間發生了什麼事情。 而對分散式資料系統許多方面而言, 這才是問題的真正核心。

不過,在我們進行更加深入的討論之前,讓我先澄清有些讓人混淆的概念。 每個程式設計人員都熟悉另一種日誌記錄-應用使用syslog或者log4j可能寫入到本地檔裡的沒有結構的錯誤資訊或者追蹤資訊。 為了區分開來,我們把這種情形的日誌記錄稱為「應用日誌記錄」。 應用日誌記錄是我在這兒所說的日誌的一種低級的變種。 最大的區別是:文本日誌意味著主要用來方便人們閱讀,而我所說明的「日誌」或者「資料日誌」的建立是方便程式訪問。

(實際上,如果你對它進行深入的思考,那麼人們讀取某個機器上的日誌這種理念有些不順應時代潮流。 當涉及到許多服務和伺服器的時候,這種方法很快就變成一個難於管理的方式,而且為了認識多個機器的行為,日誌的目標很快就變成查詢和圖形化這些行為的輸入了-對多個機器的某些行為而言, 檔裡的英文形式的文本同這兒所描述的這種結構化的日誌相比幾乎就不適合了。 )

資料庫日誌

我不知道日誌概念起源於何處-可能它就像二進位搜索一樣:發明者認為它太簡單而不能當作一項發明。 它早在IBM的系統R出現時候就出現了。 資料庫裡的用法是在崩潰的時候用它來同步各種資料結構和索引。 為了保證操作的原子性和持久性,在對資料庫維護的所有各種資料結構做更改之前,資料庫把即將修改的資訊謄寫到日誌裡。 日誌記錄了發生了什麼,而且其中的每個表或者索引都是一些資料結構或者索引的歷史映射。 由於日誌是即刻永久化的,可以把它當作崩潰發生時用來恢復其他所有永久性結構的可信賴資料來源。

隨著時間的推移,日誌的用途從實現ACID細節成長為資料庫間複製資料的一種方法。 利用日誌的結果就是發生在資料庫上的更改順序與遠端複製資料庫上的更改順序需要保持完全同步。

Oracle,MySQL 和PostgreSQL都包括用於給備用的複製資料庫傳輸日誌的日誌傳輸協議。 Oracle還把日誌產品化為一個通用的資料訂閱機制,這樣非Oracle資料訂閱使用者就可以使用XStreams和GoldenGate訂閱資料了,MySQL和PostgreSQL上的類似的實現則成為許多資料結構的關鍵元件。
正是由於這樣的起源,機器可識別的日誌的概念大部分都被局限在資料庫內部。 日誌用做資料訂閱的機制似乎是偶然出現的,不過要把這種 抽象用於支援所有類型的消息傳輸、資料流程和即時資料處理是不切實際的。

分散式系統日誌

日誌解決了兩個問題:更改動作的排序和資料的分發,這兩個問題在分散式資料系統裡顯得尤為重要。 協商出一致的更改動作的順序(或者說保持各個子系統本身的做法,但可以進行存在副作用的資料拷貝)是分散式系統設計的核心問題之一。

以日誌為中心實現分散式系統是受到了一個簡單的經驗常識的啟發,我把這個經驗常識稱為狀態機複製原理:如果兩個相同的、確定性的進程從同一狀態開始,並且以相同的順序獲得相同的輸入,那麼這兩個進程將會生成相同的輸出, 並且結束在相同的狀態。

這也許有點難以理解,讓我們更加深入的探討,弄懂它的真正含義。

確定性意味著處理過程是與時間無關的,而且任何其他「外部的「輸入不會影響到處理結果。 例如,如果一個程式的輸出會受到執行緒執行的具體順序影響,或者受到gettimeofday調用、或者其他一些非重複性事件的影響,那麼這樣的程式一般最有可能被認為是非確定性的。

進程狀態是進程保存在機器上的任何資料,在進程處理結束的時候,這些資料要麼保存在記憶體裡,要麼保存在磁片上。

以相同的順序獲得相同輸入的地方應當引起注意-這就是引入日誌的地方。 這兒有一個重要的常識:如果給兩段確定性代碼相同的日誌輸入,那麼它們就會生成相同的輸出。

分散式運算這方面的應用就格外明顯。 你可以把用多台機器一起執行同一件事情的問題縮減為實現分散式一致性日誌為這些進程輸入的問題。 這兒日誌的目的是把所有非確定性的東西排除在輸入流之外,來確保每個複製進程能夠同步地處理輸入。

當你理解了這個以後,狀態機複製原理就不再複雜或者說不再深奧了:這或多或少的意味著「確定性的處理過程就是確定性的」。 不管怎樣,我都認為它是分散式系統設計裡較常用的工具之一。

這種方式的一個美妙之處就在於索引日誌的時間戳記就像時鐘狀態的一個副本——你可以用一個單獨的數位描述每一個副本,這就是經過處理的日誌的時間戳記。 時間戳記與日誌一一對應著整個副本的狀態。

由於寫進日誌的內容的不同,也就有許多在系統中應用這個原則的不同方式。 舉個例子,我們記錄一個服務的請求,或者服務從請求到回應的狀態變化,或者它執行命令的轉換。 理論上來說,我們甚至可以為每一個副本記錄一系列要執行的機器指令或者調用的方法名和參數。 只要兩個進程用相同的方式處理這些輸入,這些進程就會保持副本的一致性。

一千個人眼中有一千種日誌的用法。 資料庫工作者通常區分物理日誌和邏輯日誌。 物理日誌就是記錄每一行被改變的內容。 邏輯日誌記錄的不是改變的行而是那些引起行的內容被改變的SQL語句(insert,update和delete語句)。

分散式系統通常可以寬泛分為兩種方法來處理資料和完成回應。 「狀態機器模型」通常引用一個主動-主動的模型——也就是我們為之記錄請求和回應的物件。 對此進行一個細微的更改,稱之為「預備份模型」,就是選出一個副本做為leader,並允許它按照請求到達的時間來進行處理並從處理過程中輸出記錄其狀態改變的日誌。 其他的副本按照leader狀態改變的順序而應用那些改變,這樣他們之間達到同步,並能夠在leader失敗的時候接替leader的工作。

為了理解兩種方式的不同,我們來看一個不太嚴謹的例子。 假定有一個演算法服務的副本,保持一個獨立的數位作為它的狀態(初始值為0),並對這個值進行加法和乘法運算。 主動-主動方式應該會輸出所進行的變換,比如「+1」,「*2」等。 每一個副本都會應用這些變換,從而得到同樣的解集。 主動-被動方式將會有一個獨立的主體執行這些變換並輸出結果日誌,比如「1」,「3」,「6」等。 這個例子也清楚的展示了為什麼說順序是保證各副本間一致性的關鍵:一次加法和乘法的順序的改變將會導致不同的結果。

分散式日誌可以理解為一致性問題模型的資料結構。 因為日誌代表了後續追加值的一系列決策。 你需要重新審視Paxos演算法簇,儘管日誌模組是他們最常見的應用。 在Paxos演算法中,它通常通過使用稱之為多paxos的協定,這種協定將日誌建模為一系列的問題,在日誌中每個問題都有對應的部分。 在ZAB, RAFT等其它的協定中,日誌的作用尤為突出,它直接對維護分散式的、一致性的日誌的問題建模。

我懷疑的是,我們就歷史發展的觀點是有偏差的,可能是由於過去的幾十年中,分散式運算的理論遠超過了其實際應用。 在現實中,共識的問題是有點太簡單了。 電腦系統很少需要決定單個值,他們幾乎總是處理成序列的請求。 這樣的記錄,而不是一個簡單的單值寄存器,自然是更加抽象。

此外,專注于演算法掩蓋了 抽象系統需要的底層的日誌。 我懷疑,我們最終會把日誌中更注重作為一個商品化的基石,不論其是否以同樣的方式 實施的,我們經常談論一個雜湊表而不是糾結我們 得到是不是具體某個細節的雜湊表,例如線性或者帶有什麼什麼其它變體雜湊表。 日誌將成為一種大眾化的介面,為大多數演算法和其實現提升提供最好的保證和最佳的性能。

變更日誌101: 表與事件的二相性。

讓我們繼續聊資料庫。 資料庫中存在著大量變更日誌和表之間的二相性。 這些日誌有點類似借貸清單和銀行的流程,資料庫表就是當前的盈餘表。 如果你有大量的變更日誌,你就可以使用這些變更用以創建捕獲目前狀態的表。 這張表將記錄每個關鍵點(日誌中一個特別的時間點)的狀態資訊。 這就是為什麼日誌是非常基本的資料結構的意義所在:日誌可用來創建基本表,也可以用來創建各類衍生表。 同時意味著可以存儲非關聯式的物件。

這個流程也是可逆的:如果你正在對一張表進行更新,你可以記錄這些變更,並把所有更新的日誌發佈到表的狀態資訊中。 這些變更日誌就是你所需要的支援准即時的克隆。 基於此,你就可以清楚的理解表與事件的二相性: 表支援了靜態資料而日誌捕獲變更。 日誌的魅力就在於它是變更的完整記錄,它不僅僅捕獲了表的最終版本的內容,它還記錄了曾經存在過的其它版本的資訊。 日誌實質上是表歷史狀態的一系列備份。

這可能會引起你對原始程式碼的版本管理。 原始程式碼管理和資料庫之間有密切關係。 版本管理解決了一個大家非常熟悉的問題,那就是什麼是分散式資料系統需要解決的— 時時刻刻在變化著的分散式管理。 版本管理系統通常以補丁的發佈為基礎,這實際上可能是一個日誌。 您可以直接對當前 類似于表中的代碼做出「快照」互動。 你會注意到, 與其他分散式狀態化系統類似,版本控制系統 當你更新時會複製日誌,你希望的只是更新補丁並將它們應用到你的當前快照中。

最近,有些人從Datomic –一家銷售日誌資料庫的公司得到了一些想法。 這些想法使他們對如何 在他們的系統應用這些想法有了開闊的認識。 當然這些想法不是只針對這個系統,他們會成為 十多年分散式系統和資料庫文獻的一部分。

這可能似乎有點過於理想化。 但是不要悲觀! 我們會很快把它實現。

(責任編輯:蒙遺善)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.