? ? 系統(tǒng)的性能并不是唯一指標(biāo),尤其是現(xiàn)在,系統(tǒng)的移動性、功耗也成為了都成為了最重要,甚至在手機(jī)等移動設(shè)備上是超過性能的指標(biāo)。對于一些極端的設(shè)備,性能可能是最次的考察指標(biāo),比如飛機(jī)上的黑匣子最重要的是穩(wěn)定性,南極科考站的系統(tǒng)最重要的是低溫情況下的運(yùn)作情況。對于我們一般人而言,最重要的可能是系統(tǒng)的容錯性和安全性。
? ? 系統(tǒng)的容錯主要是兩種方面,一個是數(shù)據(jù)的容錯,這是指系統(tǒng)能夠自動糾正可能含有錯誤的數(shù)據(jù);一個是控制的容錯,這是指系統(tǒng)在控制出現(xiàn)錯誤的時候,能夠按照正常的方式運(yùn)行而不會崩潰。要處理這些錯誤,勢必是要付出代價的,或者是通過冗余的方式在發(fā)生錯誤的時候進(jìn)行恢復(fù),或者增加額外的控制方法來應(yīng)對系統(tǒng)發(fā)生的錯誤。
? ? 數(shù)據(jù)通信中,是最常見發(fā)生錯誤的部分。但第一個簡單的問題就是,如何知道數(shù)據(jù)傳輸發(fā)生錯誤了?
假設(shè)從設(shè)備A到設(shè)備B,發(fā)送的信息是XYZ的話:
? ? ? ? 設(shè)備A知道A發(fā)送的是什么
? ? ? ? 設(shè)備B知道B收到的是什么
? ? ? ? 但是設(shè)備A不知道B收到的是什么
? ? ? ? 設(shè)備B不知道A發(fā)送的是什么。
雖然像繞口令,但是大概明確了這個問題為什么是個需要解決的問題。一個簡單的方法是:
? ? ? ? 設(shè)備A發(fā)送給B之后,
? ? ? ? B返回給A他收到的內(nèi)容,
? ? ? ? A根據(jù)收到的內(nèi)容來判斷是否和發(fā)送的內(nèi)容一致,
? ? ? ? 如果一致的話,告訴B這是一致的。
這固然是可以的方法,但是他將同樣的內(nèi)容發(fā)送了兩次,并且進(jìn)行了三次數(shù)據(jù)傳遞。如果原本一次數(shù)據(jù)傳遞發(fā)生錯誤的概率是a%,那么由于一次“被確認(rèn)的數(shù)據(jù)傳遞”需要三次普通的數(shù)據(jù)傳遞,這個“被確認(rèn)的數(shù)據(jù)傳遞”的只要其中一次傳遞發(fā)生錯誤,就會整體的錯誤,所以不僅數(shù)據(jù)傳輸?shù)男首兊土?,連數(shù)據(jù)傳輸?shù)目煽啃砸沧兊土恕?/p>
另外一種解決方法是,在數(shù)據(jù)傳輸?shù)倪^程中,增加一些信息來校驗(yàn)前面的數(shù)據(jù)中是否發(fā)生了錯誤。比如最簡單的奇偶校驗(yàn),對于每一個字節(jié)的8個bit,計算這個字節(jié)中1的數(shù)量,奇數(shù)個1的話就在后面添上一位校驗(yàn)碼1,偶數(shù)個1的話就在后面添上一位校驗(yàn)碼0。這樣做的效果是,傳輸?shù)臄?shù)據(jù)增加了12.5%,因?yàn)槊?位數(shù)據(jù)要添加一位校驗(yàn);有50%的概率發(fā)現(xiàn)錯誤,因?yàn)楫?dāng)偶數(shù)個數(shù)據(jù)位發(fā)生錯誤時,奇偶校驗(yàn)失效(這句話不正確,實(shí)際上是奇偶校驗(yàn)碼和數(shù)據(jù)位錯誤數(shù)一致時)。通過設(shè)計更好的校驗(yàn)方法,能有更高的糾錯能力。
知道是否有錯誤之后,我們有兩個選擇,一個是直接丟棄這部分?jǐn)?shù)據(jù),另一個是試圖修復(fù)這部分?jǐn)?shù)據(jù)。如果只考慮根據(jù)手中的數(shù)據(jù)來進(jìn)行數(shù)據(jù)糾錯,那么必須要使用更多的冗余信息來對數(shù)據(jù)進(jìn)行糾錯。比如海明碼通過對數(shù)據(jù)的多重校驗(yàn),來找到具體哪一位發(fā)生了錯誤,當(dāng)然這會增加更多的數(shù)據(jù)冗余,并且只有有限的數(shù)據(jù)修復(fù)能力。
對于實(shí)時數(shù)據(jù)傳輸來說,也許重新請求傳輸數(shù)據(jù)是一種更好的方法。如果是數(shù)據(jù)存儲系統(tǒng),就有更多的選擇。比如很多人使用的Ghost鏡像,就是在系統(tǒng)發(fā)生錯誤的時候快速恢復(fù)系統(tǒng)的冗余,原理很簡單,把所有東西都做備份。硬件上可以采用多塊硬盤互相備份的方式,來進(jìn)行數(shù)據(jù)的回復(fù),比如RAID系統(tǒng)保障了系統(tǒng)內(nèi)一塊或幾塊硬盤毀壞,數(shù)據(jù)不會丟失,由于采用了封裝的設(shè)計,計算機(jī)系統(tǒng)對RAID操作就和對于一塊硬盤操作的方式一樣。
如果從更大的維度上看,類似于Google這樣的公司在全球各地設(shè)計了數(shù)據(jù)中心。這就將容錯提升到了災(zāi)備的級別,即便有一個數(shù)據(jù)中心因?yàn)榈卣鸹蛘吒鞣N災(zāi)難毀壞了,其他數(shù)據(jù)中心也會繼續(xù)工作,用戶的數(shù)據(jù)不會丟失。當(dāng)然這樣的冗余成本也是巨大的。
除了硬件上的容錯機(jī)制之外,軟件上也會有對于操作的容錯,比如通過數(shù)據(jù)庫的日志來恢復(fù)數(shù)據(jù)庫的數(shù)據(jù)。此外就是一些軟件設(shè)計上的容錯,比如支付寶在支付的時候需要經(jīng)過若干步驟,就是為了在錯誤的下單后能夠及早發(fā)現(xiàn)和糾正。這些容錯的手段,或者是通過冗余的信息使得操作能夠恢復(fù)到某個時間點(diǎn),或者是通過冗余的流程來糾正錯誤的操作。
計算機(jī)系統(tǒng)設(shè)計容錯性的原則實(shí)際上依然是依賴于分層與封裝。容錯機(jī)制都是為了讓每一層和每一個模塊確保自己所存儲或者傳遞的信息是正確的,也基本都是發(fā)生在該層或者該模塊。比如網(wǎng)絡(luò)通信中,這些校驗(yàn)碼都是在物理傳輸層面進(jìn)行的,這樣使用這一層的通信層就可以依賴完全正確的物理傳輸進(jìn)行傳遞;這一層會進(jìn)行相互對話來確保A到B,B到A的通信是暢通的,這樣更高的應(yīng)用層就可以依賴通信層互通的鏈接來傳遞更多的數(shù)據(jù)。