在大數(shù)據(jù)時代,Log是干系數(shù)據(jù)庫對計較機(jī)行業(yè)的偉大孝敬,更是基本技能之一。然而在各人熱烈接頭GFS, NoSQL,以致Paxos, LSM tree等詞語的時候,Log這個基本技能以及它對大數(shù)據(jù)行業(yè)的龐大孝敬卻一直以來都被業(yè)界所忽略。除了Kafka作者之一Jay Kreps2013年一篇非著名的文章以外,我險些不能發(fā)明太多接頭Log的。豈論這種忽略有意無意,都讓我以為有須要寫一篇文章。本文團(tuán)結(jié)了Jay的文章的概念和本人在這個規(guī)模的實(shí)踐履歷,旨在對我們司空見慣的Log在大數(shù)據(jù)系統(tǒng)內(nèi)里的龐大浸染做一個推廣和普及
01
當(dāng)我們說Log的時候,凡是在指兩種差異對象,其一是應(yīng)用措施的調(diào)試信息,凡是此類log是人閱讀的,形式也不牢靠,有時候需要像Splunk這樣的東西來資助。別的一種則是我們本日要講的log,由干系數(shù)據(jù)庫規(guī)模發(fā)現(xiàn)出來,最開始的目標(biāo)是為了做妨礙規(guī)復(fù)。這種log教科書上有Undo Log, Redo Log 可能Undo/Redo Log三種。可是實(shí)踐來說,Redo Log是最常用的,也是本日我們要談?wù)摰摹K詮倪@里往下,整篇文章我們接頭的是干系數(shù)據(jù)庫內(nèi)里的Redo Log。有關(guān)這個的界說我會在下面一節(jié)展開。
02
要領(lǐng)略Log,我們可以把它看做一個數(shù)據(jù)布局,雷同于Hash Table可能Stack。至于這個數(shù)據(jù)布局怎么實(shí)現(xiàn),本文不做具體接頭,也不影響領(lǐng)略本文的內(nèi)容。
Log這個數(shù)據(jù)布局的根基形式是一個記錄的的序列。每個記錄分為兩部門:一個時間戳,和記錄的內(nèi)容。Log要求時間戳是嚴(yán)格遞增的。也就是說下一筆記錄老是比上一筆記錄的時間戳要大。時間序列不必然是呆板時間,任何嚴(yán)格遞增的序列,都是可以的。
對付Log的操縱有兩種,第一種是在序列的末端加一條新的記錄,第二是順序閱讀這個記錄序列。Log內(nèi)里的所有記錄一旦寫入今后就是只讀的了。
03
在Log的記錄里,每筆記錄可以存放的內(nèi)容凡是有兩種形式,一種是記錄要對數(shù)據(jù)庫的表做什么樣的操縱,一種是記錄數(shù)據(jù)庫的表顛末操縱今后值產(chǎn)生了什么改變。我們通過一個例子來展示這兩種方法的差異。
假設(shè)一個數(shù)據(jù)庫表內(nèi)里存的是用戶和他存的錢的金額,而所有的勾當(dāng)僅僅限于存錢和費(fèi)錢。我們假設(shè)張三的初始存款是500塊。那么第一種log的方法看起來像這樣:
1 張三 + 100
2 張三 – 200
3 張三 – 50
4 張三 + 100
而第二種方法則看起來像這樣:
1 張三 800
2 張三 600
3 張三 550
4 張三 650
兩種方法的區(qū)別在于第二種記錄了錢變革后的功效,而不記錄是什么樣的操縱導(dǎo)致了錢的變革。第一種則記錄了實(shí)際的操縱。
作為一個Log,我們凡是還會有對應(yīng)操縱的工具,在干系數(shù)據(jù)庫內(nèi)里,凡是這個是表可能數(shù)據(jù)庫。而在NoSQL內(nèi)里則是Key和Value。我們可以說,對應(yīng)操縱的工具存的是工具的當(dāng)前狀態(tài),而Log內(nèi)里則記錄了從初始狀態(tài)到當(dāng)前狀態(tài)的所有變革。所以作為Log的第一個浸染,就是當(dāng)系統(tǒng)產(chǎn)生妨礙今后,對系統(tǒng)舉辦規(guī)復(fù)。
作為系統(tǒng)規(guī)復(fù)的Log,第一種方法和第二種方法的記錄有著本質(zhì)的差異。當(dāng)我們利用第二種方法的時候,我們沒有任何需要擔(dān)憂的,獨(dú)一的一點(diǎn),我們也同樣丟失了是什么原因?qū)е铝藬?shù)值的改變。這種丟失對付一個呆板閱讀的Log是無所謂的。而第一種方法就紛歧樣了,我們必需假設(shè)所有的操縱在給定初始狀態(tài)和操縱今后,返回的功效是確定的。一些操縱好比說獲取當(dāng)前系統(tǒng)時間,可能取一個隨機(jī)數(shù)這樣的對象,是不正當(dāng)?shù)牟倏v,不然Log作為規(guī)復(fù)數(shù)據(jù)的浸染也就不存在了。因此實(shí)踐來說,利用第二種方法記錄數(shù)據(jù)改變的Log居多。可是在漫衍式系統(tǒng)內(nèi)里,利用第一種方法來記錄也并非不存在。
Log作為規(guī)復(fù)手段,在漫衍式系統(tǒng)和大數(shù)據(jù)系統(tǒng)中無處不在。好比說在BigTable里,對Memory Table舉辦更新之前,就要先寫Log。
04
Log的重要特性:假如知道初始狀態(tài)和Log,就可以規(guī)復(fù)出期間任意一個狀態(tài)。
這個特性讓Log在妨礙規(guī)復(fù)以外的規(guī)模很快就找到了用武之地。在漫衍式數(shù)據(jù)庫內(nèi)里,不管是高峻上的Oracle照舊白菜化的MySQL,在差異的備份之間舉辦同步,其根基的思路就是一方把Log傳給別的一方。別的一方只要老誠懇實(shí)的憑據(jù)順序執(zhí)行Log上的操縱。按照我們講過的Log的重要特性,我們知道最終的狀態(tài)也一定是一致的。
當(dāng)我們進(jìn)入到大數(shù)據(jù)時代今后,這種傳統(tǒng)的漫衍式數(shù)據(jù)庫的同步方法就被代替了。無論是Chubby照舊BigTable照舊Spanner,有一個很是有名的刺眼的名詞Paxos就這樣善良登場了。