好久沒有寫技術文章了,因為一直在思考 「後端分布式」這個系列到底怎麼寫才合適。最近基本想清楚了,「後端分布式」包括「分布式存儲」和 「分布式計算」兩大類。結合實際工作中碰到的問題,以尋找答案的方式來剖解技術,很多時候我們都不是在創造新技術,而是在應用技術。為了更有效率與效果的用好技術,我們需要了解一些技術的原理與工作方式。帶著問題從使用者的角度去剖析技術原理,並將開源技術產品和框架作為一類技術的參考實現來講解。以講清原理為主要目的,對於具體實現的技術細節若無特別之處則盡可能點到即止。
近期參與了一個數據分布化相關的項目,涉及到數據庫 MySQL 的數據分布化。簡單來說就是需要在異地數據中心實現多點可寫並保證分布後的數據能達成最終一致性。以前對 MySQL 作數據分布僅僅是讀寫分離,通過數據庫自身的主從復制即可實現寫主庫、讀從庫。現在則需要雙寫主庫並在經歷一個短暫的延時後達成最終一致性,這個問題乍一想比較復雜,但歸根結底還是數據最終一致性的問題。
先回到最簡單的情況,只有一個 MySQL 數據庫時,數據一致性是怎麼保證的?了解數據庫的都知道,這是通過數據庫的事務特性來保證的,事務包括四大特性:
Atomicity 原子性 Consistency 一致性 Isolation 隔離性 Durability 持久性事務的 ACID 四大特性不是本文重點,就不展開做學術性解說了,不了解的可以在後面參考文獻裡[3]去看相關文章。這裡只想提一個問題,單一數據庫事務能保證數據的一致性,那麼 MySQL 在部署成主從架構時,如何保證主從之間數據的一致性的?
MySQL 為了提供主從復制功能引入了一個新的日志文件叫 binlog,它包含了引發數據變更的事件日志集合。從庫請求主庫發送 binlog 並通過日志事件還原數據寫入從庫,所以從庫的數據來源為 binlog。這樣 MySQL 主庫只需做到 binlog 與本地數據一致就可以保證主從庫數據一致(暫且忽略網絡傳輸引發的主從不一致)。我們知道保證本地數據一致性是靠數據庫事務特性來達成的,而數據庫事務是如何實現的呢?先看下面這張圖:
vcrHu/nT2iByZWRvIGxvZyC6zSB1bmRvIGxvZ6GjvPK1pcC0y7WjrHJlZG8gbG9nILzHwrzKws7x0N64xLrztcTK/b7dLCB1bmRvIGxvZyC8x8K8ysLO8cewtcTUrcq8yv2+3aGjy/nS1LWx0ru49srCzvHWtNDQyrHKtbzKt6LJ+rn9s8y88ruvw+jK9sjnz8KjujwvcD4NCs/IvMfCvCB1bmRvL3JlZG8gbG9no6zIt7GjyNXWvsuitb20xcXMyc+z1r7DtOa0oqGjILj80MLK/b7dvMfCvKOsu7q05rLZ1/eyotLssr3LosXMoaMgzOG9u8rCzvGjrNTaIHJlZG8gbG9nINbQ0LTI6yBjb21taXQgvMfCvKGjDQo8cD7U2iBNeVNRTCDWtNDQysLO8bn9s8zW0MjnufvS8rnK1c/W0LbPo6y/ydLUzai5/SByZWRvIGxvZyDAtNbY1/bKws7xu/LNqLn9IHVuZG8gbG9nIMC0u9i59qOsyLexo8HLyv2+3bXE0rvWwtDUoaPV4tCptrzKx9PJysLO8dDUtOa0otL9x+bAtM3qs8m1xKOstasgYmlubG9nILK71NrKws7xtOa0otL9x+a3ts6nxNqjrLb4ysfTySBNeVNRTCBTZXJ2ZXIgwLS8x8K8tcSho8THw7S+zbHY0Ouxo9akIGJpbmxvZyDK/b7dus0gcmVkbyBsb2cg1q685LXE0rvWwtDUo6zL+dLUv6rG9MHLIGJpbmxvZyC688q1vMq1xMrCzvHWtNDQvs224MHL0ruyvaOsyOfPwqO6PC9wPg0Kz8i8x8K8IHVuZG8vcmVkbyBsb2ejrMi3saPI1da+y6K1vbTFxczJz7PWvsO05rSioaMguPzQwsr9vt28x8K8o6y7urTmstnX97Ki0uyyvcuixcyhoyC9q8rCzvHI1da+s9a+w7uvtb0gYmlubG9noaMgzOG9u8rCzvGjrNTaIHJlZG8gbG9nINbQ0LTI68zhvbu8x8K8oaMNCjxwPtXi0fm1xLuwo6zWu9KqIGJpbmxvZyDDu9C0s8m5pqOs1fu49srCzvHKx9Do0qq72Ln2tcSjrLb4IGJpbmxvZyDQtLPJuaa687y0yrkgTXlTUUwgQ3Jhc2ggwcu2vL/J0tS71ri0ysLO8bKizeqzyczhvbuho9Kq1/a1vdXiteOjrL7N0OjSqrDRIGJpbmxvZyC6zcrCzvG52MGqxvDAtKOstvjWu9PQsaPWpMHLIGJpbmxvZyC6zcrCzvHK/b7dtcTSu9bC0NSjrLLFxNyxo9ak1ve008r9vt21xNK71sLQ1KGjy/nS1CBiaW5sb2cgtcTQtMjruf2zzLK7tcOyu8e2yOu1vbS/tOK1xMrCzvG05rSi0v3H5ta00NC5/bPM1tCjrLKi0tTE2rK/t9ayvMq9ysLO8aOoeGEgysLO8aOptcS3vcq9zeqzycG9vde2zszhvbuho7340ruyvbXEz7i92r7NsrvVub+qwcujrL/J0tSyzr+0uvPD5rLOv7zOxM/XWzVdoaM8L3A+DQo8aDIgaWQ9"總結">總結
我們前面先提出了一個問題,然後從數據一致性的角度去思考,參考了 MySQL 的實現方式。理清並分析了 MySQL 單機環境是如何保證復制機制的數據一致性,也就是 binlog 和事務數據的一致。後面我們才能基於 binlog 這個機制去實現復制並保證主從復制的一致性。主從復制又引入了網絡因素,進一步增加了保證主從數據一致性的復雜度,後面還會撰文進一步分析這個問題。