Mycat - 高可用與負載均衡實現,滿滿的乾貨!

来源:https://www.cnblogs.com/youzhibing/archive/2019/01/23/10263557.html
-Advertisement-
Play Games

前言 開心一刻 和朋友去吃小龍蝦,隔壁桌一個小女孩問媽媽:"媽媽,小龍蝦回不了家,它媽媽會不會著急?" 她媽媽愣住了,我扒蝦的手停下了,這麼善良的問題,怎麼下得了口。這是老闆急忙過來解圍:"不會的,不會的,它們全家都在這了。" 路漫漫其修遠兮,吾將上下而求索! github:https://gith ...


前言

  開心一刻

    和朋友去吃小龍蝦,隔壁桌一個小女孩問媽媽:"媽媽,小龍蝦回不了家,它媽媽會不會著急?" 她媽媽愣住了,我扒蝦的手停下了,這麼善良的問題,怎麼下得了口。這是老闆急忙過來解圍:"不會的,不會的,它們全家都在這了。" 

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

  github:https://github.com/youzhibing

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

前情回顧

  Mycat - 實現資料庫的讀寫分離與高可用中我們實現了mysql的讀寫分離與高可用,有幾個點我們回顧下

    1、數據的同步在mysql層面實現的,mycat不負責任何的數據同步,我們需要配置mysql的主從複製來實現數據的同步;

    2、資料庫的讀寫分離是mycat最常用的場景之一,我們的應用代碼只需要關註業務代碼,而不需要處理資料庫讀寫、分片問題,這些都由Mycat實現,簡化了開發;

    3、讀寫分離往往伴隨著高可用,而Mycat同時支持這兩者;

  那是不是就完美無缺了呢? 顯然還有點小瑕疵,此時我們的Mycat是單點部署的,如果Mycat服務掛了,那麼整個資料庫端就掛了,整個應用也就不能正常服務了,那怎麼辦了? 很明顯,我們需要實現Mycat的高可用,具體實現我們往下看。

keepalived實現Mycat高可用

  centos7_1 (192.168.1.110)上搭建mycat

    上篇博文中,我們搭建的讀寫分離各組件關係如下

    此時還是單節點的mycat,我們還需要搭建一個mycat,搭建過程可以參考192.168.1.212上mycat的搭建,具體我就不演示了,搭建好之後各組件關係如下

    昨天我們測試了master mysql宕機的情況,後續的DML SQL與Select SQL都是走的slave mysql,所以此時mysql的主從複製已經被破環、mycat的writeHost也切換到了192.168.1.211,我們需要重新配置mysql的主從複製,192.168.1.210仍是主,192.168.1.211回退為slave,並將192.168.1.212上mycat的writeHost進行還原(只需要將mycat/conf/dnindex.properties文件刪了即可);生產環境不要這麼處理,按上篇說的處理。

    我們來看下測試結果

    可以看到,192.168.1.110上的mycat與192.168.1.212上的mycat具有完全一樣的功能,但此時兩者還沒有任何聯繫,彼此也互不影響。我們可以在應用代碼中集成兩個mycat,由代碼控制mycat的高可用,這種方式可行但不可取,代碼應該更多的關註業務層,而不是處理資料庫層面的高可用問題。mycat的高可用應該就由更專業的組件來處理。

  keepalived實現vip對外提供服務

    VIP:192.168.1.200、master:192.168.1.212、backup:192.168.1.110

    keepalived的搭建過程可參考:主從熱備+負載均衡(LVS + keepalived),這裡就不做詳細的演示了。

    192.168.1.212(master)上keepalived.conf

global_defs {
    notification_email {
        997914490@qq.com
    }
    notification_email_from sns-[email protected]
    #smtp_server smtp.hysec.com
    #smtp_connection_timeout 30
    router_id mycat_master         # 設置mycat master的id,在一個網路應該是唯一的
}
vrrp_script chk_mycat_alive {
    script "/usr/local/src/mycat/check_pid.sh" # 返回狀態碼為0表示正常,檢測腳本為true;返回狀態碼非0表示異常,檢測腳本為false
    interval 2                     # 檢測腳本執行的間隔,單位是秒
    weight 20
}
vrrp_instance VI_1 {
    state MASTER                  # 指定keepalived的角色,MASTER為主,BACKUP為備
    interface eth0                 # 當前進行vrrp通訊的網路介面卡(當前centos的網卡)
    virtual_router_id 66         # 虛擬路由編號,同集群,主備必須一致
    priority 100                 # 優先順序,數值越大,獲取處理請求的優先順序越高
    advert_int 1                 # 檢查間隔,預設為1s(vrrp組播周期秒數)
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    track_script {
        chk_mycat_alive            # 調用檢測腳本
    }
    virtual_ipaddress {
        192.168.1.200            # 定義虛擬ip(VIP),可多設,每行一個
    }
}
View Code

    192.168.1.110(backup)上keepalived.conf

global_defs {
    notification_email {
        997914490@qq.com
    }
    notification_email_from sns-[email protected]
    #smtp_server smtp.hysec.com
    #smtp_connection_timeout 30
    router_id mycat_backup        # 設置mycat backup的id,在一個網路應該是唯一的
}
vrrp_script chk_mycat_alive {
    script "/usr/local/src/mycat/check_pid.sh"    #mycat檢測腳本
    interval 2                          #(檢測腳本執行的間隔,單位是秒)
    weight 20
}
vrrp_instance VI_1 {
    state BACKUP            # 指定keepalived的角色,MASTER為主,BACKUP為備
    interface enp0s3          # 當前進行vrrp通訊的網路介面卡(當前centos的網卡)
    virtual_router_id 66    # 虛擬路由編號,同集群,主備必須一致
    priority 90            # 優先順序,數值越大,獲取處理請求的優先順序越高
    advert_int 1            # 檢查間隔,預設為1s(vrrp組播周期秒數)
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    track_script {
        chk_mycat_alive            #(調用檢測腳本)
    }
    virtual_ipaddress {
        192.168.1.200            # 定義虛擬ip(VIP),可多設,每行一個
    }
}
View Code

    mycat存活檢測腳本check_pid.sh

#!/bin/bash
count=`/usr/local/mycat/bin/mycat status |grep 'Mycat-server is running' | wc -l`
time=$(date "+%Y-%m-%d %H:%M:%S")
if [ $count = 0 ]; then
    echo "$time : count=$count, mycat is not running..." >> /var/log/keepalived_check.log
    exit 1 # 返回1說明腳本非正常執行,mycat不在運行中
else
    echo "$time : count=$count, mycat is running..." >> /var/log/keepalived_check.log
    exit 0 # 返回0說明腳本正常執行,mycat正在運行中
fi
View Code

      腳本目錄:/usr/local/src/mycat/,給腳本可執行許可權:[root@centos7-01 src]# chmod -R 755 mycat/check_pid.sh

    各組件關係圖如下

    如上圖所示,外部應用向192.168.1.200發送sql請求,keepalived完成VIP到ip的映射,請求會落到具體的某個mycat上,再由mycat轉發到具體的mysql上。同一時刻只會有一個keepavlied處理VIP,一般而言是優先順序高的keepalived會成為master,負責VIP的映射。各組件配置好之後,我們來看看測試結果

    1、vip的正常綁定與切換

      一開始212和110都沒有啟動mycat,優先順序分別是100,90,所以vip在212上,212成為master,110成為backup;接著我們啟動了110上的mycat,檢測腳本返回0,vrrp_script中script為true,此時110的權重=90+20,大於212的100,110搶占vip成為master,而212則降級成為backup;然後我們啟動了212上的mycat,212的權重=100+20,大於110的110,vip漂浮到212上,212成為master,110成為backup;最後我們停了212上的mycat,權重=100,vip又漂到了110上。如果我們接著停了110上的mycat,則vip又會漂到212上。

      權重 = priority + weight * script的結果(腳本執行返回0,script則為true,否則script為false),權重大的搶占到vip,成為master;殺掉keepalived進程,vip也會進行正確的轉移,具體我就不展示測試結果,大家可以自行去測試。

    2、mycat高可用

      我們通過vip可以進行正常的sql請求,當212上的mycat停了,vip漂到了110上,通過vip仍然可以進行sql請求,應用端根本感知不到後端vip的漂移、mycat的切換,實現了mycat的高可用。

  這種方案已經可以滿足大多數的應用場景了,master上的mycat對外服務,backup上的mycat僅作為備用以防master宕機,backup上的mycat基本上不提供服務,就是起到一個以防萬一的作用,併發量不高的應用採用此種方案就可以了。如果併發量高了,master上的mycat壓力太大,那我們就需要考慮將backup上的mycat也利用起來了,並做一個負載均衡,減輕master上的mycat壓力,並充分利用backup上的mycat,具體實現請往下看。

lvs實現Mycat的負載均衡

  Mycat的高可用是實現了,但美中不足的是沒有物盡其用,我們不難發現,Mycat的兩個節點其實只有一個對外服務,另一個完全備用(以備基本不會發生的宕機),宕機的概率本來就小,備用機基本相當於沒用了,那可不可以將備用機利用起來了? 我們可以將主備Mycat都利用起來,併進行負載均衡,減小主Mycat的壓力,如果其中一個節點宕機了,則由另一個節點完全接管,繼續正常提供服務。

  組件結構圖如上所示,keepalived負責lvs的健康檢測與高可用,lvs負責mycat的負載均衡與心跳檢測。如果伺服器不夠,keepalived、lvs和mycat可以部署在一起,但不推薦,組件都部署在同一個伺服器上,風險太大,分散部署,可以降低風險。keepalived + lvs的具體部署過程可參考主從熱備+負載均衡(LVS + keepalived),具體配置文件如下

  192.168.1.214(master)上keepalived.conf

global_defs {
    notification_email {
        997914490@qq.com
    }
    notification_email_from sns-[email protected]
    #smtp_server smtp.hysec.com
    #smtp_connection_timeout 30
    router_id lvs_master         # 設置lvs master的id,在一個網路應該是唯一的
}
vrrp_instance VI_1 {
    state MASTER                  # 指定keepalived的角色,MASTER為主,BACKUP為備
    interface eth0                 # 當前進行vrrp通訊的網路介面卡(當前centos的網卡)
    virtual_router_id 66         # 虛擬路由編號,主從要一致
    priority 100                 # 優先順序,數值越大,獲取處理請求的優先順序越高
    advert_int 1                 # 檢查間隔,預設為1s(vrrp組播周期秒數)
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.200            # 定義虛擬ip(VIP),可多設,每行一個
    }
}
virtual_server 192.168.1.200 8066 {  #設置虛擬伺服器,需要指定虛擬IP地址和服務埠,IP與埠之間用空格隔開
    delay_loop 6              #設置運行情況檢查時間,單位是秒
    lb_algo rr                #設置負載調度演算法,這裡設置為rr,即輪詢演算法
    lb_kind DR                #設置LVS實現負載均衡的機制,有NAT、TUN、DR三個模式可選
    nat_mask 255.255.255.0
    persistence_timeout 0     #會話保持時間,單位是秒;同一IP x秒內的請求都發到同個real server
    protocol TCP              #指定轉發協議類型,有TCP和UDP兩種
 
    real_server 192.168.1.212 8066 { #配置服務節點1,需要指定real server的真實IP地址和埠,IP與埠之間用空格隔開
        weight 3              #配置服務節點的權值,權值大小用數字表示,數字越大,權值越高,設置權值大小可以為不同性能的伺服器
        TCP_CHECK {           #realserver的狀態檢測設置部分
            connect_timeout 10     #表示10秒無響應超時
            nb_get_retry 3      #表示重試次數
            delay_before_retry 3  #表示重試間隔
        }
    }
    real_server 192.168.1.110 8066 {
        weight 3
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}
View Code

  192.168.1.213(backup)上keepalived.conf

global_defs {
    notification_email {
        997914490@qq.com
    }
    notification_email_from sns-[email protected]
    #smtp_server smtp.hysec.com
    #smtp_connection_timeout 30
    router_id lvs_backup        # 設置lvs backup的id,在一個網路應該是唯一的
}
vrrp_instance VI_1 {
    state MASTER                  # 指定keepalived的角色,MASTER為主,BACKUP為備
    interface eth0                 # 當前進行vrrp通訊的網路介面卡(當前centos的網卡)
    virtual_router_id 66         # 虛擬路由編號,主從要一致
    priority 100                 # 優先順序,數值越大,獲取處理請求的優先順序越高
    advert_int 1                 # 檢查間隔,預設為1s(vrrp組播周期秒數)
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.200            # 定義虛擬ip(VIP),可多設,每行一個
    }
}
virtual_server 192.168.1.200 8066 {  #設置虛擬伺服器,需要指定虛擬IP地址和服務埠,IP與埠之間用空格隔開
    delay_loop 6              #設置運行情況檢查時間,單位是秒
    lb_algo rr                #設置負載調度演算法,這裡設置為rr,即輪詢演算法
    lb_kind DR                #設置LVS實現負載均衡的機制,有NAT、TUN、DR三個模式可選
    nat_mask 255.255.255.0
    persistence_timeout 0     #會話保持時間,單位是秒;同一IP x秒內的請求都發到同個real server
    protocol TCP              #指定轉發協議類型,有TCP和UDP兩種
 
    real_server 192.168.1.212 8066 { #配置服務節點1,需要指定real server的真實IP地址和埠,IP與埠之間用空格隔開
        weight 3              #配置服務節點的權值,權值大小用數字表示,數字越大,權值越高,設置權值大小可以為不同性能的伺服器
        TCP_CHECK {           #realserver的狀態檢測設置部分
            connect_timeout 10     #表示10秒無響應超時
            nb_get_retry 3      #表示重試次數
            delay_before_retry 3  #表示重試間隔
        }
    }
    real_server 192.168.1.110 8066 {
        weight 3
        TCP_CHECK {
            connect_timeout 10
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}
View Code

  192.168.212、192.168.1.110上的realserver.sh內容一致

#!/bin/bash

VIP=192.168.1.200

/etc/rc.d/init.d/functions
 
case "$1" in
start)
       ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP
       /sbin/route add -host $VIP dev lo:0               
      echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
       echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
       echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
       echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
       sysctl -p >/dev/null 2>&1
       echo "RealServer Start OK"
       ;;
stop)
       ifconfig lo:0 down
       route del $VIP >/dev/null 2>&1              
       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
       echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
       echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
       echo "RealServer Stoped"
       ;;
*)
       echo "Usage: $0 {start|stop}"
       exit 1
esac
 
exit 0
View Code

    在/usr/local/src/目錄下,給腳本可執行許可權:[root@centos212 ~]# chmod -R 755 /usr/local/src/realserver.sh

  按照上述結構圖,從右往左逐個啟動組件:先啟動mysql,接著啟動mycat,然後啟動realserver.sh,再啟動keepalived。我們來看下負載均衡效果

  負載均衡效果我們可以通過ipvsadm -l命令來查看,具體體現在ActiveConn和InActConn值,ActiveConn是活動連接數,也就是tcp連接狀態的ESTABLISHED,而InActConn是指除了ESTABLISHED以外的,所有的其它狀態的tcp連接。因為./mysql -h192.168.1.200 -P8066 -uroot -p123456 -DTESTDB  -e 'select @@hostname'是瞬時的,這個連接就歸為InActConn,如果我們想測試ActiveConn,我們可以用./mysql -h192.168.1.200 -P8066 -uroot -p123456 -DTESTDB,其實與我們平時操作mysql是一樣的。從上圖中可以看出,是達到了負載均衡效果的,192.168.1.110:8066與192.168.1.212:8066輪著來處理。

  可能會有人對上圖中./mysql -h192.168.1.200 -P8066 -uroot -p123456 -DTESTDB  -e 'select @@hostname'的返回值有疑問:為什麼總是centos211? 這個sql其實就是查詢mysql的主機名,註意是mysql伺服器的主機名,不是mycat的主機名!sql最終的執行者是mysql! 而我們知道mycat對mysql做了讀寫分離,也就是說./mysql -h192.168.1.200 -P8066 -uroot -p123456 -DTESTDB  -e 'select @@hostname'始終會在mysql slave上執行,而我們的mysql slave的ip是192.168.1.211,其hostname是centos211,所以看到的hostname總是centos211。

總結

  1、很多時候我們都只需要實現mycat的高可用,而不需要實現mycat的負載均衡;組件越多,越容易出錯,也更難以維護;沒有一成不變的最優方案,只有在合適時機的最佳方案;

  2、keepalived的作用,有沒有lvs,keepalived啟動的作用是有所區別的。沒有lvs時,keepalived負責vip的映射與轉移、mycat的存活檢測;有lvs時,Keepalived負責vip的映射與轉移、RealServer的健康狀態檢查。不管有沒有lvs,keepalived都會負責VIP的映射與轉移,實現master和slave主機之間failover,達到高可用目的;

  3、各個組件的職責都很明顯,mysql負責sql的執行,mycat負責mysql的讀寫分離與高可用,lvs負責mycat的負載均衡與高可用,keepalived負責vip相關工作以及lvs的高可用。各個組件的角色弄清楚了,搭建起來也就不難了;

  4、《Mycat權威指南》中採用haproxy + keepalived實現mycat的高可用和負載均衡,我就不再重覆講了,有興趣的可以去實踐一把;另外留個疑問:nginx可不可實現mycat的負載均衡?

  5、關於搭建過程中遇到的問題,我會在下篇博文詳細講解,包括keepalived的“腦裂”問題,以及一些其他大家在搭建過程中可能會遇到的問題,敬請期待;

參考

  《Mycat權威指南》

  LVS+Keepalived搭建MyCAT高可用負載均衡集群


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

-Advertisement-
Play Games
更多相關文章
  • 掛載方法 smbclient鏈接 如果沒有smbclient命令:yum安裝smbclient命令 ...
  • 問題 說下我linux配置情況,不一樣的可以選擇借鑒我的辦法。 在虛擬機中以最小化方式安裝centos7,ifconfig命令無效,而且在sbin目錄中沒有ifconfig文件。 原因 這是因為centos7已經不適用ifconfig命令了,已經用ip命令代替;同時網卡名稱也由eth0改為eno16 ...
  • VirtualBox安裝centos7配置靜態ip地址可以本機訪問,可以聯網。 在開始之前先說一下,不知道為什麼,我在網上百度的大多數是不能用的,或者只能主機訪問,或者只能聯網。 我的配置文件為ifcfg-enp0s3 話不多說:上圖 1.安裝完centos7之後進入 2.選擇設置 >網路 如下圖可 ...
  • 本文收錄在容器技術學習系列文章總目錄 1、kubernetes安裝介紹 1.1 K8S架構圖 1.2 K8S搭建安裝示意圖 1.3 安裝kubernetes方法 優點:你只要安裝kubeadm即可;kubeadm會幫你自動部署安裝K8S集群;如:初始化K8S集群、配置各個插件的證書認證、部署集群網路 ...
  • 命令: cp 對應英文: copy 作用: 複製文件或目錄 選項: -f:已存在的目標文件直接覆蓋,不會提示 -i:覆蓋文件前提示,接著輸入 y 或 n -r:若給出的源文件是目錄文件,則cp將遞歸複製該目錄下的所有子目錄和文件,目標文件必須是一個目錄名 用法: cp [選項] 源文件 目標文件 # ...
  • #字元串比較if [ "$1" == "判斷條件" ] then echo "$1" elif [ "$1" == "判斷條件" ] then echo "$1" else echo '[提示信息]' fi#數值比較int1 -eq int2 兩數相等為真int1 -ne int2 兩數不等為真in ...
  • 一 Ansible的安裝部署 1.1 PIP方式 略,可參考《001.Pip簡介及使用》。 提示:建議將PIP升級到最新:pip install --upgrade pip。 1.2 YUM方式 二 Ansible目錄及配置 2.1 Ansible目錄結構 配置文件目錄:/etc/ansible 主 ...
  • #日期時間 echo '日期時間' datetime=$(date "+%Y-%m-%d %H:%M:%S") echo "$datetime" ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...