(10) 如何MySQL讀壓力大的問題

来源:https://www.cnblogs.com/huchong/archive/2019/01/15/10267547.html
-Advertisement-
Play Games

如何進行讀寫分離 由開發人員根據所執行的SQL類型連接不同的伺服器 由資料庫中間層實現讀寫分離 讀寫分離時,需要註意,對於實時性要求比較高的數據,不適合在從庫上查詢(因為主從複製存在一定延遲(毫秒級)),比如庫存就應該在主庫上查詢,如果放在從庫上查詢,可能會存在超賣的情況 由開發人員根據所執行的SQ ...


如何進行讀寫分離

  • 由開發人員根據所執行的SQL類型連接不同的伺服器
  • 由資料庫中間層實現讀寫分離

讀寫分離時,需要註意,對於實時性要求比較高的數據,不適合在從庫上查詢(因為主從複製存在一定延遲(毫秒級)),比如庫存就應該在主庫上查詢,如果放在從庫上查詢,可能會存在超賣的情況

由開發人員根據所執行的SQL類型進行讀寫分離的方式

優點:
1. 完全由開發人員控制,實現更加靈活
2. 由程式直接連接資料庫,所以性能損耗比較少

缺點:
1. 增加了開發的工作量,使程式代碼更加複雜
2. 人為控制,容易出現錯誤

  1. 可採用DNS輪詢的方式

DNS輪詢:在同一個功能變數名稱伺服器上為同一個功能變數名稱配置多個不同IP地址的A記錄

應用端使用功能變數名稱來連接資料庫伺服器,這樣在進行功能變數名稱解析時,功能變數名稱伺服器會迴圈的將不同的IP返回給應用端,應用端就可以按地址連接不同的只讀伺服器來進行讀取操作
這種操作比較簡單,只需要修改功能變數名稱伺服器的配置即可,但是如果某一後端伺服器出現故障,則必須通過修改DNS的方式把故障伺服器剔除到只讀伺服器列表之外,性能較差,負載也不均衡,大多數情況下不推薦此方式

  1. 使用LVS/Haproxy 等代理層軟體

由於是通用的代理層軟體,所以不能自動對SQL語句進行分析,實現讀寫分離,但是可以完成只讀伺服器的負載均衡操作
LVS 四層代理,Haproxy 七層代理,所以從性能來看LVS高於Haproxy

  1. F5硬體:成本較高

keepalived+lvs的架構方式

此處使用keepalived+lvs的架構方式,演示如下

優點:
抗負載能力較強,屬於四層代理,只進行流量分發,不會對數據內容進行解析,對記憶體和CPU的消耗也比較低,處理效率更高
工作穩定,自身有完整的雙機熱備方案,可進行高可用配置
無流量,只分發請求,流量不從它本身出去,不會對主機的網路IO造成影響

伺服器信息

# 主DB         IP:192.168.3.100
# 主備DB     IP:192.168.3.101
# SlaveDB    IP:192.168.3.102
# keepalived    vip:192.168.3.99
# lvs manage    :    192.168.3.100/101
# lvs vip :192.168.3.98

1. 安裝lvs管理工具

在192.168.3.100 和192.168.3.101上安裝lvs管理工具

[root@Node1 keepalived]#    yum install -y ipvsadmin.x86_64

2. 載入ipvs模塊

在 192.168.3.100 和192.168.3.101以及192.168.3.102 執行以下命令,載入ipvs模塊

[root@Node1 keepalived]#    modprobe ip_vs

3. 在slave伺服器上編寫並運行要使用lvs腳本

在 192.168.3.101和 192.168.3.102上編寫腳本

/etc/init.d/lvsrs 腳本文件內容如下

#!/bin/bash 
VIP=192.168.3.98
. /etc/rc.d/init.d/functions 
case "$1" in 
start) 
/sbin/ifconfig lo down 
/sbin/ifconfig lo up 
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 
/sbin/sysctl -p >/dev/null 2>&1 
/sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 up 
/sbin/route add -host $VIP dev lo:0 
echo "LVS-DR real server starts successfully.\n" 
;; 
stop) 
/sbin/ifconfig lo:0 down 
/sbin/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 "LVS-DR real server stopped." 
;; 
status) 
isLoOn=`/sbin/ifconfig lo:0 | grep "$VIP"` 
isRoOn=`/bin/netstat -rn | grep "$VIP"` 
if [ "$isLoOn" == "" -a "$isRoOn" == "" ]; then 
echo "LVS-DR real server has to run yet." 
else 
echo "LVS-DR real server is running." 
fi 
exit 3 
;; 
*) 
echo "Usage: $0 {start|stop|status}" 
exit 1 
esac 
exit 0 

/etc/init.d/lvsrs 需要具有可執行許可權

運行腳本

[root@Node1 keepalived]#  /etc/init.d/lvsrs start

運行成功後 通過ip addr 命令 可以看到lo中除了127.0.0.1外還有192.168.3.98

4. 修改主伺服器上的keepalived.conf文件,通過keepalived,保證lvs的高可用

! Configuration File for keepalived

global_defs {
   router_id mysql_ha
}
vrrp_script check_run {
    script "/etc/keepalived/check_mysql.sh"
    interval 2
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 200
    priority 99
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1200
    }
   
  track_script {
         check_run
     }

   virtual_ipaddress {
      192.168.3.99/24
    }
}

vrrp_instance VI_2 {
    state BACKUP
    interface eth0
    virtual_router_id 201
    priority 99
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1200
    }
   
   virtual_ipaddress {
      192.168.3.98/24
    }
}
virtual_server 192.168.3.99/24 3306 { 
delay_loop 5 
lb_algo rr 
lb_kind DR 
persistence_timeout 120
protocol TCP
sorry_server 192.168.3.99 3306
real_server 192.168.3.101 3306 {
  weight 1
  MISC_CHECK {
  misc_path "/etc/keepalived/check_slave.sh -udba_monitor -p123456 -h10.103.9.204 -P3306"
  misc_dynamic
  }
}
real_server 192.168.3.102 3306 {
weight 1
MISC_CHECK {
  misc_path "/etc/keepalived/check_slave.sh -udba_monitor -p123456 -h10.103.9.205 -P3306"
  misc_dynamic
  }
}

delay_loop :健康檢查時間,單位秒
lb_algo :lvs負載均衡調度演算法,rr:輪詢演算法
lb_kind :lvs實現負載均衡的機制,有NAT,TUN,DR三種模式
persistence_timeout:會話保存時間,單位秒,如果要做session保持,可以將值設大點,可以保證同一個連接在指定時間內都會讀取到同一臺客戶端伺服器
sorry_server :後端所有伺服器失效後,就會訪問此伺服器

check_slave.sh 用來監測slave伺服器是否可用,當slave伺服器宕機或者slave伺服器延遲比較大時,腳本會把此slave伺服器從lvs的讀列表中去掉

腳本內容如下

#/bin/bash
# check_slave.sh
MYSQL=`which mysql`
VIP=192.168.3.98
VPORT=3306 
function usage()  
{  
  echo "usage:"  
  echo "example:# mysql -umonitor -pmonitor -P3306 -h192.168.3.100"  
  echo "-p, --password[=name]"  
  echo "-P, --port"  
  echo "-h, --host=name"  
  echo "-u, --user=name"  
}  
  
  
while getopts "u:p:h:P:" option  
do  
    case "$option" in  
        u)  
            dbuser="$OPTARG";;  
        p)  
            dbpwd="$OPTARG";;  
        h)  
            dbhost="$OPTARG";;  
        P)  
            dbport="$OPTARG";;  
        \?)  
            usage  
            exit 1;;  
    esac  
done  
  
if [ "-$dbuser" = "-" ]; then  
    usage  
    exit 1  
fi  
  
if [ "-$dbpwd" = "-" ]; then  
    usage  
    exit 1  
fi  
  
if [ "-$dbhost" = "-" ]; then  
    usage  
    exit 1  
fi  
  
if [ "-$dbport" = "-" ]; then  
    usage  
    exit 1  
fi  
  
$MYSQL -u$dbuser -p$dbpwd -P$dbport -h$dbhost -e "select @@version;" >/dev/null 2>&1
if [ $? = 0 ] ;then
  MySQL_ok=1
else
  /sbin/ipvsadm -d -t $VIP:$VPORT -r $dbhost:$VPORT
  exit 1
fi

slave_status=$(${MYSQL} -u$dbuser -p$dbpwd -P$dbport -h$dbhost -e 'show slave status \G' | awk ' \
  /Slave_IO_Running/{io=$2} \
  /Slave_SQL_Running/{sql=$2} \
  /Seconds_Behind_Master/{printf "%s %s %d\n",io,sql,$2}') >/dev/null 2>&1


arr=($slave_status)
io=${arr[0]}
sql=${arr[1]}
behind=${arr[2]}




if [ "$io" == "No" ]||[ "$sql" == "No" ]; then  
    /sbin/ipvsadm -d -t $VIP:$VPORT -r $dbhost:$VPORT
    exit 1  
elif [ $behind -gt 60 ]; then
    /sbin/ipvsadm -d -t $VIP:$VPORT -r $dbhost:$VPORT
    exit 1
else
    /sbin/ipvsadm -a -t $VIP:$VPORT -r $dbhost:$VPORT -g
    exit 0  
fi  

5. 創建lvs用於監控後端資料庫所使用的資料庫賬號

[root@Node1 keepalived]# mysql  -uroot -p

mysql> grant all privileges on *.* to dba_monitor@'192.168.3.%' identified  by '123456';

6. 在使用lvs的manage伺服器上編寫並運行lvs所需要的腳本

在 192.168.3.100 上編寫腳本lvsdr

/etc/init.d/lvsdr 腳本文件內容如下

#!/bin/bash 
VIP=192.168.3.98
DEV=eth0 
. /etc/rc.d/init.d/functions 
case "$1" in 
start) 
echo "1">/proc/sys/net/ipv4/ip_forward 
/sbin/ipvsadm -A -t $VIP:3306 -s rr -p 60 
/sbin/ipvsadm -a -t $VIP:3306 -r 10.103.9.204:3306 -g 
/sbin/ipvsadm -a -t $VIP:3306 -r 10.103.9.205:3306 -g 
/sbin/ipvsadm --start-daemon 
echo "LVS-DR server starts successfully.\n" 
;; 
stop) 
/sbin/route del $VIP >/dev/null 2>&1 
echo "0" >/proc/sys/net/ipv4/ip_forward 
/sbin/ipvsadm -C 
echo "LVS-DR real server stopped." 
;; 
status) 
isLoOn=`/sbin/ifconfig lo:0 | grep "$VIP"` 
isRoOn=`/bin/netstat -rn | grep "$VIP"` 
if [ "$isLoOn" == "" -a "$isRoOn" == "" ]; then 
echo "LVS-DR real server has to run yet." 
else 
echo "LVS-DR real server is running." 
fi 
exit 3 
;; 
*) 
echo "Usage: $0 {start|stop|status}" 
exit 1 
esac 
exit 0 

/etc/init.d/lvsdr 需要具有可執行許可權

運行腳本

[root@Node1 keepalived]#  /etc/init.d/lvsdr start

7. 在從伺服器上訪問虛擬IP,進行測試

[root@Node3 ~]# mysql  -udba_monitor -p123456 -h192.168.3.98 -e"show variables like ''server_id";

可以通過以上命令查看虛擬IP當前所在伺服器的server_id
由於我們persistence_timeout設置的是120秒,所以接下來的120秒如果一直運行以上命令可以發現,一直訪問的是同一個server_id

下麵我們在192.168.3.102上查看一下ipvs的狀態,命令如下

 [root@Node2 init.d]#  ipvsadm -L -n

可以看到 192.168.3.98:3306 對應了兩個伺服器ip 192.168.3.101 和192.168.3.102

接下來我們模擬其中一個伺服器宕機的情況

[root@Node3 ~]# /etc/init.d/mysqld stop

然後我們再來查詢ipvs狀態

 [root@Node1 keepalived]#  ipvsadm -L -n

發現 192.168.3.98:3306 現在只對應了1個伺服器ip 192.168.3.101,而192.168.3.102已被剔除

二. 由資料庫中間層完成讀寫分離

常用中間層軟體有:MysqlProxy、MaxScale、OneProxy 、 ProxySQL等

優點:
1. 由中間件根據查詢語法分析,自動完成讀寫分離
通過判斷SQL語句如果是select語句則使用slave,如果是update、insert、delete、create語句則使用master伺服器,無法判斷的則使用master
2. 對程式透明,對於已有程式不用做任何調整
3. 前面所說到的一些中間層軟體除了能做到讀寫分離外,還具有能對多個只讀資料庫進行負載均衡的功能

缺點:
1. 由於增加了中間層,所以對查詢效率有損耗
2. 對於延遲敏感的業務無法自動在主庫執行

使用MaxScale解決讀壓力大的問題

MaxScale介紹

支持高可用,負載均衡,良好擴展的插件式資料庫中間層軟體

MaxScale允許用戶開發和定製適合自己的插件,目前MaxScale提供的插件功能主要分為5個種類

1. 認證插件

提供資料庫登錄認證的功能

2. 協議插件

負責 MaxScale和外部系統間介面的協議,包括客戶端到MaxScale的介面,以及MaxScale 到後端資料庫的介面

3. 路由插件

ReadConnRoute 用來解決多台讀伺服器的負載均衡
ReadWriteSplit 用來實現讀寫分離

4. 監控插件

用於對後端資料庫進行實時監控,以便將前端請求發送到正確的(即正常的可以對外提供服務的)資料庫中

5. 過濾和日誌插件

提供了簡單的資料庫防火牆功能,可以對某些SQL進行過濾和改寫,可以進行一些簡單的SQL容錯和語句的自動轉換

使用MaxScale

安裝方法自行百度

伺服器信息

MaxScale 節點 192.168.3.102
Master    DB:192.168.3.100
Slave    DB:192.168.3.101
Slave    DB:192.168.3.102

1. 為監控模塊創建mysql賬號

mysql> create user scalemon@'192.168.3.%' identified by '123456';
mysql> grant replication slave,replication client on *.* to scalemon@'192.168.3.%';

2. 為路由模塊創建mysql賬號

用來讀取mysql系統庫下的表,獲取後端資料庫的許可權

mysql> create user scaleroute@'192.168.3.%' identified by '123456';
mysql> grant select on  mysql.* to scaleroute@'192.168.3.%';

3. 對資料庫密碼進行加密

因為maxScale的配置文件是一個文本格式的明文文件,在文件中直接書寫mysql密碼是不安全的

maxScale提供了加密mysql密碼的命令,這個命令是在maxScale節點中運行

[root@Node3 tools]#  maxpassword  /var/lib/maxscale/    123456
E3AEE4B7125B9C76BF742AE6246ECC5C

生成了密碼123456對應的加密字元串

4. 對maxscale進行配置

[root@Node3 tools]#   vim /etc/maxscale.cnf

參數說明

[maxscale]
thread=1    # 不要超過cpu的數量

[server1]
type=server
address=192.168.3.100
port=3306
protocol=MySQLBackend

[server2]
type=server
address=192.168.3.101
port=3306
protocol=MySQLBackend

[server3]
type=server
address=192.168.3.102
port=3306
protocol=MySQLBackend


[MySQL Monitor]
type=monitor
module =mysqlmon
servers=server1,server2,server3
user=scalemon
passwd=E3AEE4B7125B9C76BF742AE6246ECC5C    # 使用剛剛的加密字元串
monitor_interval=1000    # 毫秒

[Read-Write Service]
type=service
router=readwritesplit
servers=server1,server2,server3
user=scalerouter
passwd=E3AEE4B7125B9C76BF742AE6246ECC5C    # 使用剛剛的加密字元串
max_slave_connections=100%
max_slave_replication_lag=60    

[MaxAdmin Service]
type=service
router=cli

[Read-Write Listener]
type=listener
service=Read-Write Service
protocol=MySQLClient
port=4006

[MaxAdmin Listener]
type=listener
service=MaxAdmin Service
protocol=maxscaled
port=6603

5. 啟動maxscale服務

[root@Node3 tools]# maxscale -f /etc/maxscale.cnf

6. 查看maxscale服務狀態

maxscale是使用maxadmin進行管理的,預設賬號是admin,密碼是mariadb

 [root@Node3 tools]#    maxadmin --user=admin --password=mariadb
# 查看後端伺服器列表
MaxScale> list servers

# 查看是否讀取到了後端資料庫伺服器的賬號
MaxScale> show dbusers "Read-Write Service"

引入MaxScale後的架構

將雙主架構改為了單主架構,因為MaxScale會自動識別後端伺服器的角色,如果使用雙主架構,則無法分清當前的主是哪一個


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

-Advertisement-
Play Games
更多相關文章
  • 當安裝好了 Windows 和 Ubuntu 雙系統之後,預設的啟動項是 Ubuntu,我們可以來設置預設的啟動項, 開機時,在啟動項選擇處,可以通過↑↓ 鍵來選擇啟動哪個系統,第一行序號是 0 ,第二行 序號是 1,依次類推, 博主的只有 4 項,也就是 4 行,Ubuntu 在第一行,對應序號 ...
  • 對於使用校園網的學生來說,安裝好Ubuntu之後,很多人需要用 DrClient 客戶端來上網,那麼怎麼操作呢, 這裡介紹 DrClient 客戶端在Ubuntu上的使用方法, 首先下載 對應版本的軟體包,,有 Linux 64位 和 Linux 32位,然後解壓,打開文件夾, 這個時候雙擊 DrC ...
  • 《Orange'S 一個操作系統的實現》源代碼 《Linux 0.11 內核完全註釋》源代碼 閑來無事,在 64 位 ubuntu-16 中,把 Orange'S 和 linux-0.11 又重新實現了一遍,運行無誤。 這兩本書,可在百度中搜索獲取,自不待言。 Orange‘S 需要註意的是,為 < ...
  • 目錄 一、製作linux啟動盤 1.1. 準備工作 1.2. 製作linux系統U盤 二、使用U盤安裝Centos7.6 2.1. 使用U盤啟動 2.2. 更改安裝配置 2.3. 開始安裝 回到頂部 一、製作linux啟動盤 使用光碟刻錄軟體將系統鏡像刻錄到U盤後使用U盤安裝系統。 1、 準備 1個 ...
  • 自上而下從應用層到底層分析 app: QQ、微信、游戲、控制界面 GUI圖形用戶界面(Graphical User Interface,簡稱 GUI,又稱圖形用戶介面):QT(C++)、Android(java)、GTK(C) 文件系統 內核:Linux、Android、windows Bootlo ...
  • [root@nfs01 backup]# rsync -avz /backup [email protected]::backupPassword: @ERROR: auth failed on module backuprsync error: error starting clie ...
  • 博主的電腦是Win10系統,在修改完系統的用戶文件夾名後,桌面右擊出現了反應卡頓的現象,並且點擊輸入法,也變得卡頓。問題解決後,於是想簡單記錄一下。 還是註冊表的問題,使用Win+R快捷鍵,打開運行,輸入regedit,開啟註冊表編輯器,按照路徑順序打開 HKEY_CLASSES_ROOT\Dire ...
  • 一. 回憶主從複製的一些缺點 上節說到主從複製的一些問題 我們再來回憶一下 主從複製,增加了一個資料庫副本,從資料庫和主資料庫的數據最終會是一致的 之所以說是最終一致,因為mysql複製是非同步的,正常情況下主從複製數據之間會有一個微小的延遲 通過這個資料庫副本看似解決了資料庫單點問題,但並不完美 因 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...