數據庫mysql讀寫分離實現方案

隨着一個網站的業務不斷擴展,數據不斷增加,數據庫的壓力也會越來越大,對數據庫或者SQL的基本優化可能達不到最終的效果,此時可以考慮通過添加數據庫節點來使其達到提升性能的目的通常有以下常見幾種方案。

  • 讀寫分離
    打開一個帖子內容頁,需要select帖子表,和帖子評論表,每個耗時10ms的話。每秒1000次查詢就是這個數據庫的極限了。也就是說,這個論壇只能承載每秒500次訪問。那麼我們就可以對這個數據庫做讀寫分離,來成倍提高數據庫的讀性能。

  • 水平分表
    交易歷史,這種表。因爲很少查詢1年前的信息。所以,我們可以按年份來進行水平分表。將今年的表優先對待。就減少了要查詢的表的大小。

  • 分庫
    如果我們的系統非常大了,功能非常多,就會有很多類型的數據庫表,例如營銷活動的表,和用戶賬號的表是沒有關聯的,那麼我們就可以將他們分到兩個數據庫中,然後放到不同的獨立的數據庫服務器,就能使數據庫吞吐量成倍增加。

  • 垂直分表
    典型的應用場景是在文章列表這樣的場景,一般來講,我們的文章表會有title、userId、Content等字段,其中的Content字段一般是Text或者LongText類型,而其它的字段都是固定長度的數據類型。我們知道一個數據庫優化規則是:

    • 如果一個表的所有字段都是固定長度類型的,那麼它就是定長表,定長表比動態長度表查詢性能要高
    • 那麼,我們就可以使用垂直分表來將文章表分成文章表和文章內容表。於是文章列表頁面所需的查詢,就只需要查詢一張定長表了。
  • 引入Cache
    通常來說即使前者的數據庫架構做得再好,對於定時搶購/抽獎/等,這種類似高密度密集訪問的場景也是力不從心,最好的方法還是在服務層和數據庫層添加一個緩存層用,使其讓請求命中至緩存層,數據層只持久化變更的數據即可

MySQL讀寫分離是指讓master處理寫操作,讓slave處理讀操作,非常適用於讀操作量比較大的場景,可減輕master的壓力。

常見高併發場景

1.實現mysql的讀寫分離(Mysql-proxy)

mysql-proxy是官方提供的mysql中間件產品可以實現負載平衡,讀寫分離,failover等,但其不支持大數據量的分庫分表且性能較差。

使用mysql-proxy實現mysql的讀寫分離,mysql-proxy實際上是作爲後端mysql主從服務器的代理,它直接接受客戶端的請求,對SQL語句進行分析,判斷出是讀操作還是寫操作,然後分發至對應的mysql服務器上。
mysql-proxy是官方提供的mysql中間件產品可以實現負載平衡,讀寫分離,failover等

MySQL Proxy就是這麼一箇中間層代理,簡單的說,MySQL Proxy就是一個連接池,負責將前臺應用的連接請求轉發給後臺的數據庫,並且通過使用lua腳本,可以實現複雜的連接控制和過濾,

從而實現讀寫分離和負載平衡。對於應用來說,MySQL Proxy是完全透明的,應用則只需要連接到MySQL Proxy的監聽端口即可。

當然,這樣proxy機器可能成爲單點失效,但完全可以使用多個proxy機器做爲冗餘,在應用服務器的連接池配置中配置到多 個proxy的連接參數即可。



     從圖中可以看到,SQL語句並不直接進入到master數據庫或者slave數據庫,而是進入到
proxy,然後proxy判斷這條語句是有關寫的語句(包括insert、update、delete)還
是讀語句(select),當是寫語句的時候,那麼proxy將向master所在的服務器發出請
求,同理,如果是讀語句的時候,proxy將向slave所在的服務器發出請求。

2.實現mysql的讀寫分離(MyCat)

MyCAT就是: 一個徹底開源的,面向企業應用開發的“大數據庫集羣” 支持事務、ACID、可以替代Mysql的加強版數據庫. 一個可以視爲“Mysql”集羣的企業級數據庫,用來替代昂貴的Oracle集羣 . 一個融合內存緩存技術、Nosql技術、HDFS大數據的新型SQL Server . 結合傳統數據庫和新型分佈式數據倉庫的新一代企業級數據庫產品 .一個新穎的數據庫中間件產品。

  • 1 . 修改MyCat的schema.xml文件vim /usr/local/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
        <!-- 定義一個MyCat的模式,邏輯數據庫名稱TestDB -->
        <!-- “checkSQLschema”:描述的是當前的連接是否需要檢測數據庫的模式 -->
        <!-- “sqlMaxLimit”:表示返回的最大的數據量的行數 -->
        <!-- “dataNode="dn1"”:該操作使用的數據節點是dn1的邏輯名稱 -->
        <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"/>
        <!-- 定義個數據的操作節點,以後這個節點會進行一些庫表分離使用 -->
        <!-- “dataHost="localhost1"”:定義數據節點的邏輯名稱 -->
        <!-- “database="test"”:定義數據節點要使用的數據庫名稱 -->
        <dataNode name="dn1" dataHost="localhost1" database="test" />
        <!-- 定義數據節點,包括了各種邏輯項的配置 -->
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
            <!-- 配置真實MySQL與MyCat的心跳 -->
            <heartbeat>select user()</heartbeat>
            <!-- 配置真實的MySQL的連接路徑 -->
            <writeHost host="hostMaster" url="192.168.1.196:3306" user="root" password="123456">
                <readHost host="hostSlave" url="192.168.1.168:3306" user="root" password="123456"/>
            </writeHost>
        </dataHost>
</mycat:schema>

2 . dataHost標籤上屬性釋義:

  • balance:負載均衡類型
    • 0:不開啓讀寫分離機制,所有讀操作都發送到當前可用的writeHost上
    • 1:全部的readHost與stand by writeHost參與select語句的負載均衡,
    • 2:所有讀操作都隨機在writeHost、readHost上分發
    • 3:所有讀請求隨機分發到writeHost對應的readHost執行,writeHost不負擔讀壓力
  • writeType:負載均衡類型
    • 0:所有寫操作發送到配置的第一個writeHost,當第一個writeHost宕機時,切換到第二個writeHost,重新啓動後以切換後的爲準,切換記錄在配置文件:dnindex.properties
    • 1:所有寫操作都隨發送到配置的writeHost
    • 2:尚未實現
  • switchType:切換方式
    • -1:不自動切換
    • 1:自動切換(默認)
    • 2:基於MySql主從同步的狀態來決定是否切換

3.實現mysql的讀寫分離(MaxScale)

MaxScale 是 Mysql 的兄弟公司 MariaDB 開發的,現在已經發展得非常成熟

MaxScale 是插件式結構,允許用戶開發適合自己的插件

MaxScale 目前提供的插件功能分爲5類

認證插件

提供了登錄認證功能,MaxScale 會讀取並緩存數據庫中 user 表中的信息,當有連接進來時,先從緩存信息中進行驗證,如果沒有此用戶,會從後端數據庫中更新信息,再次進行驗證

協議插件

包括客戶端連接協議,和連接數據庫的協議

路由插件

決定如何把客戶端的請求轉發給後端數據庫服務器,讀寫分離和負載均衡的功能就是由這個模塊實現的

監控插件

對各個數據庫服務器進行監控,例如發現某個數據庫服務器響應很慢,那麼就不向其轉發請求了

日誌和過濾插件

提供簡單的數據庫防火牆功能,可以對SQL進行過濾和容錯

4.實現mysql的讀寫分離(MySQL Router)

 MySQL Router是MySQL官方提供的一個輕量級中間件,可以在應用程序與MySQL服務器之間提供透明的路由方式。主要用以解決MySQL主從庫集羣的高可用、負載均衡、易擴展等問題。Router可以與MySQL Fabric無縫連接,允許Fabric存儲和管理用於路由的高可用數據庫服務器組,使管理MySQL服務器組更加簡單。

        MySQL Router是一個可執行文件,可以與應用程序在同一平臺上運行,也可以單獨部署。雖然MySQL Router是InnoDB Cluster(MySQL 7.X)的一部分,MySQL 5.6 等版本數據庫仍然可以使用Router作爲其中間代理層。MySQL Router的配置文件中包含有關如何執行路由的信息。它與MySQL服務器的配置文件類似,也是由多個段組成,每個段中包含相關配置選項。

        MySQL Router是MySQL Proxy的替代方案,MySQL官方不建議將MySQL Proxy用於生產環境,並且已經不提供MySQL Proxy的下載。

5.實現mysql的讀寫分離(Proxysql)

ProxySQL 是一款可以實際用於生產環境的 MySQL 中間件,它有官方版和 percona 版兩種。percona版是在官方版的基礎上修改的,添加了幾個比較實用的工具。生產環境建議用官方版。

ProxySQL 是用 C++ 語言開發的,雖然也是一個輕量級產品,但性能很好(據測試,能處理千億級的數據),功能也足夠,能滿足中間件所需的絕大多數功能,包括:

  • 最基本的讀/寫分離,且方式有多種
  • 可定製基於用戶、基於schema、基於語句的規則對SQL語句進行路由。換句話說,規則很靈活。基於schema和與語句級的規則,可以實現簡單的sharding(分庫分表)
  • 可緩存查詢結果。雖然ProxySQL的緩存策略比較簡陋,但實現了基本的緩存功能,絕大多數時候也夠用了。此外,作者已經打算實現更豐富的緩存策略
  • 監控後端節點。ProxySQL可以監控後端節點的多個指標,包括:ProxySQL和後端的心跳信息,後端節點的read-only/read-write,slave和master的數據同步延遲性(replication lag)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章