首席工程師揭祕:LinkedIn大數據後臺是如何運做的?(一)

文章內容很是乾貨,很是值得學習。文章將以四部分進行闡述,建議你們耐心看完。

  第一部分:Log是什麼? html

  第二部分:數據集成 算法

  第三部分:日誌和實時流處理 數據庫

  第四部分:系統建設 編程

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

  從這一切裏咱們體會到的最有益的事情是咱們構建的許多東西的核內心都包含一個簡單的理念:日誌。有時候也稱做預先寫入日誌或者提交日誌或者事務日誌,日誌幾乎在計算機產生的時候就存在,同時它仍是許多分佈式數據系統和實時應用結構的核心。 服務器

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

  第一部分:日誌是什麼? 分佈式

日誌

  日誌是一種簡單的不能再簡單的存儲抽象。它是一個只能增長的,徹底按照時間排序的一系列記錄。日誌看起來以下: 工具

  咱們能夠給日誌的末尾添加記錄,而且能夠從左到右讀取日誌記錄。每一條記錄都指定了一個惟一的有必定順序的日誌記錄編號。 oop

  日誌記錄的排序是由「時間」來肯定的,這是由於位於左邊的日誌記錄比位於右邊的要早些。日誌記錄編號能夠看做是這條日誌 記錄的「時間戳」。在一開始就把這種排序說成是按時間排序顯得有點多餘 ,不過 ,與任何一個具體的物理時鐘相比,時間 屬性是很是便於使用的屬性。在咱們運行多個分佈式系統的時候,這個屬性就顯得很是重要。

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

  日誌並非徹底不一樣於文件或者數據表的。文件是由一系列字節組成,表是由一系列記錄組成,而日誌實際上只是按照時間順序存儲記錄的 一種數據表或者文件。

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

  不過,在咱們進行更加深刻的討論以前,讓我先澄清有些讓人混淆的概念。每一個編程人員都熟悉另外一種日誌記錄-應用使用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 –一家銷售日誌數據庫的公司獲得了一些想法。這些想法使他們對如何 在他們的系統應用這些想法有了開闊的認識。 固然這些想法不是隻針對這個系統,他們會成爲 十多年分佈式系統和數據庫文獻的一部分。

  這可能彷佛有點過於理想化。可是不要悲觀!咱們會很快把它實現。

  接下來的內容

  在這篇文章的其他部分,我將試圖說明日誌除了可用在分佈式計算或者抽象分佈式計算模型內部以外,還可用在哪些方面。其中包括:

  數據集成-讓機構的所有存儲和處理系統裏的全部數據很容易地獲得訪問。

  實時數據處理-計算生成的數據流。

  分佈式系統設計-實際應用的系統是如何經過使用集中式日誌來簡化設計的。

  全部這些用法都是經過把日誌用作單獨服務來實現的。

  在上面任何一種用法裏,日誌的用途開始都是使用了日誌所能提供的某個簡單功能:生成永久的、可重現的歷史記錄。使人意外的是,問題的核心是可讓多少臺機器以特定的方式,按照自身的速度重現歷史記錄的能力。



http://www.pmtoo.com/data/2014/0305/5037.html

相關文章
相關標籤/搜索