MySQL架構設計談:從開發規範、選型、拆分到減壓(二)

2、運維規範

(1)SQL審覈

SQL評審這部分工作相信讓很多的DBA同學都叫苦不迭,人肉審覈不僅效率低下,容易出錯,對DBA的自身發展也非常不利,難道我們來上班就是爲了審覈SQL的嗎?在經過了一段痛苦的人肉審覈之後,我們接入了去哪兒網開源的Inception,並根據自身的業務特點做了一些調整。當然現在開源的SQL評審軟件已經很多了,大家可以自由選擇,也可以自行開發。

在審覈與執行上線DDL語句的時候,要注意MySQL官方原生Online DDL和Percona公司的pt-osc之間的一些差異,例如pt-osc在執行時每次都要copy全表,相對來說比較慢,好處是不鎖表,並且有完善的條件檢測和延時負載策略控制。官方Online DDL雖然官方也一直在改進,但生產環境使用還不是很完美,尤其要注意執行過程中容易導致MDL鎖。官方Online DDL也有優於pt-osc的地方,比如增刪索引,重命名列等,如下圖所示。

(2)權限控制

Mysql從5.6開始,逐步完善了權限系統,比如MySQL5.6可以安裝檢查密碼強度的插件,5.7開始增加了密碼過期機制、賬戶鎖定等功能,對SSL這一塊也做了一些優化,8.0版本增加了角色的功能,權限系統已經逐步在向Oracle數據庫靠攏了。在日常運維中,也可以使用pt-show-grants工具提高權限審查的力度。應用程序賬號應只賦予SELECT、INSERT、UPDATE權限,DELETE的邏輯改用UPDATE實現,並啓用sql_safe_updates選項。

另一個有效控制權限的方法就是SQL堡壘機,早期我們通過改造MyWebSQL實現,在Web版客戶端的基礎上加入了一些資源控制策略、審計、語法校驗等功能。後續又使用Python開發了功能更完備的SQL堡壘機,同時支持MySQL、Oracle、Greenplum等數據庫。

SQL堡壘機不僅可控制公司內部人員的數據庫權限,追溯各類人員對數據庫的操作,也能避免大查詢或全表更新的情況發生,支持審計需求,整體運維質量提升了一個臺階。

(3)MySQL版本選擇MySQL社區版,用戶羣體最大MySQL企業版,收費Percona Server版,新特性多,和MySQL社區版最接近MariaDB版,國內用戶暫時不多選擇優先級:MySQL社區版> Percona Server > MariaDB > MySQL 企業版

對於版本選擇這件事,建議大家還是跟進官方社區版比較好,目前比較穩定的版本是MySQL5.6,推薦大家使用。有特殊需求的話再選擇MySQL5.7、PXC、TiDB、TokuDB等數據庫。二、MySQL高可用架構選型

MySQL高可用方面,目前業界主流依然是基於異步複製的技術,例如Keepalived、MHA、ZooKeeper等,要求數據強一致的場景逐步開始使用分佈式協議,這方面的典型代表有PXC、Group Replication、TiDB。下面我們就重點來說說keepalived、MHA和PXC這幾種大家用得比較多的架構。

1、keepalived高可用架構

業內使用非常普遍,它部署容易、方便維護,還節省服務器資源。這種架構的一個好處就是在發生切換後,原Master只需重新拉起來即可恢復高可用,不需要過多幹預。擴展起來也方便,可以任意掛載只讀庫和災備庫。但它存在的問題也很明顯,比如Keepalived的檢測機制不完善、有腦裂隱患、數據一致性較弱等等。

還需要注意主從拓撲的設計。如下圖,只讀庫掛到哪個Master比較合適?顯然是M2,其它兩種拓撲在發生切換後都會影響到只讀庫的訪問。

2、MHA

MHA自誕生以來,就得到了業內的廣泛關注,並迅速流行開來。與keepalived相比,MHA最大的優點就是在發生故障切換之後,能自動補齊binlog,最大程度保證數據一致性。從服務器能自動切換,無需人工干預,能非常好的工作在讀寫分離的環境下。基於Perl語言的腳本也非常方便進行二次開發。MHA非常適合讀寫壓力比較大的應用。

但由於MHA在工作時需要配置SSH互信,因此選擇這種架構時內網安全一定要做到位。另外也可以搭配Binlog Server使用。

3、PXC

PXC全稱是Percona XtraDB Cluster,是Percona公司基於Galera協議開發的一個產品。PXC犧牲了CAP裏面的P(Partition Tolerance),保留了C(Consistency )和A(Availability )。這種結構非常適合電商、金融類業務,自PXC和Group Replication出現以後,MySQL徹底掃清了進入金融行業的障礙。

PXC的優勢:同步複製,解決了傳統架構複製延遲和腦裂的問題數據強一致多主複製,每個節點都可以讀寫數據並行複製,多個事務可以並行推送到其他節點高可用,單點故障不影響集羣可用性新節點自動部署與傳統MySQL幾乎完全兼容

使用PXC要注意的問題:不要有大事務木桶效應,集羣性能取決於性能最差的那個節點併發效率有損失網絡要求較高,建議萬兆網絡多點併發寫時鎖衝突、死鎖問題多寫無法擴展,無法解決熱點更新問題

除此之外,還有一類採用DNS/ZooKeeper的高可用架構,這種架構通常都需要自行開發,無通用的方案,比較適合大規模集羣的高可用,這裏我們不過多贅述。

下面簡單回顧一下上述幾種高可用架構:雙Master架構:非常成熟,使用很普遍,要注意延遲和數據的一致性。PXC: 分佈式協議,數據強一致性,併發效率略低,可用性好MHA:各項指標介於M-M和PXC之間,性能無損失,適合讀寫分離架構。

總而言之,沒有最完美的架構,只有最適合的架構。選擇適合自己業務的即可。三、MySQL sharding拆分

接下來是第三個議題,MySQL拆分原則和分庫分表設計。

首先先提一個問題,爲什麼要拆,不拆不行嗎?按照我們的經驗來看,當數據和業務到了一定的規模,都不可避免的要面臨分庫分表的問題。這就好像汽車的發動機一樣,要達到更高的性能,4缸6缸明顯是不夠用的,V8、V12纔是王道。

拆分能解決如下幾個問題:單庫併發較大單庫物理文件太大單表過大,DDL無法接受防止出現性能瓶頸,提升性能防止出現抖動不穩定現象

確定要進行數據庫的拆分了,應該怎麼拆呢?

垂直拆分

優點:拆分簡單明瞭,拆分規則明確應用程序模塊清晰,整合容易數據維護方便易行,容易定位

缺點:表關聯需要改到程序中完成事務處理變的複雜熱點表還有可能存在性能瓶頸過度拆分會造成管理複雜

水平拆分

優點:不會影響表關聯、事務操作超大規模的表和高負載的表可以打散應用程序端改動比較小拆分能提升性能,也比較易擴展

缺點:數據分散,影響聚集函數的使用切分規則複雜,維護難度增加後期遷移較複雜

要先分庫還是先分表?分庫的優點:實現簡單,庫與庫之間界限分明,便於維護,缺點是不利於頻繁跨庫操作,單表數據量大的問題解決不了。分表的優點:能解決分庫的不足點,但是缺點恰恰是分庫的優點,分表實現起來比較複雜,特別是分表規則的劃分,程序的編寫,以及後期的數據庫拆分移植維護。

一巴掌拍板直接選分庫或分表都是不可取的,主要是看需要達到什麼樣的擴展方式,才能決定先分庫還是先分表,根據具體的場景決定。分庫分表的最終目的還是爲了擴展,而且要看拆分的規劃設計是針對哪一層。

上述問題都解決了,該考慮如何實現了,到底是在應用程序中實現,還是使用中間件?個人建議如果是小規模的拆分,直接在程序邏輯中實現即可,大規模的拆分再考慮使用各種中間件。

目前業內已經開源了很多的MySQL中間件產品,例如Atlas、DBProxy、MyCAT、OneProxy、DRDS、Vitess等等,每個中間件都有自己的特點,個別不太成熟的可能會存在一些Bug,選用之前要做好相關的調研與測試工作,上線使用一定要保證自己能hold住。如果要完全貼合自身業務,並且掌控得較好的還是要自行開發。

下面說說我們的拆分經驗。

首先我們先在壓力比較大的數據庫上做垂直拆分,剝離出活動、後臺統計等業務。這一步也是最容易實現的。

接下來,如果是消息類的數據,就基於時間維度進行拆分,單表控制在5-10G,行數控制到500-1000w這個樣子。這個時候我們發現數據庫的性能是比較好的,而且比較好維護。如果是用戶類的數據,就按照Hash或Range進行拆分。這種情況下用這種方法拆分會拆的比較均勻一些。

併發仍然比較高怎麼辦?可以在時間維度拆分的基礎上再按Range或Hash進行拆分。

最後要注意的就是不要過度的拆分,會造成複雜度的上升。Schema設計合理的情況下,10億的數據量也能跑的好好的。個別不關鍵的應用,例如日誌、監控數據等,使用分區表、TokuDB也能抗。拆分對應用層總是有損的。

要做個“懶”DBA。

四、利用NoSQL爲MySQL減壓

最後一個議題,我們聊一聊NoSQL。NoSQL現在遍地開花,應用也很廣泛了,業內用的比較多的主要集中在Redis、MongoDB、Cassandra等NoSQL數據庫上。今天我們主要來說說和MySQL關聯最爲密切的Redis。

爲什麼要使用Redis?數據存儲在內存中,訪問速度快能支持大批量操作及爆發性負載數據結構豐富,有效緩解MySQL壓力協議簡單,支持各種語言的API存儲大量數據無需擔心性能

Redis主要作用還是抗讀的壓力。讀操作先到Redis,Redis中取不到再從MySQL數據庫訪問,從MySQL讀取到數據後,還要回寫到Redis。

使用Redis要注意的幾點:

性能方面,由於Redis完全是基於內存的訪問,性能無需擔心。

在使用Redis時,要注意Cache 和Storage不要混合使用。不要依賴Redis的持久化,持久化這一塊Redis要努力的還很多。另外如果你把Redis拿來做Storage的話,一旦Redis的內存跑滿,那就慘了,所有的Redis連接都會卡着不響應。如果只是把Redis來做cache的話,那問題就不大。

還有諸如緩存穿透、緩存雪崩、熱點key重建時緩存失效這些問題也是重點關注的對象。

如何利用Redis給MySQL加速:

1)利用K/V結構,緩存結果,例如存儲用戶信息、全局排行、統計信息等。

2)利用其豐富的數據結構爲MySQL減壓,例如計數器、排序、Hash(把表映射到Redis中)、消息隊列等。總結

系統架構設計是一個長期總結與進化的過程,講究均衡與取捨。在進行大規模MySQL架構設計的過程中,除了要汲取別人的經驗之外,還要關注各種架構背後的業務場景與架構思想,與自己的實際業務場景相結合,才能設計出一個好的系統架構來。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章