張旭剛,李東輝,俞俊,朱廣新,鄭磊
?
基于zookeeper和強一致性復制實現(xiàn)MySQL分布式數(shù)據(jù)庫集群
張旭剛,李東輝,俞俊,朱廣新,鄭磊
摘 要:目前MySQL數(shù)據(jù)庫間的復制技術(shù)主要有異步、半同步、同步等,這幾種技術(shù)存在各自的局限性和適用場景,很難滿足國家電網(wǎng)業(yè)務對分布式事務和性能的要求。結(jié)合國內(nèi)外先進的框架和技術(shù),利用zookeeper實現(xiàn)MySQL數(shù)據(jù)庫間復制的監(jiān)控和管理,并改進MySQL數(shù)據(jù)庫的線程池,參考半同步技術(shù)模型實現(xiàn)數(shù)據(jù)庫間強一致性復制,融合以上兩種技術(shù)實現(xiàn)復制在毫秒級、高可靠和高性能的MySQL分布式數(shù)據(jù)庫集群。
關(guān)鍵詞:MySQL;zookeeper;強一致性
MySQL的復制模式有異步、半同步、同步等模式。在MySQL發(fā)展的早期,采取異步復制技術(shù),由于主數(shù)據(jù)庫只管把Binary Log發(fā)出去,而不關(guān)心從數(shù)據(jù)庫是否收到,主從數(shù)據(jù)庫間的數(shù)據(jù)不一致非常嚴重,通常是把從數(shù)據(jù)庫作為一種容災和備份方案。到MySQL5.5后,提供了半同步模式,確保必須收到一個從數(shù)據(jù)庫的應答才讓事務在主數(shù)據(jù)庫中提交,若備機應答超時,強同步會自動退化成異步模式,這種模式適用于局域網(wǎng),當跨數(shù)據(jù)中心時,時延較大,通常會工作在異步模式下,而且主數(shù)據(jù)庫等待從數(shù)據(jù)庫的應答,影響主數(shù)據(jù)庫的性能。除了異步和半同步模式,還有同步集群方案,主要有MySQL NDB Cluster和MariaDB Galera Cluster,MySQL NDB Cluster基于全內(nèi)存,只支持Read Committed事務隔離級別,需要把引擎Innodb為NDB,需要高速網(wǎng)絡環(huán)境支持,而MariaDB Galera Cluster維護和管理復雜,在跨數(shù)據(jù)中心時,性能下降比較大。
為解決上述異步和半同步復制的缺陷,同步復制在跨數(shù)據(jù)中心時的性能降低問題,本文提供一種強一致性主從數(shù)據(jù)庫復制方案,并通過zookeeper監(jiān)控和管理主從數(shù)據(jù)復制的一致性、主從數(shù)據(jù)庫的切換、服務器負載等,實現(xiàn)一種高性能、高可靠、易管理的分布式數(shù)據(jù)庫集群。
1.1 Zookeeper介紹
Zookeeper是一個分布式的協(xié)調(diào)服務,為分布式應用提供統(tǒng)一命名服務、狀態(tài)同步服務、集群管理、分布式應用配置項的管理等,由2n+1(n>=1)服務器節(jié)點組成,這些節(jié)點中有一個主節(jié)點(leader),leader是通過leader selection自動地從
服務器節(jié)點中選舉出來,其他節(jié)點角色為follower或observer。Zookeeper提供了一個類似于標準文件系統(tǒng)目錄結(jié)構(gòu)的層次化的命名空間(hierarchal namespace)。如圖1所示:
圖1 層次化的命名空間
hierarchal namespace中的每一個節(jié)點都被稱為 znode。Znode是組成hierarchal namespace的基本單位。在源碼中對應于類DataNode,其維護著節(jié)點用戶數(shù)據(jù)、父節(jié)點和子節(jié)點集合,以及本節(jié)點狀態(tài),用戶可以在hierarchal namespace中創(chuàng)建znode,將數(shù)據(jù)保存在znode中,并監(jiān)聽znode的狀態(tài)變化,Zookeeper會保證client對znode的操作是順序一致性。
1.2 Zookeeper結(jié)構(gòu)
Zookeeper服務器節(jié)點的實現(xiàn)可以分成兩部分:一部分是處理與客戶端交互,實現(xiàn)客戶端對zookeeper的hierachal namespace的各種操作;另一部分是作為zab算法(paxos算法的zookeeper實現(xiàn))的參與者(leader、follower、observer3種角色的其中一種),實現(xiàn)具體的算法邏輯。
Zookeeper服務器的hierachal namespace、znode、客戶端與服務器連接、以及客戶端可以監(jiān)聽服務器的znode狀態(tài)的watch機制之間的元數(shù)據(jù)關(guān)系如圖2所示:
圖2 Zookeeper 組件關(guān)系圖
Zookeeper使用Trie樹 來實現(xiàn)了hierachal namespace,由PathTrie這個類來完成。為了實現(xiàn)從路徑到znode的映射,zookeeper在內(nèi)存中維護了一個znode的hashmap,key為znode在hierachal namespace上的路徑,value為znode對象,znode在zookeeper源碼中由DataNode這個類實現(xiàn)。為了實現(xiàn)client監(jiān)聽znode的狀態(tài)變化,zookeeper將與客戶端的連接和hierachal namespace的節(jié)點路徑進行映射,WatchManager這個類就是用于維護這個映射關(guān)系的,其中NIOServerCnxn是zookeeper服務器與client的一個socket連接;為了監(jiān)聽Znode的目錄結(jié)構(gòu)的變化和數(shù)據(jù)變化,zookeeper使用了兩個WatchManager,分別用來監(jiān)聽namespace的目錄結(jié)構(gòu)和數(shù)據(jù)的變化。
在paxos算法中有3種角色,分別是提案者,接受者和學習者,與在zookeeper中的3種節(jié)點類型對應,即leader、follower和observer3種類型的節(jié)點,其中observer節(jié)點只能學習已經(jīng)批準的提案,而不會參與到提案的投票過程中,這個角色的設定是為了保證提案選舉的性能不會隨著zookeeper集群規(guī)模擴大而降低。角色間的信令交互如圖3所示:
圖3 角色交互圖
基于zookeeper實現(xiàn)的MySQL強一致性復制集群,主要由zookeeper、agent和MySQL等組件組成,zookeeper作為系統(tǒng)的協(xié)調(diào)器,監(jiān)控和管理系統(tǒng)資源,agent部署在MySQL上,負責向Scheduler上報MySQL實例的狀態(tài),包括實例的可用性、復制的一致性、服務器負載等,由mysqlreport和mysqltransfer兩個模塊構(gòu)成,mysqltransfer用于自動擴容,mysqlreport用于上報心跳信息、資源信息??傮w結(jié)構(gòu)如圖4所示:
圖4 系統(tǒng)結(jié)構(gòu)圖
2.1 主從一致性監(jiān)控
主從數(shù)據(jù)庫的一致性監(jiān)控通常是在從庫上執(zhí)行語句show slave statusG獲取Seconds_Behind_Master參數(shù)的值來判斷,但這個值通常不能反映主從數(shù)據(jù)庫一致性的真實情況。Seconds_Behind_Master是通過比較sql_thread執(zhí)行的event 的timestamp和io_thread復制的 event的timestamp進行比較得到的一個差值。當主庫I/O負載很大或是網(wǎng)絡阻塞,io_thread復制binlog的速度會非常慢或停滯,此時sql_thread一直都能及時應用io_thread的復制,Seconds_Behind_Master的值是0,表示是沒有無延時的,實際主從數(shù)據(jù)一致性延遲非常嚴重。
為解決以上問題,本文通過在主從數(shù)據(jù)庫上創(chuàng)建一張表SysDB.StatusTable,dbagent將當前當前時間戳、ip、端口通過replace into方式寫入SysDB.StatusTable表,mysqlreport默認3秒連接一次mysql,并對sysdb.statustable表進行讀操作,根據(jù)master同步過來的時間、slave寫入的時間進行相減,計算出時間差值作為延遲的時間,將以上獲取的數(shù)據(jù)庫信息寫入zookeeper的hb@IP地址_端口號位置上,寫入信息:{"agentbindport":"57086","autorebuildms":"1","conn_err":
"0","conn_info":"","delay":"0","gtiddelay":"","read_err":" 0","read_info":"","repl":"0","svrtype":"master","ver":"1.0","wri te_err":"0","write_info":""},其中delay值代表主從數(shù)據(jù)復制的延遲,單位為秒,0表示無延遲,結(jié)構(gòu)圖如圖5所示:
圖5 復制一致性設計圖
通過以上方式,能準確獲取主從數(shù)據(jù)庫的一致性延遲,如果延遲超過設置的閾值,則在主庫宕機從庫承擔讀寫角色時,從庫只能讀不能寫。
2.2 資源監(jiān)控
在MySQL分布式集群系統(tǒng)中,有多種系統(tǒng)資源需要監(jiān)控,并根據(jù)結(jié)果做出反應,主要的監(jiān)控資源有CPU的使用率、磁盤使用率、磁盤IO、MySQL數(shù)據(jù)庫狀態(tài)信息等,如圖6所示:
圖6 系統(tǒng)資源監(jiān)控設計圖
放到zookeeper的相關(guān)目錄下,進行統(tǒng)一管理,并通過界面查看各資源信息,進行優(yōu)化。
實際步驟是mysqlreport根據(jù)mysql的my.cnf文件,找到數(shù)據(jù)文件日志和日志目錄, mysqlreport調(diào)用C語言的statfs函數(shù)分析mysql的數(shù)據(jù)文件、binlog文件在磁盤使用情況,mysqlreport獲取只是統(tǒng)計數(shù)據(jù)文件及binlog的根目錄大小,同時mysqlreport連接到mysql通過show global statusG命令獲取Com_select、Com_update、Com_insert、Slow_queries等信息,Mysqlreport默認5秒一次將收集到的數(shù)據(jù)上傳到zookpeeper的rsinfo@IP_端口號目錄下。
通過獲取以上信息,當數(shù)據(jù)庫的資源使用率超過設置閾值時,調(diào)用策略應對,如當CPU使用率超過95%時,進行主從切換,防止數(shù)據(jù)庫宕機。
在分布式數(shù)據(jù)系統(tǒng)中,有一個CAP原理,由三個要素組成,包括一致性(Consistency)、可用性(Availability)和分區(qū)容忍性(Partition tolerance),這3個要素最多只能同時實現(xiàn)兩點,不可能三者兼顧。對于分布式數(shù)據(jù)系統(tǒng),分區(qū)容忍性是基本要求,否則就失去了價值,因此設計分布式數(shù)據(jù)系統(tǒng),就是在一致性和可用性之間取一個平衡。對于大多數(shù)應用系統(tǒng),并不需要強一致性,因而犧牲一致性而換取高可用性,是目前多數(shù)分布式數(shù)據(jù)庫產(chǎn)品的方向。
但在計費、ERP等系統(tǒng)中,對數(shù)據(jù)的一致性要求很高,數(shù)據(jù)庫承受的壓力也很大,在保證可用性和分區(qū)容忍性的同時,盡可能提高數(shù)據(jù)一致性的實時性,使產(chǎn)品具有更廣泛的應用場景。
3.1 MySQL復制技術(shù)的發(fā)展
在MySQL發(fā)展的早期,就提供了異步復制的技術(shù),Mysql 主數(shù)據(jù)庫將自己的Binary Log通過復制線程傳輸出去以后,Mysql 主數(shù)據(jù)庫就自動返回數(shù)據(jù)給客戶端,而不關(guān)系從數(shù)據(jù)庫是否接受到了這個二進制日志,異步復制模型如圖7所示:
圖7 異步復制模型
到了MySQL 5.5版本,google提供了一個半同步半異步的插件,當主數(shù)據(jù)庫在將自己binlog發(fā)給從數(shù)據(jù)庫后,要確保從數(shù)據(jù)庫已經(jīng)接受到了這個二進制日志,才會返回數(shù)據(jù)給客戶端,通過收到一個從數(shù)據(jù)庫的應答來實現(xiàn);當備機應答超時時,強同步就會自動退化成異步模式,復制模型如下圖8所示:
圖8 半同步復制模型
半同步方案相對異步復制,在數(shù)據(jù)的可靠性方面得到了提高,若主數(shù)據(jù)庫故障則最后一個事務,至少在一個從數(shù)據(jù)庫上存在。但在主從數(shù)據(jù)庫跨數(shù)據(jù)中心時,性能非常很低。
除了異步和半同步,還有同步方案,典型的有MySQL NDB Cluster、MariaDB Galera Cluster等,MySQL NDB Cluster基于全內(nèi)存,只支持Read Committed事務隔離級別,需要把引擎Innodb改為NDB,需要高速網(wǎng)絡環(huán)境支持,應用范圍窄。MariaDB Galera Cluster 是一套在mysql innodb存儲引擎上面實現(xiàn)multi-master及數(shù)據(jù)實時同步的系統(tǒng)架構(gòu),業(yè)務層面無需做讀寫分離工作,數(shù)據(jù)庫讀寫壓力都能按照既定的規(guī)則分發(fā)到各個節(jié)點上去,具有如下特點:
(1)同步復制;
(2)多主的拓撲結(jié)構(gòu),可以認為沒有備機的概念;(3)可對集群中任一節(jié)點進行數(shù)據(jù)讀寫;
(4)自動成員控制,故障節(jié)點自動從集群中移除;(5)自動節(jié)點加入;
(6)真正并行的復制,基于行級;
(7)每個節(jié)點都包含完整的數(shù)據(jù)副本。
MariaDB Galera Cluster在功能實現(xiàn)上非常完美,但管理和維護困難,在跨數(shù)據(jù)中心時,性能損耗較大。
3.2 性能分析
如圖9所示:
圖9 同步模式對比
從上圖9可以看出,在跨數(shù)據(jù)中心時,半同步、同步復制的性能損耗非常嚴重,這與MySQL前期版本采用的每個連接一個線程的模型有關(guān),該模型的優(yōu)勢在于開發(fā)特別簡單,線程內(nèi)部都是同步調(diào)用,只要不訪問外部接口,支撐每秒上千的請求量也夠用,因為大部分情況下IO是瓶頸。不過隨著當前硬件的發(fā)展,尤其是SSD、FusionIO的出現(xiàn),IOPS從每秒200+發(fā)展到每秒幾十萬甚至百萬次,IO基本上不再是瓶頸,如再采用這套模型并采用阻塞的方式調(diào)用延遲較大的外部接口,則CPU會阻塞在等網(wǎng)絡應答上了,性能自然下降。
3.3 強一致性復制實現(xiàn)
在MySQL5.6企業(yè)版和MariaDB、Percona中引入了線程池,優(yōu)勢在于線程處理的最小單位是statement(語句),一個線程可以處理多個連接的請求。這樣,在保證充分利用硬件資源情況下(合理設置線程池大小),可以避免瞬間連接數(shù)暴增導致的服務器抖動,線程池的實現(xiàn)模型如圖10所示:
圖10 線程池模型
每一個綠色的方框代表一個group,group數(shù)目由thread_pool_size參數(shù)決定。每個group包含一個優(yōu)先隊列和普通隊列,包含一個listener線程和若干個工作線程,listener線程和worker線程可以動態(tài)轉(zhuǎn)換,worker線程數(shù)目由工作負載決定,同時受到thread_pool_oversubscribe設置影響。此外,整個線程池有一個timer線程監(jiān)控group,防止group“停滯”。
一個連接一個線程與線程池的對比如圖11所示:
圖11 線程模型對比
從上面的分析可知,半同步半異步是較輕量級的高一致性容災方案,但是受限于已有的同步網(wǎng)絡模型,CPU利用不起來。如果在線程池基礎(chǔ)之上做一些修改,參考半同步的思路就可以實現(xiàn)一個高性能的強同步方案。
目前的做法是采用與Linux內(nèi)核處理中斷的思路:將上面線程池模型的第三個環(huán)節(jié)(執(zhí)行SQL的邏輯)拆成2個部分:
(1)上半部分,任務執(zhí)行到寫binlog為止,然后將會話保存到session中,接著執(zhí)行下一輪循環(huán)去處理其他請求了,這樣就避免讓線程阻塞等待應答了;
(2)然后MySQL自身負責主備同步的dump線程會將binlog立即發(fā)送出去,備機的io線程收到binlog并寫入到relay log之后,再通過udp給主機一個應答;
(3)在主機上,開一組線程來處理應答,收到應答之后找到對應的會話,執(zhí)行下半部分的commit,send應答,綁定到epoll等操作。綁定到epoll之后這個連接又可以被其它線程檢測到并執(zhí)行了。
流程圖如圖12所示:
圖12 強一致性復制流程圖
該同步方案完全獨立于原生的主從復制系統(tǒng),屬于新開發(fā)功能,同時強同步的概念是從整個MySQL分布式數(shù)據(jù)庫集群上來看的,保證數(shù)據(jù)在切換、或進行讀寫分離時數(shù)據(jù)的一致性。當主備數(shù)據(jù)延遲超過了一定的閥值時(可配置),就不會發(fā)生主從切換、進行讀寫分離操作,與半同步方案的差別:
(1)當備機應答超時的情況下,半同步就不會自動退化成異步模式;
(2)線程池優(yōu)化,在主機上開啟單獨的多線程來處理從機寫入relaylog后的應答實現(xiàn)連接的復用,提高效率。
基于zookeeper與強一致性復制的分布式數(shù)據(jù)庫集群,易于部署、管理和維護,數(shù)據(jù)一致性實時性高,可靠性得到保證,已在國網(wǎng)多個業(yè)務系統(tǒng)中應用,實踐效果良好。但也存在需要改進和擴展的方向,如zookeeper在使用過程中存在占用內(nèi)存過高的現(xiàn)象,同時擴展dbagent功能模塊,實現(xiàn)彈性計算,如容量按需自動收縮、數(shù)據(jù)在線搬遷等,是今后研究和設計的方向。
參考文獻
[1] Flavio Junqueira,Benjamin Reed.ZooKeeper: Distributed Process Coordination[M].O'Reilly Media,2013,12,210-333.
[2] 曾大聃,周傲英.Hadoop 權(quán)威指南(第二版-中文版)[M].北京:清華大學出版社,2011(1):88-89.
[3] 鄧鵬,李枚毅,何 誠.Namenode 單點故障解決方案研究[J].計算機工程,2012, 38(21):25-44.
[4] PatrickHunt,MahadevKonar,F(xiàn)lavioPJunqueira,BenjaminReedZooKeeper:Wait-freecoordinationforIntem etscalesystemsUSENIXAnnualTechnologyConference[C] .2011:2-3.
[5] 葉謙.Zookeeper初步調(diào)研報告[J].計算機技術(shù)與發(fā)展,2011,7(7):15-25.
[6] 倪超.從Paxos到Zookeeper[M].北京:電子工業(yè)出版社,2015:43-61.
[7] Marco Aiello.leader_election[M].Distributed system.2011,1:5-9.
[8] 雷明.fast paxos算法與Zookeeper leader選舉源代碼分析[J].計算機技術(shù)與發(fā)展,2015.3,3(04):3-20.
[9] ZooKeeper: Because Coordinating Distributed Systems is a Zoo[J/OL]。Science,2014,3 (http://zookeeper.apache.org/doc/r3.4.6/ /).
MySQL Distributed Database Cluster Based on Zookeeper and Strong Consistency
Zhang Xugang, Li Donghui, Yu Jun, ZhuGuangxin, Zheng Lei
(Information System Integration Company, Nari Group Cooperation, Nanjing 210000, China)
Abstract:At present, the replication technology between MySQL mainly contains asynchronization, semi-synchronization and synchronization. These technologies have respective limits and suitable scenarios, and that make them hardly meet the requirements for distributed affairs and performances of State Grid Corporation of China. This paper uses zookeeper to realize the monitoring and management of replication between MySQL databases and improves the thread pool of MySQL databases, combining with the advanced framework and technology of home and abroad. It consults the semi-synchronization model to realize the strong consistence replication between the databases, and it also fuses the two above technologies to realize the replication on the millisecond, high reliability and performance MySQL distributed database groups.
Key words:MySQL; Zookeeper; Strong Consistency
收稿日期:(2015.10.13)
作者簡介:張旭剛(1979-),南京南瑞集團公司信息系統(tǒng)集成分公司,助理工程師,研究方向:計算機應用技術(shù),南京,211000李東輝(1970-),南京南瑞集團公司信息系統(tǒng)集成分公司,高級工程師,研究方向:電力系統(tǒng)通信信息,南京,211000 俞 ?。?978-),南京南瑞集團公司信息系統(tǒng)集成分公司,高級工程師,研究方向:電力系統(tǒng)通信信息,南京,211000朱廣新(1981-),南京南瑞集團公司信息系統(tǒng)集成分公司,工程師,研究方向:模式識別與智能系統(tǒng),南京,211000 鄭 磊(1972-),南京南瑞集團公司信息系統(tǒng)集成分公司,助理工程師,研究方向:電力系統(tǒng)通信信息,南京,211000
文章編號:1007-757X(2016)01-0077-04
中圖分類號:TP393
文獻標志碼:A