《談談PhxSQL的設計和實現哲學(上)》要點:
本文介紹了談談PhxSQL的設計和實現哲學(上),希望對您有用。如果有疑問,可以聯系我們。
https://github.com/tencent-wechat/phxsql
PhxSQL是一個提供Zookeeper級別強一致和高可用的MySQL集群.PhxSQL完全兼容MySQL,建立在簡單可邏輯證明的一致性模型之上,架構、部署、運維簡單.文章還討論了PhxSQL與相關技術方案的區別,并比較了各自的優缺點.
文章比較長,正文分成上下兩章.上章主要討論why,即我們為什么要做PhxSQL以及為什么這樣做.下章著重探討why not,即我們為什么不支持若干特性,例如多主多寫和分庫分表,及與Galera和MySQL Group Replication的比較等.
PhxSQL[22]發布以來,受到很多關注.作為熱愛技術的碼農,我們感謝大家的關心和支持,歡迎一切基于技術出發點的討論.“Show you the code”之后,我們在這里談談PhxSQL的設計和實現哲學,也同時回答大家提出的一些疑問.
PhxSQL是一個通過Paxos保證強一致和高可用的的MySQL集群.PhxSQL建立在Paxos的一致性和MySQL的binlog流水基礎上.主要原理簡單來說:
只要有多于一半機器工作和互聯,PhxSQL就可以正常工作.
很多MySQL集群方案都宣稱強一致和高可用.PhxSQL這方面有什么不同?
大家熟知的Zookeeper提供強一致和高可用.一致性有很多級別,從強到弱分別是:Strict(嚴格一致性),Linearizable(線性一致性)[1],Sequential(序列一致性)[2],Causal(因果一致性),Eventual等.具體定義請參見參考文獻.嚴格一致性只是一個理論模型.根據相對論,由于信息傳播的速度不可能高于光速,嚴格一致性在實際中幾乎無法實現.線性一致性的理論定義很復雜,不太嚴謹直觀地講,就是任何一個客戶端都可以讀到別的客戶端寫入的最新內容.這也是大家通常理解的強一致.
Zookeeper的強一致指“線性一致性”[3].高可用是說只要多于一半機器工作和互聯即可在保證線性一致性的質量下正常工作.PhxSQL的強一致是指“線性一致性”,高可用是指只要多于一半機器工作和互聯即可在保證線性一致性質量下工作.即,
PhxSQL提供和Zookeeper相同的強一致性和高可用性!
PhxSQL提供和Zookeeper相同的強一致性和高可用性!
PhxSQL提供和Zookeeper相同的強一致性和高可用性!
重要事情說三遍:).大家可以把PhxSQL當Zookeeper使用,例如用來選主!
在數據庫事務隔離方面,PhxSQL支持最高級別的serializable.在性能方面,PhxSQL提供明顯優于MySQL半同步的寫性能和幾乎相同的讀性能[22].
細心的讀者可能注意到,和通常的“高可用、強一致”說法順序相反,這個小節的標題中,“強一致”有意放在了“高可用”的前面.在這里需要澄清一個誤區.當談到高可用時,有時會有意無意忽略或者降低一致性.嚴格意義上來講,可用性和一致性必須一塊討論,滿足一致性要求前提下的可用性才有意義.打個不嚴謹的比方,一致性就像汽車的“安全性”,可用性就是汽車的“可用性”.如果一輛車號稱“可用性”很好,可以連續工作10年,但從來不提“安全性”,那么這輛車的品質是值得懷疑的.
雖然有很多NoSQL、NewSQL系統、以及多主多寫MySQL集群、支持分庫分表的MySQL集群,MySQL傳統主備同步方案仍然具備很多新系統難以企及的優點.MySQL主備在主機上支持完整SQL、全局事務、以repeatable read和serializable級別的事務隔離,在金融、帳號等關鍵業務中有巨大的價值.同時,現有復雜MySQL應用遷移到新的非兼容系統成本也很高.
但是MySQL傳統主備方案也有其缺點.最明顯的就是主機故障后的自動換主和新舊主數據一致性(以及衍生的換主后主備一致性、各個備機之間一致性,這里就不詳加討論了),即所謂的一致性和可用性.
為了解決這個問題,有傳統流派:用Zookeeper、etcd、或者其它第三方來檢測心跳、選主、和切換.改造MySQL client讓其能感知新的主機.或者為了能讓傳統MySQL client不加修改就能感知新的主機,部署MySQL代理服務器,讓其將連到自身的MySQL client請求透明轉發給新的主機.為了減少主備間數據的落后,從而降低舊主機故障、某臺備機被提升成新主機時,新舊主機之間、新主機和其它備機之間的差異,很多方案在主備同步機制上做了很多有益的工作.例如semi-sync等待多數派備機應答,通過優化線程和網絡、主備多通道、備機并行執行binlog流水等盡量減少主備之間差異.如果主備間任何時刻都完全一致,那么任何時刻換主都是強一致的.這句話的另外一個意思是,如果無法保證主備間任何時刻完全一致,那么當有持續不斷的更新時,任何時刻的換主都是無法保證強一致的.
傳統流派另外一個分支就是將MySQL本地磁盤換成更高可靠性的SAN,當MySQL主機故障時,將SAN掛接到備機上提供服務.而當SAN故障時怎么辦?當需要跨機房部署時怎么辦?
意識到傳統流派的局限性,新出了Galera和MySQL Group Replication等.除了宣稱提供強一致性和高可用性外,還支持master-master多點寫入等誘人新特性.
世界上目前已知的經過理論證明和實際檢驗的一致性算法屈指可數:兩階段提交two-phase commit (2PC)、Paxos[4]、Raft[5]、Zookeeper Atomic Broadcast (ZAB)[3]、Viewstamped Replication[5]等.2PC雖然可以保證一致性,但在主機故障時無法工作,存在可用性問題.目前被工業界廣泛認可和應用的是Paxos和Raft,2PC一般在前兩者幫助選主下使用.這里的一個小建議就是:如果一個分布式系統宣稱支持線性一致性級別的強一致和高可用,請先檢查它使用的一致性算法.如果是新算法,請檢查它的形式化證明或者邏輯證明.
因此,為支持線性一致性和高可用,同時完全兼容MySQL,我們在MySQL的基礎上應用Paxos,設計和開發了PhxSQL.
從實際需求出發,除了前述強一致、高可用、完全兼容MySQL這3個明顯、必須的設計原則,我們還提出以下3原則.
這可能是明顯區別PhxSQL和其它方案的一個特點.一個經過邏輯證明的模型才是可靠的,一個建立在可靠模型基礎上的系統也才是可信賴的.PhxSQL一致性模型建立在兩個前提上:
在這兩個前提下,PhxSQL的一致性模型通過Paxos,使得主機寫入Paxos的binlog流水與備機從Paxos里拉取的binlog流水一致,從而保證MySQL數據的一致性.詳細證明過程我們將另外提供.模型和證明過程都很簡單,大家在讀完源碼后也可以嘗試:).
但即使模型正確,PhxSQL正確實現了這個模型嗎?用通俗的話講,沒有bug.碼農都知道這是個巨大的挑戰.從一個算法和模型到正確的實現之間差距是巨大的.例如,正確實現Paxos挑戰就很大[7].為了盡量減少bug,我們選擇了簡單和易理解同時應用廣泛的Paxos作為一致性協議.為了實現一個“生產”級別的Paxos,三位主要碼農各自獨立實現了Paxos,在各自測試完正確性后,三套Paxos之間作為一組Paxos的獨立節點互操作檢驗正確性,最后再集體實現一個發行版本PhxPaxos[21]!除了單元測試、系統測試外,測試環境還隨機高頻率獨立重啟機器、對網絡包進行亂序、延遲、重復等以對系統進行充分測試.
有讀者可能問,Paxos慢且網絡延遲大,PhxSQL為什么不實現一個“優化”版?Paxos有各種版本,例如Fast Paxos[19]、EPaxos[20].但這些都是Paxos,遵循Paxos的基本操作,所作的改變,都做了嚴格的形式化或者邏輯證明.PhxPaxos嚴格遵照Paxos算法[4]實現,沒有做任何改變或者“優化”.PhxPaxos的正常寫操作的網絡延遲是一個網絡RTT,已經是任何算法理論上能達到的最快速度.
現在,對于PhxSQL來說,切換主機是一件很平常和容易的操作,就像往MySQL里插入一條數據一樣平常和容易.
MySQL是個巨大的快速演進的生態系統,保證PhxSQL中的MySQL與官方MySQL的兼容性與可升級性是必須的.這使得MySQL應用可以快速遷移到和運行在PhxSQL上.這也使得PhxSQL可以迅速響應官方MySQL的升級,將PhxSQL中的舊版本MySQL升級到新的官方MySQL,從而獲得新的特性、性能、穩定性、和安全性提升.
這就要求PhxSQL中的MySQL對官方MySQL改動盡量少.實際上,PhxSQL版MySQL只更改了三個小地方:修改了binlog插件接口中一個函數的參數;在MySQL啟動時新增了一個插件函數用于檢查MySQL本地的binlog文件,在MySQL協議中透傳了真正的客戶端IP以兼容授權功能(如果應用不需要可以不修改).這幾個改動是如此小,且涉及的是幾乎穩定不變的流程,使得PhxSQL中MySQL跟隨官方MySQL升級可以無縫完成.實際上,我們正和MySQL社區溝通,希望把這幾處修改并入官方版本,從而使得PhxSQL以后可以完全使用官方版本MySQL,也使得更多人可以方便采用PhxSQL.
(a)
(b)
圖 2:PhxSQL對MySQL的關鍵修改.(a)是MySQL.(b)是PhxSQL中的MySQL.PhxSQL修改了after_flush這個函數的參數,新增了在MySQL啟動時調用的before_recovery這個函數.
也正是因為這個原因,我們沒有因為可以減少模塊個數而把PhxSQLProxy、PhxBinlogSvr放到MySQL進程內.為了保證和應用最廣泛的MySQL單機版兼容,也沒有在事務層和存儲層介入或修改.
在滿足要求的前提下,簡單的架構有很多好處,例如開發、維護、診斷、維護、可靠性等等都變得容易.PhxSQL只有3+1個模塊.PhxSQL中的MySQL是必須的.PhxBinlogSvr負責全局binlog存儲和同步、選主、集群成員管理等關鍵功能.在很多MySQL主備集群方案中,使用Zookeeper、etcd、心跳檢測、Agent等承擔選主的功能.PhxSQLProxy則作為傳統MySQL client訪問PhxSQL中MySQL服務的代理,使得PhxSQL的換主操作對于傳統MySQL client透明.在其它集群方案中,一般也是通過代理MySQL proxy、或者虛擬網關VIP,向傳統MySQL client屏蔽集群的換主操作,提供透明訪問.可選模塊是PhxSQL client lib,它修改了MySQL client庫中的連接初始化函數,允許傳入一個集群的PhxSQLProxy列表,從而在一個PhxSQLProxy沒有響應時、自動訪問其它可用PhxSQLProxy,進一步提高可用性.開發人員可以直接鏈接PhxSQL client lib.
PhxSQL的部署和運維都很簡單.在部署時,只要在目標機各自裝好PhxSQL,在配置中指定集群的機器的IP列表,PhxSQL即可運行.換主這個操作已經從運維層面轉移到PhxSQL正常的工作流程.通常MySQL集群中換主后可能需要人肉檢查數據一致性、人肉“閃回”(這可能違反一致性保證,導致“幻讀”);無法”閃回“導致必須清除某臺MySQL,重新拉取數據備份,和追流水等.這些耗時、繁重、易錯的操作在PhxSQL中已經完全不需要.
至于熱升級和熱變更集群成員更簡單.PhxSQL支持rolling-update,可以逐步升級每臺機器.變更集群成員是指往集群添加機器、撤出機器、和替換機器(原子操作).在保證強一致和高可用前提下,熱變更(不停服變更)是非常困難的.PhxSQL通過在Paxos中實現成員變更解決了這個難題.PhxSQL提供了一個變更操作命令.當在新機器安裝和啟動PhxSQL后(要求MySQL已經加載一份較新的數據備份),可以在現有集群中一鍵將新機器引入、剔除一臺舊機器、或者同時做兩者.這三種操作都是原子操作!新機器會自動追流水.想想看,相當于Zookeeper支持熱變更成員,是不是很令人激動的特性?
PhxSQL由于在同步層使用Paxos,天然支持多數據中心、多機房部署,兩地三中心這種部署更是不在話下.對于PhxSQL來說,多數據中心和多機房部署與機房內部署沒有區別.PhxSQL的性能取決于多數派機器之間的網絡延遲.
作為熱愛技術的碼農,我們相信開源的技術可以使得這個世界更美好.從我們日常開發使用的Emacs/Vim、GCC、GDB,間接為大眾提供社交、電子商務、信息服務的Linux、Apache、MySQL、PHP,到大眾每日使用來溝通和娛樂的Android等,開源是整個互聯網的基石,為全世界提供許多關鍵不可或缺的基礎服務.我們充分享受了開源帶來的技術進步、經濟發展、和社會前進,我們也希望開源的PhxSQL可以回饋社區,幫助更多有需要的人.
另外,我們希望通過開源更好地改進PhxSQL.我們歡迎技術性討論和志愿者提交修改.我們承諾開源的PhxSQL會一直更新.除了一些和內部運維支撐系統進行集成的功能(PhxSQL把這些功能抽象成插件,我們針對內部運維支撐系統實現了這些插件),開源版和內部版本將保持一致.
在一個不完美的世界里,完美是不存在的.我們很坦誠指出PhxSQL存在的兩個局限:
由于MySQL的innodb引擎不支持DDL回滾,如果主機在innodb已經commit這條DDL命令,但是這條命令的binlog還沒到達PhxSQL的攔截點前宕機,則這條DDL binlog會在全局binlog中缺失,從而備機也不會收到這條binlog.而為了保證線性一致性、serializable級別事務隔離、及“最小侵入MySQL”原則,我們也不想修改MySQL源碼,提前截獲DDL命令.考慮到DDL命令頻度較低,我們后續準備在PhxSQLProxy加入檢查和后續審計告警.也歡迎大家提出更好方案.
為了保證線性一致性,對于要求讀取最新數據的請求(通過ReadWritePort發起的讀請求)也將失??;需要等至少一臺備機追完流水,被提升為主機才能響應讀取最新數據的請求.對于不需要讀取最新數據的請求(通過ReadonlyPort發起的請求),可以從任意備機執行,但不保證線性一致性.(注意:PhxSQL保證無論MySQL主機流水領先MySQL備機多少,MySQL主機binlog流水和全局binlog流水是一致的,不會導致數據丟失和破壞線性一致性.)
MySQL備機追流水落后是基于binlog復制這種模式的一個潛在問題.事實上,不僅MySQL主備,任何一個多副本系統,只要每個寫操作不等待所有副本返回,都會出現類似的有些副本落后的問題;而那些等待所有副本返回的模式,在耗時和可用性方面又存在問題.可喜的是MySQL 5.7版本實現了并行復制機制,顯著地提高了備機追流水的性能.PhxSQL將很快支持MySQL 5.7,對于寫入請求量很大的場景也可以很大程度上避免備機追流水落后的情況.
談完why,敬請期待《PhxSQL設計和實現哲學》的下章:why not,即我們為什么不支持若干特性,例如多主多寫和分庫分表,及與Galera和MySQL Group Replication的比較等.
謝謝閱讀!
參考
1. M.P. Herlihy and J. M. Wing. Linearizability: a correctness condition for concurrent objects. ACM Transactions on Programming Languages and Systems (TOPLAS), Volume 12 Issue 3, July 1990, Pages 463-492.
2. L. Lamport. How to make a multiprocessor computer that correctly executes multiprocess programs. IEEE Trans. Computer. C-28,9 (Sept. 1979), 690-691.
3. P. Hunt, M. Konar, F. P. Junqueira, and B. Reed. ZooKeeper: wait-free coordination for Internet-scale systems. USENIXATC’10, 2010.
4. L. Lamport. Paxos Made Simple. ACM SIGACT News (Distributed Computing Column) 32, 4 (Whole Number 121, December 2001) 51-58.
5. D. Ongaro and J. Ousterhout. In search of an understandable consensus algorithm. USENIX ATC ’14, 2014.
6. B. M. Oki and B.H. Liskov. Viewstamped replication: a New primary copy method to support highly-available distributed systems. PODC’88, 8-17, 1988.
7. T. Chandra, R. Griesemer, and J. Redstone. Paxos made live – an engineering perspective. PODC’07, 2007.
8. J. C. Corbett, J. Dean, M. Epstein, and etc. Spanner: Google’s Globally-Distributed Database. OSDI’12, 2012.
9. F. Pedone, R. Guerraoui, and A. Schiper. The database state machine approach. Journal of Distributed and Parallel Databases and Technology, 14:71–98, 2002
10. V. Zuikeviciute and F. Pedone. Revisiting the database state machine approach. VLDB Workshop on Design, Implementation, and Deployment of Database Replication. 2005.
11. http://galeracluster.com/documentation-webpages/certificationbasedreplication.html. Visited at 2016/9/5.
12. https://en.wikipedia.org/wiki/Snapshot_isolation. Visited at 2016/9/5.
13. Y. Amir, L. E. Moser, P. M. Melliar-smith, D. A. Agarwal, and P. Ciarfella. The totem single ring ordering and membership protocol. ACM Transactions on Computer Systems. 13 (4): 311–342.
14. http://downloads.mysql.com/presentations/innovation-day-2016/Session_7_MySQL_Group_Replication_for_High_Availability.pdf. Visited at 2016/9/5.
15. http://galeracluster.com/documentation-webpages/architecture.html. Visited at 2016/9/5.
16. http://corosync.github.io/corosync/. Visited at 2016/9/5.
17. http://www.spread.org/. Visited at 2016/9/5.
18. http://galeracluster.com/documentation-webpages/isolationlevels.html. Visited at 2016/9/5
19. L. Lamport. Fast Paxos. Technical Report, MSR-TR-2005-112.
20. I. Moraru, D. G. Andersen, and M. Kaminsky. There is more consensus in egalitarian parliaments. SOSP’13, 2013.
21. https://github.com/tencent-wechat/phxpaxos.
22. http://mp.weixin.qq.com/s?__biz=MzI4NDMyNTU2Mw==&mid=2247483783&idx=1&sn=a2d6e589f1f591ded7703eb74aefccbe. Visited at 2016/9/5.
文:mingchen
文章出處:微信后臺團隊
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/4426.html