《MySQL架構設計談:從開發規范、選型、拆分到減壓》要點:
本文介紹了MySQL架構設計談:從開發規范、選型、拆分到減壓,希望對您有用。如果有疑問,可以聯系我們。
作者介紹
李輝,原新浪愛彩票運維負責人,常用網名:門牙沒了.曾主導新浪愛彩票的MySQL運維工作.培訓合伙人、資深講師,中國科學院大學在讀研究生(大數據方向),擅長大型項目的關系型數據庫運維和管理,現在在數據庫運維自動化方向研究.
隨著MySQL自身的發展與不斷完善,不知不覺中整個互聯網行業已離不開這個完善又小巧的關系型數據庫,整個生態鏈也已經變得非常成熟,即便是初創企業和傳統企業也可以放心大膽地把數據庫遷移到MySQL上來.在大家和MySQL數據庫愉快玩耍的同時,我來聊聊MySQL架構設計相關的一些話題.
本文大綱:
數據庫規范到底有多重要?有過初創公司經歷的朋友應該都深有體會.規范是數據庫運維的一個基石,能有效地減少數據庫出問題的概率,保障數據庫schema的合理設計并方便后續自動化的管理.
曾經我們花了大半年時間來做數據庫規范化的工作,例如制定數據庫開發指南、給程序員做培訓等,推進的時候也會遇到一些阻力.但規范之后運維質量會有一個質的提升,也增進了DBA的工作效率.
在開發規范方面,我們劃分為開發規范和運維規范兩部分.
表設計的規范:
索引設計的規范:
1)所有表必須有顯式主鍵
2)合理地建立索引
SQL編寫規范:
1)避免在數據庫中進行大量計算任務
2)優化join
3)注重where條件,多用EXPLAIN確認
Schema Review:
1)字符集問題
表字符集選擇UTF8 ,如果需要存儲emoj表情,就改成UTF8mb4
2)Schema設計原則
3)Schema設計目標
整體來說,這部分規范還是很容易遵守的,實現起來也沒有什么難度,就能取得很好的效果.
(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版本選擇
對于版本選擇這件事,建議大家還是跟進官方社區版比較好,目前比較穩定的版本是MySQL5.6,推薦大家使用.有特殊需求的話再選擇MySQL5.7、PXC、TiDB、TokuDB等數據庫.
MySQL高可用方面,目前業界主流依然是基于異步復制的技術,例如Keepalived、MHA、ZooKeeper等,要求數據強一致的場景逐步開始使用分布式協議,這方面的典型代表有PXC、Group Replication、TiDB.下面我們就重點來說說keepalived、MHA和PXC這幾種大家用得比較多的架構.
業內使用非常普遍,它部署容易、方便維護,還節省服務器資源.這種架構的一個好處就是在發生切換后,原Master只需重新拉起來即可恢復高可用,不需要過多干預.擴展起來也方便,可以任意掛載只讀庫和災備庫.但它存在的問題也很明顯,比如Keepalived的檢測機制不完善、有腦裂隱患、數據一致性較弱等等.
還需要注意主從拓撲的設計.如下圖,只讀庫掛到哪個Master比較合適?顯然是M2,其它兩種拓撲在發生切換后都會影響到只讀庫的訪問.
MHA自誕生以來,就得到了業內的廣泛關注,并迅速流行開來.與keepalived相比,MHA最大的優點就是在發生故障切換之后,能自動補齊binlog,最大程度保證數據一致性.從服務器能自動切換,無需人工干預,能非常好的工作在讀寫分離的環境下.基于Perl語言的腳本也非常方便進行二次開發.MHA非常適合讀寫壓力比較大的應用.
但由于MHA在工作時需要配置SSH互信,因此選擇這種架構時內網安全一定要做到位.另外也可以搭配Binlog Server使用.
PXC全稱是Percona XtraDB Cluster,是Percona公司基于Galera協議開發的一個產品.PXC犧牲了CAP里面的P(Partition Tolerance),保留了C(Consistency )和A(Availability ).這種結構非常適合電商、金融類業務,自PXC和Group Replication出現以后,MySQL徹底掃清了進入金融行業的障礙.
PXC的優勢:
使用PXC要注意的問題:
除此之外,還有一類采用DNS/ZooKeeper的高可用架構,這種架構通常都需要自行開發,無通用的方案,比較適合大規模集群的高可用,這里我們不過多贅述.
下面簡單回顧一下上述幾種高可用架構:
總而言之,沒有最完美的架構,只有最適合的架構.選擇適合自己業務的即可.
接下來是第三個議題,MySQL拆分原則和分庫分表設計.
首先先提一個問題,為什么要拆,不拆不行嗎?按照我們的經驗來看,當數據和業務到了一定的規模,都不可避免的要面臨分庫分表的問題.這就好像汽車的發動機一樣,要達到更高的性能,4缸6缸明顯是不夠用的,V8、V12才是王道.
拆分能解決如下幾個問題:
確定要進行數據庫的拆分了,應該怎么拆呢?
垂直拆分
優點:
缺點:
水平拆分
優點:
缺點:
要先分庫還是先分表?
一巴掌拍板直接選分庫或分表都是不可取的,主要是看需要達到什么樣的擴展方式,才能決定先分庫還是先分表,根據具體的場景決定.分庫分表的最終目的還是為了擴展,而且要看拆分的規劃設計是針對哪一層.
上述問題都解決了,該考慮如何實現了,到底是在應用程序中實現,還是使用中間件?個人建議如果是小規模的拆分,直接在程序邏輯中實現即可,大規模的拆分再考慮使用各種中間件.
目前業內已經開源了很多的MySQL中間件產品,例如Atlas、DBProxy、MyCAT、OneProxy、DRDS、Vitess等等,每個中間件都有自己的特點,個別不太成熟的可能會存在一些Bug,選用之前要做好相關的調研與測試工作,上線使用一定要保證自己能hold住.如果要完全貼合自身業務,并且掌控得較好的還是要自行開發.
下面說說我們的拆分經驗.
首先我們先在壓力比較大的數據庫上做垂直拆分,剝離出活動、后臺統計等業務.這一步也是最容易實現的.
接下來,如果是消息類的數據,就基于時間維度進行拆分,單表控制在5-10G,行數控制到500-1000w這個樣子.這個時候我們發現數據庫的性能是比較好的,而且比較好維護.如果是用戶類的數據,就按照Hash或Range進行拆分.這種情況下用這種方法拆分會拆的比較均勻一些.
并發仍然比較高怎么辦?可以在時間維度拆分的基礎上再按Range或Hash進行拆分.
最后要注意的就是不要過度的拆分,會造成復雜度的上升.Schema設計合理的情況下,10億的數據量也能跑的好好的.個別不關鍵的應用,例如日志、監控數據等,使用分區表、TokuDB也能抗.拆分對應用層總是有損的.
要做個“懶”DBA.
最后一個議題,我們聊一聊NoSQL.NoSQL現在遍地開花,應用也很廣泛了,業內用的比較多的主要集中在Redis、MongoDB、Cassandra等NoSQL數據庫上.今天我們主要來說說和MySQL關聯最為密切的Redis.
為什么要使用Redis?
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架構設計的過程中,除了要汲取別人的經驗之外,還要關注各種架構背后的業務場景與架構思想,與自己的實際業務場景相結合,才能設計出一個好的系統架構來.
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/1978.html