mysql分佈式性能優化

上面已經介紹了主從的方式,在這裏完善一下。

主從分佈的優點是實現了備份和讀寫分離,master只需要專門負責寫操作,讀操作交給slave來執行,然後主從數據庫通過bin_log來異步更新,當然這樣也會有一個數據不同步的情況,那可以改成同步的嗎?當然,mysql有一個半同步的方式,當寫請求來到master上之後,必須保證至少一臺slave更新了數據,纔會返回寫成功的信號,當然這種情況下,對於效率會有一些破壞,所以一般例如支付場景之類的必須保證數據的可以用這種方式。對於數據不是那麼敏感的不需要用這種方式。

多主多從

對於上面的單主單從的方式,只是分散了讀寫的壓力,但是針對寫並沒有做什麼優化,於是有了多主多從。

多從比較好理解,多主其實就是數據分片的概念,一條數據只會在一個主機中。

如何進行數據分片?我們可以採用hash+mode分片。當有多臺master的時候,傳來一個insert命令,那麼我們需要有一層來決定路由到哪個master上。舉個例子:我們需要確定用哪個字段來分片,例如id,我們可以對id進行hash(數字格式的也可以不做),用生成的字符串最後一位進行取模,例如有2臺,那麼就取模2,得出的數就對應那臺master。自然的,讀請求也是hash+mode的方式來決定是哪臺master。

接下來說一下分片的維度,也就是根據什麼樣的規則進行分片。我們之所以做分庫分表,就是爲了減緩插入和查詢的壓力,但如果一次請求涉及到了多個庫,且不說查詢一致性,單說查詢的消耗,需要橫跨多個數據庫的節點,那顯然是不划算的。因此對於分片的原則,就是一次請求儘可能全部命中在一個數據庫上。基於這個原則,我們有兩個維度:固定路由位、時間自增分片。固定路由位就是我們上面說的,根據id去取模然後路由到不同的節點上。對於時間自增,顧名思義,例如每隔一年放到一個庫中。

另外還有一個概念就是數據分片冗餘。舉個例子,一個用戶查自己的一些記錄,那麼根據id就可以定位到相對的路由位上進行查詢,而如果是一個商戶,那麼他的用戶可能在不同的分片上,那麼他就需要橫跨所有的路由位來進行查詢,這個情況我們就需要做數據分片的冗餘。

上圖中,當請求發送一個insert後,master1以user id記錄到這條數據,同時通過MQ發送一條消息給另一個應用中,應用受到該消息後以business id的方式存到master2中,這樣當用戶查詢的時候,就去查master1,商戶查就查master2即可。當然也可以不用MQ,用bin_log,當然肯定不會有MQ好。

接下來說說分庫的擴展,一旦拓展庫以後,相對的mode的hash也會發生變化,這也就需要我們進行數據遷移,那麼對於數據遷移,我們有幾種方案:mod位數據遷移、彈性自增。重點講一下彈性自增,老數據不變,新數據放到別的庫中,例如上圖master1需要發生擴展,那麼我們訪問的時候可以以時間爲條件進行路由,例如2019年的都只訪問master1,2020年和之後的用新的路由算法進行路由。

最後說一下一致性原理,在單機狀態下,mysql遵從acid,自然不用擔心一致性,但在分佈式環境下,一致性就變的非常需要注意了。對於一致性可以分爲:強一致性、弱一致性、最終一致性。強一致性:數據庫(或集羣)對外是完完全全一致的,最典型的就是acid的事務,要麼全部成功,要麼全部失敗。弱一致性:例如上圖,通過MQ進行同步,那麼難免會有master1和master2庫不一致的時候,這就是弱一致性。最終一致性:還是上圖,儘管master12的數據會有不同步的情況,但是由於MQ的事務性消息,最終終會一致,這就是最終一致性。那如果我想進行強一致性怎麼做?二階段提交,犧牲可用性來保證。

在分佈式的情況下,我們不追求ACID,而是追求cap理論(c:一致性,a:可用性,p:分片性)。在分佈式的環境下,c和a只可得兩者,不可得三者。這也就衍生出了base理論(basic avaliable:基本可用,s:軟狀態(瞬時狀態,例如上圖用戶下單,用戶可看到,商戶看不到時),e:最終一致性)。

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