1. 程式人生 > >分庫分表,讀寫分離,從理論到實戰

分庫分表,讀寫分離,從理論到實戰

分庫分表,讀寫分離會帶來哪些問題?

前面一篇文章圖解分散式系統架構(看推薦閱讀)大概講了一下分庫分表,以及讀寫分離出現的場景,分庫分表為了解決高併發和海量資料的問題。

分庫後會出現新的問題

  1. 跨庫join問題
    如有2個庫,訂單庫,使用者庫,要查詢買了某件商品的所有使用者資訊
  2. 事務問題
    使用者下訂單的時候需要扣減商品庫存,如果訂單資料和商品資料在一個數據庫中,我們可以使用事務來保證扣減商品庫存和生成訂單的操作要麼都成功要麼都失敗,但分庫後就無法使用資料庫事務了,這時就要用到分散式事務了

分表後也會出現新的問題

  1. join操作
    水平分表後,資料分散在多個表中,如果需要與其他表進行join查詢,需要在業務程式碼或資料庫中介軟體中進行多次join查詢,然後將結果合併
  2. count()操作
    業務程式碼或者資料庫中介軟體對每個表進行count(*)操作,然後將結果相加。或者新建一張表,假如表名為“記錄數表”,包含table_name和row_count兩個欄位,每次插入或刪除子表資料成功後,都更新“記錄數表”
  3. order by操作
    水平分表後,資料分散到多個字表中,排序操作無法再資料庫中完成,只能由業務程式碼或資料庫中介軟體分別查詢每個子表中的資料,然後彙總進行排序

而高併發這個階段,肯定是需要做讀寫分離的,啥意思?因為實際上大部分的網際網路公司,一些網站,或者是 app,其實都是讀多寫少。所以針對這個情況,就是寫一個主庫,但是主庫掛多個從庫,然後從多個從庫來讀,那不就可以支撐更高的讀併發壓力了嗎?

那麼如何實現 MySQL 的讀寫分離?
其實很簡單,就是基於主從複製架構,簡單來說,就搞一個主庫,掛多個從庫,然後我們就單單只是寫主庫,然後從庫讀取bin log進行重放,這樣主庫和從庫資料就一樣,只不過併發量比較高時,會有主從同步延時問題

放個圖理解一下MySQL主從複製的原理,這塊面試經常被問到

在這裡插入圖片描述

總的來說,MySQL複製有三個步驟

  1. 在主庫上把資料更改記錄到二進位制日誌中(Binary Log)中(這些記錄被稱為二進位制日誌事件)
  2. 備庫將主庫上的日誌複製到自己的中繼日誌(Relay Log)中
  3. 備庫讀取中繼日誌中的事件,將其重放到備庫資料之上

現在理論知識都有了,就剩怎麼實現了?本來就是為了實現一個功能,現在好了,單寫讀寫分離,跨庫join,分散式事務,排序操作等就夠你忙的了。

這時候你就應該想起資料庫中介軟體了,它能幫你進行上述操作,把你從複雜的資料處理中解放出來,專注於開發業務程式碼。

資料庫中介軟體能幫你做什麼?

目前國內用的最多的中介軟體就是sharding-jdbc,mycat,別的用的很少,不再介紹

而資料庫中介軟體針對資料來源管理,目前主要有兩種思路

  1. 客戶端模式,在每個應用程式模組中配置管理自己需要的一個(或者多個)資料來源,直接訪問各個資料庫,在模組內完成資料的整合,sharding-jdbc的實現方式
  2. 通過中間代理層來統一管理所有的資料來源,後端資料庫叢集對前端應用程式透明,mycat的實現方式

放兩張圖就能理解區別了
在這裡插入圖片描述

在這裡插入圖片描述

一般的建議是小公司用sharding-jdbc,大公司用mycat,因為維護一套mycat叢集也需要人力,物力。鑑於篇幅限制,本文就介紹一下mycat的基本使用

以一個最形象的例子,讓你明白mycat到底幫你做了什麼?
在這裡插入圖片描述

先介紹一下什麼是分片?簡單來說,就是通過某種特定的條件,將我們存放在同一個資料庫中的資料,分散存放到多個數據庫上面,以達到分散單臺裝置負載的效果

如上圖所表示,資料被分到多個分片資料庫後,應用如果需要讀取資料,就要需要處理多個數據源的資料。如果沒有資料庫中介軟體,那麼應用將直接面對分片叢集,資料來源切換、事務處理、資料聚合都需要應用直接處理,原本該是專注於業務的應用,將會花大量的工作來處理分片後的問題,最重要的是每個應用處理將是完全的重複造輪子。

所以有了資料庫中介軟體,應用只需要集中與業務處理,大量的通用的資料聚合,事務,資料來源切換都由中介軟體來處理。

那麼資料庫中介軟體是怎麼做到的呢?

在這裡插入圖片描述

綠色的部分為mycat的邏輯節點,藍色的部分為物理節點(即資料庫的部署地址)

schema:邏輯庫
通常對實際應用來說,並不需要知道中介軟體的存在,業務開發人員只需要知道
資料庫的概念,所以資料庫中介軟體可以被看做是一個或多個數據庫叢集構成的邏輯庫

table:邏輯表
既然有邏輯庫,那麼就會有邏輯表,分散式資料庫中,對應用來說,讀寫資料的表就是邏輯表。邏輯表,可以是資料切分後,分佈在一個或多個分片庫中,也可以不做資料切分,不分片,只有一個表構成

datanode:分片節點
資料切分後,一個大表被分到不同的分片資料庫上面,每個表分片所在的資料庫就是分片節點

datahost:節點主機(上圖藍色節點)
資料切分後,每個分片節點(dataNode)不一定都會獨佔一臺機器,同一機器上面可以有多個分片資料庫,這樣一個或多個分片節點(dataNode)所在的機器就是節點主機(dataHost),為了規避單節點主機併發數限制,儘量將讀寫壓力高的分片節點(dataNode)均衡的放在不同的節點主機(dataHost)。

rule:分片規則
前面講了資料切分,一個大表被分成若干個分片表,就需要一定的規則,這樣按照某種業務規則把資料分到某個分片的規則就是分片規則,資料切分選擇合適的分片規則非常重要,將極大的避免後續資料處理的難度。

實戰Mycat

到官網下一個release包下載即可。為了快速熟悉各種配置,一般直接從git上下載程式碼,本地用idea開啟啟動,方便練習一波

mycat的配置其實是蠻簡單的,最主要的是熟悉各配置檔案的規則。如使用者名稱,密碼,如何分庫,都是在配置檔案中定義的

關於配置檔案,conf目錄下主要以下三個需要熟悉。
server.xml是Mycat伺服器引數調整和使用者授權的配置檔案
schema.xml是邏輯庫定義和表以及分片定義的配置檔案
rule.xml是分片規則的配置檔案

[1]https://www.cnblogs.com/joylee/p/7513038.html
Mycat-Server的github
[2]https://github.com/MyCATApache/Mycat-Server