應用集成mycat,實現mycat的高可用與mysql的讀寫分離

来源:https://www.cnblogs.com/youzhibing/archive/2019/02/25/10384439.html
-Advertisement-
Play Games

前言 開心一刻 一個女人自朋友圈寫道:我家老公昨天和別人家的老婆出去旅游,迄今未歸,我則被別人家的老公折騰了一天,好累哦! 圈子下麵,評論無數,老公在下麵評論到:能不能好好說話,我只不過陪女兒去畢業旅游行,而你負責在家留守,照顧三歲兒子,要不要寫的這麼刺激、讓人浮想聯翩的? 你是不是有點虎? 諾維斯 ...


前言

  開心一刻

    一個女人自朋友圈寫道:我家老公昨天和別人家的老婆出去旅游,迄今未歸,我則被別人家的老公折騰了一天,好累哦!

    圈子下麵,評論無數,老公在下麵評論到:能不能好好說話,我只不過陪女兒去畢業旅游行,而你負責在家留守,照顧三歲兒子,要不要寫的這麼刺激、讓人浮想聯翩的? 你是不是有點虎?

諾維斯基:你往哪射了?

周子瑜:我只是個娛樂明星,射箭我不是專業的...

  路漫漫其修遠兮,吾將上下而求索!

  github:https://github.com/youzhibing

  碼雲(gitee):https://gitee.com/youzhibing

前情回顧

  通過前面的兩篇博文:Mycat - 實現資料庫的讀寫分離與高可用Mycat - 高可用與負載均衡實現,滿滿的乾貨!,我們完成瞭如下圖所示的組件部署

組件結構圖一

  SQL請求發給VIP,keepalived完成VIP的映射,並通過lvs將請求轉發mycat,mycat根據SQL請求類型(DML SQL還是SELECT SQL,亦或是強制指定db節點)將SQL分發到具體的db,完成由具體的資料庫服務完成SQL的執行。

  但這還只是停留在資料庫層面的部署,還沒集成我們的應用,沒有實際意義,那麼我們如何集成我們的應用,實現mycat的使命呢?

應用集成

  如果mycat搭建好了,進行應用集成非常簡單,下麵我們一步一步來實現各種情況下的應用集成

  Mysql的讀寫分離與高可用

    資料庫的讀寫分離可以在代碼層面實現(可參考:spring集成mybatis實現mysql讀寫分離),但不推薦,代碼的核心職責應該是業務的實現,如果將大篇的代碼用來實現資料庫的讀寫分離與高可用,那就背離了本意、南轅北轍了。

    電腦領域有句名言:“電腦科學領域的任何問題都可以通過增加一個間接的中間層來解決”。既然我們的代碼直接對接資料庫不好實現資料庫的讀寫分離與高可用,那就在中間新增一層中間件來實現,從而產生了資料庫中間件(mycat只是實現之一),應用代碼直接與資料庫中間對接,由資料庫中間件來實現資料庫的讀寫分離與高可用。此時的組件結構圖如下

組件結構圖二

    具體的部署過程可參考:Mycat - 實現資料庫的讀寫分離與高可用,此時應用如何集成了?其實非常簡單,只需要將我們的連接池配置中的資料庫地址改成mycat的地址即可(將mycat看成資料庫),具體如下

    application.yml

server:
  port: 8886
spring:
  #連接池配置
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.1.212:8066/TESTDB?useSSL=false&useUnicode=true&characterEncoding=utf-8
      username: root
      password: 123456
      initial-size: 1                     #連接池初始大小
      max-active: 20                      #連接池中最大的活躍連接數
      min-idle: 1                         #連接池中最小的活躍連接數
      max-wait: 60000                     #配置獲取連接等待超時的時間
      pool-prepared-statements: true    #打開PSCache,並且指定每個連接上PSCache的大小
      max-pool-prepared-statement-per-connection-size: 20
      validation-query: SELECT 1 FROM DUAL
      validation-query-timeout: 30000
      test-on-borrow: false             #是否在獲得連接後檢測其可用性
      test-on-return: false             #是否在連接放回連接池後檢測其可用性
      test-while-idle: true             #是否在連接空閑一段時間後檢測其可用性
#mybatis配置
mybatis:
  type-aliases-package: com.lee.mycat.entity
  #config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/*.xml
# pagehelper配置
pagehelper:
  helperDialect: mysql
  #分頁合理化,pageNum<=0則查詢第一頁的記錄;pageNum大於總頁數,則查詢最後一頁的記錄
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql
logging:
  level:
    com.lee.mycat.mapper: DEBUG
View Code

    UserWeb.java

package com.lee.mycat.web;

import com.lee.mycat.entity.User;
import com.lee.mycat.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/mycat")
public class UserWeb {

    @Autowired
    private IUserService userService;

    @RequestMapping("/getUserByNameFromMasterDb")
    public User getUserByNameFromMasterDb(String name) {
        return userService.getUserByNameFromMasterDb(name);
    }

    @RequestMapping("/getUserByNameFromSlaveDb")
    public User getUserByNameFromSlaveDb(String name) {
        return userService.getUserByNameFromSlaveDb(name);
    }

    @RequestMapping("/getUserByName")
    public User getUserByName(String name) {
        return userService.getUserByName(name);
    }

    @RequestMapping("/addUser")
    public Integer addUser(String name, Integer age) {
        return userService.insertUser(new User(name, age));
    }
}
View Code

    UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lee.mycat.mapper.UserMapper">

    <sql id="Base_Column_List">
        id,name,age
    </sql>

    <select id="getUserByNameFromMasterDb" resultType="User" parameterType="String">
        /*!mycat:db_type=master*/ SELECT
          <include refid="Base_Column_List" />
        FROM
            tbl_user
        WHERE name=#{name}
    </select>
    <select id="getUserByNameFromSlaveDb" resultType="User" parameterType="String">
        /*!mycat:db_type=slave*/ SELECT
          <include refid="Base_Column_List" />
        FROM
          tbl_user
        WHERE name=#{name}
    </select>
    <select id="getUserByName" resultType="User" parameterType="String">
        SELECT
          <include refid="Base_Column_List" />
        FROM
          tbl_user
        WHERE name=#{name}
    </select>
    <insert id="insertUser" parameterType="User"  useGeneratedKeys="true" keyProperty="id">
        INSERT INTO
          tbl_user(name, age)
        VALUES
          (#{name}, #{age})
    </insert>
</mapper>
View Code

    UserMapper.xml文件中會與我們平時的寫法有些許不同,有時候需要明確指定強制走master還是slave節點。具體細節可查看:spring-boot-mycat

    測試結果

      如上圖所示,我們一開始新增了一個用戶:Jiraiye,其年齡是50,我們手動改了mysql slave中Jiraiye的年齡為52是為了更直觀的驗證SQL請求最終走的是mysql master還是mysql slave。從上圖可知,一般的Select SQL走的是從庫(DML SQL走主庫這個就不用說了),如在mapper.xml中強制指定了db節點,那麼就會在指定的mysql節點上來執行SQL。

      mysql的高可用就沒進行測試了,應用其實是感知不到的;mysql master宕機了,mycat會按我們配置好的進行mysql db的切換,正常服務於我們的引用。

  Mycat的高可用

    mysql的讀寫分離與高可用我們是實現了,可mycat卻存在高可用問題,一旦mycat宕機了,整個資料庫層就相當於宕機了。可想而知,我們需要實現mycat的高可用。

    mycat的高可用搭建過程可參考:Mycat - 高可用與負載均衡實現,滿滿的乾貨!,此時的組件結構圖如下

組件結構圖三

    應用工程改動非常小,只需要將資料庫連接配置的url改成VIP即可,如下

jdbc:mysql://192.168.1.212:8066/TESTDB?useSSL=false&useUnicode=true&characterEncoding=utf-8
改成
jdbc:mysql://192.168.1.200:8066/TESTDB?useSSL=false&useUnicode=true&characterEncoding=utf-8

    測試結果

      mysql的讀寫分離依然正常工作,當mycat master宕機後,mycat slave接管任務,進行sql的轉發,實現了mycat的高可用;期間出現了非常短時間的異常提示,這是因為資料庫連接池中都是212上的mycat連接,212現在已經宕機了,所以會出現一次異常提示,但連接池立馬做出了反應,重新建立資料庫連接,此時連接池中的連接都是連接的110。

  Mycat的負載均衡

    上述mycat的高可用中,絕大多數情況下,mycat slave一直處於等待狀態,未提供任何服務,因為我們的mycat master一般而言是不會宕機的。那有沒有什麼做法可以讓slave也處理SQL請求,而又和master互備實現mycat高可用呢?那就是實現Mycat的負載均衡,此時mycat不存在主從關係,而是它倆兩兩互備,此時的組件結構圖就是組件結構圖一。應用工程不用變,資料庫連接還是配置VIP。具體就不演示了,大家自行去實踐即可。

總結

  1、資料庫中間件可以降低應用代碼的複雜性,讓其專職與業務代碼的實現,而資料庫層面的工作交給資料庫中間件;mycat只是資料庫中間件的一種實現,卻也是比較優秀的實現,她是開源的。

  2、併發量不高的情況下,實現mycat的高可用即可,無需實現Mycat的負載均衡;實現mycat的負載均衡需要更多的硬體成本和維護成本,卻沒有帶來質變的收益,就性價比而言,不升反降。

  3、具體需要部署成什麼組件結構,需要看具體的需求,很多情況下根本用不到mycat中間件,如果用到了mycat中間件,個人認為最好還是實現mycat的高可用,至於需不需要實現mycat的負載均衡,就看具體的併發量了,這個也沒個標準,就要結合實際情況來排查是不是mycat的負載過高了,如果確實是mycat負載過高,那麼就有必要實現mycat的負載均衡來降低單個mycat的負載了。沒有絕對的最優部署,只有當下最合適的部署。

參考

  《Mycat權威指南》


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、TensorRT支持的模型: TensorRT 直接支持的model有ONNX、Caffe、TensorFlow,其他常見model建議先轉化成ONNX。總結如下: 1 ONNX(.onnx) 2 Keras(.h5) --> ONNX(.onnx) (https://github.com/on ...
  • 添加主機與主機組 1. 進入web頁面,在 配置 主機群組,新建主機群組 2. 在 配置 主機,新建主機 在可見的名稱中建議填寫為類似 主機類型 主機名 IP或功能變數名稱 的格式,如Web Hyrule001 192.168.233.247 在 群組 中選擇之前新建的群組 agent代理程式的介面 填寫a ...
  • Let’s Encrypt 是由 Internet Security Research Group (ISRG) 開發的一個自由、自動化和開放的證書頒發機構。目前幾乎所有的現代瀏覽器都信任由 Let’s Encrypt 頒發的證書。 這個教程,將會一步一步的教你如何在 CentOS 7 上通過 C... ...
  • 詳細說明 Restricted 執行策略不允許任何腳本運行。 AllSigned 和 RemoteSigned 執行策略可防止 Windows PowerShell 運行沒有數字簽名的腳本。 允許運行簽名腳本 首次在電腦上啟動 Windows PowerShell 時,現用執行策略很可能是 Res ...
  • 1、LAMP 環境搭建 初次安裝可以先關閉selinux 和 firewall 1.1 mariadb資料庫安裝,啟動、加入啟動項 1.2 apache安裝安裝、啟動、加入啟動項 更改mysql root初始密碼: mysql> set password for root@localhost = p ...
  • 1.前言 在Linux中,伙伴系統(buddy system)是以頁為單位管理和分配記憶體。但是現實的需求卻以位元組為單位,假如我們需要申請20Bytes,總不能分配一頁吧!那豈不是嚴重浪費記憶體。那麼該如何分配呢?slab分配器就應運而生了,專為小記憶體分配而生。slab分配器分配記憶體以Byte為單位。但 ...
  • windows powershell基礎 目錄: 1.管道和重定向 2.命令執行 3.變數 4.數組和哈希表 #@()創建數組,使用","把每個值分隔開,@{}創建哈希表,用";"把每個值分隔開 5.常用命令 get-help 查看幫助 get-command 查詢命令 get-member 查看對 ...
  • 轉自:https://blog.csdn.net/xcntime/article/details/51746148 導讀:對於Windows內置安全主體特別需要註意的是:你無法創建、重命名和刪除它們,並且它們在任何一個Windows系統中都是一樣的。 在上期雜誌的“理解Windows內置安全主體(上 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...