此次準備開啓一個新的系列來寫了,聊聊分佈式系統中的關注點。節奏不會排的太緊湊,計劃兩週一更吧。html
本文是本系列的第一篇。從廣泛認爲的分佈式系統中最最最重要的數據一致性開始。內容適合人羣>=0年技術相關經驗。網絡
任何事物可以被持續的運用和發展,必然有其價值,分佈式系統也是同樣。分佈式系統的產生我認爲主要的目的就是「快」和「海量」。這個「快」能夠分爲兩個方面:架構
第一個是系統的處理速度快。分佈式
第二個是開發的速度快(歷時短)。性能
這2點本質都是相同的,把一個動做或者一件事情拆成兩部分或者多個部分去同時進行,使得總體的耗時縮短。好比:本來一件事情要一我的作的話要兩分鐘。那麼我僱傭兩我的幫我各自作一部分,那麼最理想狀況下一分鐘就能夠完成了。單元測試
固然這兩個方面中第二項從某種意義上來講是能夠克服的,可是第一項是沒法克服的。由於沒有一個程序或者說一臺計算機,它的性能是無窮大的,若是有,那分佈式系統也不會像如今這麼廣泛了(不少時候用錢能解決的問題都不是問題了)。測試
「海量」則是因爲不存在無窮大的硬盤,因此咱們須要把數據分別存儲到不一樣的硬盤上,才能知足需求。這些硬盤可能在不一樣主機、不一樣機房、不一樣地域,將來可能會在不一樣的星球吧。架構設計
所謂每一個事物都是矛盾統一的結合體,都具備兩面性。分佈式系統再帶來了前面提到的好處的同時,也帶來了業界廣泛認爲最大的問題 —— 數據一致性問題。設計
系統是給人用的,構成使用場景的概念叫業務。業務是核心,對一個系統來講,業務的發展歸根究竟是創建在數據之上的。我能夠慢、能夠宕機、能夠搞得很複雜,這些都能忍,但惟獨不能忍的就是數據問題,數據錯誤、數據不一致等等。cdn
分佈式就意味着分治與協做,一件事一我的只負責一部分。生活中這樣的例子也無處不在,就拿舉辦一個Party來講:一部分人去準備吃的,一部分人去準備喝的,一部分人去準備場地佈置。這些事情你們均可以同時進行,可是任一環節掉鏈子了,或者說不符合Party主題的話,都是失敗的。(不知道爲何,腦子裏浮現的是一場發佈會,你們喊着cheers,一口乾了高腳杯裏的二鍋頭。。。)。
再舉個電商場景中的程序案例:
這裏的4個操做以目標來看,其實前後順序並不重要,重要的是要麼都成功,要麼都失敗,其中任意一個程序不一致那麼就會出問題。這個問題本質上和人與人之間的溝通問題是相似的,以前寫過一篇文章也專門聊過溝通問題,有興趣的能夠擴展閱讀下:《就簡單聊聊溝通效率問題》,上面的Party的例子也是這個道理。與溝通惟一的不一樣在於,對程序來講,不必定都要獲得響應,都沒響應也是一致。當一個事情分紅100個部分去作的時候,很可怕,從機率的角度來看,達到一致的機率是2/5050。
這裏舉的程序例子並非嚴謹,由於實際的分佈式系統中由於除了「write」操做還有「read」操做,因此一致性問題比這個更復雜,後面會有更詳細的說明。
那麼是什麼緣由致使了數據不一致的產生呢?一是程序設計問題,或者說代碼寫錯了。這點很好理解,也很容易想到解決方案,多作測試,驗證是否符合預期咯。常見的單元測試、接口測試、自動化測試、集成測試等等都是爲了更具性價比的將BUG下降到無限接近於0,也造就了「測試工程師」這個崗位更大的做用。
可是,假設真的沒有BUG,但仍是會產生數據不一致,由於軟件是運行在硬件之上的,因此還有硬件的因素存在。而且對咱們這裏的大部分人來講,硬件相比軟件,咱們的掌控力更弱。這其中,最爲嚴重的屬網絡問題,網絡相比其它的來講是一個更大、更復雜的組織,未知性會隨着局域網、廣域網這樣範圍越大越嚴重。想象一下,每一臺主機僅僅是一張大網中的一個眇小的鏈接點,它所承載的連接越多越容易出現問題。
可能有的小夥伴會有疑問,其它像硬盤、電源斷電什麼的,也有出現問題的可能性,爲何網絡問題最爲嚴重呢?其實硬盤、電源比如是你身體的一部分,如手和腳。而網絡是人與人之間溝通的渠道,好比手機通話,雖然你沒有主動掛斷電話,可是整個通話過程是有不少可能性致使中斷的,對方的主觀意願也好、信號很差也罷,甚至被第三者給攔截了。相信你們也能承認,打電話出現異常的機率相比本身的手腳不聽使喚是高不少的吧。
現實中網絡的特色,常遇到的問題如:延遲、丟包、亂序等問題。爲了解決這些問題,從互聯網第一次出現的1969年(當年美軍在ARPA制定的協定下用網絡鏈接了4所大學)到如今,幾十年間出了不少的理論和解決方案,這些會在後續的文章中給你們一一作梳理。本文先和你們具體剖析下什麼是一致性。
首先什麼叫達成一致了?提及來很簡單:
在任意時間、任意位置看到的同一個事物是徹底一致的。
好比一場足球賽。咱們無論在現場仍是在電視機前,看到足球從球員A傳給球員B,這個信息都是同樣的。可是嚴格意義上來講,這個並稱不上真正的一致,由於電視機接收到這個信息須要通過衛星信號、網絡等的傳輸,咱們看到的時候相比現場的人確定要晚。哪怕在現場的人,根據他所處的位置理論上看到的信息也存在延遲差,只是由於光速很是快,使得在相差幾百米以內,這個延遲小到徹底感覺不到而已。
能得出的結論是:在考慮時間維度的狀況下,不存在真正意義上的一致。
何況咱們在分佈式系統中,也沒有必要去達到真正的意義上的一致。由於越趨近於一致,系統至關於又歸一成一個單體了,在某一個時刻,只能作一件事,徹底喪失了分佈式系統的兩個目的之一「快」的優點。也所以衍生出多種一致性的變種,分別適用於不一樣的場景。爲了便於理解,咱們從嚴格程度的低到高來講。
大多數狀況下,爲了儘量的「快」,系統中使用的大部分方案都是所謂的最終一致性,也就容忍必定條件下的不一致,優先保證局部一致,而後再經過一系列複雜的狀態同步達到全局的一致。最終一致性不少可實現的分支,列出幾種常見的,拋磚引玉一下:
■ 因果一致性:僅要求有因果關係的操做順序獲得保證。好比朋友圈的回覆功能。問「飯吃了嗎?」確定得在回答「吃了」以前。
■ 讀你所寫一致性:文字看着彆扭,但很好解釋。好比你在朋友圈下面回覆一句話,其它好友能夠不用立刻看到你的回覆,可是你本身必須得立刻看到,要否則回覆到哪去了?
■ 會話一致性:與人的一次聊天能夠理解爲一次會話。聊天雖然也有必定的因果關係,可是大部分場景下更多的是邏輯上的前後關係。好比你闡述一個事情,分爲3條信息:首先...,而後...,最後...。若是這裏的一致性得不到保證那麼可能會變成:最後...,首先...,而後...。
比局部一致更嚴格一些的就是全局的順序一致性[附錄1,1979年提出],保證全部進程看到的全局執行順序一致,而且每一個進程自身的執行順序和實際發生順序一致。像上面提到的足球賽,好比實際發生的事情是①梅西把球傳給了C羅,②C羅又把球回傳給了梅西,那麼每一個人看到順序都應該是這樣。哪怕現場觀衆已經看到②了,電視機前的咱們還沒看到①,可是不要緊,這個事情發生的順序,對全世界來講都是同樣的。
再嚴格一些,就是在全局的順序一致性基礎上再增長一個相對時間的一致性要求,業界稱之爲線性一致性[附錄2,1990年提出]。仍是用上面梅西和C羅相互傳球的例子來作個比喻,至關於梅西傳出球給C羅以後,整個球場「暫停」了,要等全部在觀看這場球賽的人都接收到這個傳球信息以後,C羅才能作下一個回傳。這裏須要一個上帝(全局時鐘)來「暫停」。這是咱們實際能夠作到的極限了,知足這類要求的系統中,名氣最大的就屬Google的Spanner了。
對不一樣級別的一致性彙總概述以下:
這篇就到這吧,本來還想一次性寫完的,發現內容實在太多,上萬字的文章,估計不少人都沒有看下去的勇氣了。
如何解決一致性問題,且聽下回分解~
論文附錄:
[1]《How to Make a Multiprocessor Computer That Correctly Executes Multiprocess Programs》,Leslie Lamport,1979。連接:research.microsoft.com/en-us/um/pe…
[2] 《Linearizability:A Correctness Condition for Concurrent Objects》,Maurice P. Herlihy,Jeannette M. Wing, 1990。連接:cs.brown.edu/~mph/Herlih…
做者:Zachary_Fan
出處:www.cnblogs.com/Zachary-Fan…
以爲回答的不錯就點個【推薦】吧~
歡迎掃描下面的二維碼,關注公衆號:跨界架構師,第一時間瞭解做者的思考。
內容包括:架構設計丨分佈式系統丨產品丨運營丨一些深度思考。