Percona Mysql Galera多讀寫集群部署生產環境實記
阿新 • • 發佈:2018-12-07
trap sum 數據表 -- select interval red pau ads 一、部署MySQL:
yum install https://www.percona.com/redir/downloads/percona-release/redhat/latest/percona-release-0.1-6.noarch.rpm -y 安裝percona的倉庫文件。
yum install Percona-XtraDB-Cluster-57 percona-toolkit -y 安裝數據庫
修改配置文件:/etc/my.cnf
[mysqld]
datadir = /storage/DBdata #數據庫存放的目錄
pid-file = /usr/local/mysql/mysqld.pid
port = 3306
socket = /var/lib/mysql/mysql.sock
user = mysql
#####修改事務隔離級別####
transaction-isolation = READ-COMMITTED
default_storage_engine = InnoDB
default-time_zone = ‘+8:00‘ #修改mysql日誌中的時區。
log_timestamps=SYSTEM
#InnoDB
innodb_file_per_table = 1
innodb_flush_method = O_DIRECT
#name-resolve
skip-host-cache
explicit_defaults_for_timestamp = true
#character-set
character-set-server = utf8
collation-server = utf8_general_ci
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
max_connections = 5000 #允許的最大連接數
#fix up table open cache too small
table_open_cache = 1024
open_files_limit = 65535
ignore-db-dir=lost+found
#LOG
log-error=/var/log/mysqld.log
general_log_file=/var/log/mysql-general.log #調試時開啟下面的general_log=ON,正常運行後需要關閉
general_log=OFF
slow_query_log=ON
long_query_time = 5
slow_query_log_file = /var/log/mysql-slow.log
log_queries_not_using_indexes=false
server-id = 1 #集群中每個主機的ID需要不一樣。
log-bin = /usr/local/mysql/binlogs/mysql-bin #binlog的日誌,最好和數據庫目錄放在不同的物理磁盤中。日誌作用是用來做數據同步的。
expire_logs_days = 10 #保存的時間,如果其它節點宕機10天以後啟動加入集群將會做數據的完全同步。如果在宕機後的第九天加入集群將會接著關機時的狀態進行數據同步。
skip-name-resolve
relay-log = mysqld-relay-bin
innodb_support_xa = 1
relay_log_purge = 0
innodb_print_all_deadlocks = on
sync_binlog=2
#slave-skip-errors = all
#優化配置
join_buffer_size = 2M
sort_buffer_size = 2M
key_buffer_size=512M
read_rnd_buffer_size=2M
query_cache_type=1
query_cache_size=6M
tmp_table_size = 512M
innodb_thread_concurrency=64
innodb_buffer_pool_size=10G
max_binlog_size = 1G
max_relay_log_size = 1G
innodb_lock_wait_timeout=120
#innodb_data_file_path = ibdata1:1G:autoextend
#審計日誌配置 審計的配置第一次需要註釋掉,啟動完以後進入到mysql裏面命令安裝插件等操作
#audit_log_file=‘/var/log/mysql-audit.json‘
#audit_log_format=JSON
#audit_log_policy=QUERIES
#audit_log_rotate_on_size=4096
#audit_log_rotations=7
#audit_log_include_commands=‘create,update,insert,drop,grant,delete,select‘ #審計日誌的sql命令類型。
#新增配置
innodb_log_file_size=20M
binlog_stmt_cache_size=1M
binlog_cache_size=1M
table_open_cache=5000
#Start For Mysql Zabbix plugin
binlog_stmt_cache_size=1M
binlog_cache_size=1M
#End For Mysql Zabbix plugin
log-queries-not-using-indexes = false
gtid_mode=ON
enforce_gtid_consistency=on
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
#galera config 集群相關配置
wsrep_provider=/usr/lib64/libgalera_smm.so
wsrep_cluster_address=gcomm://192.168.2.181,192.168.2.183,192.168.2.185 #集群中的主機,根據實際情況填寫。
wsrep_slave_threads=16
innodb_autoinc_lock_mode=2
wsrep_node_address=192.168.2.181 #本機用來做數據同步的IP地址,這裏的地址可以和用來做服務的地址在不同網段。
wsrep_sst_method=xtrabackup-v2 #同步方式
pxc_strict_mode=MASTER #同步模式
wsrep_cluster_name=mysql-cluster #集群名稱
wsrep_sst_auth="sstuser:s3creV9228s@#%" #用於檢查同步情況的帳號和密碼,可以只授權本地主機訪問。
[client]
socket = /var/lib/mysql/mysql.sock
port = 3306
配置完第一臺主機後需要使用service mysql@bootstrap start啟動第一臺主機。註意這個命令只在初始化集群的時候使用,如果集群已經啟動過以後請使用service mysql start命令正常啟動。包括集群中所有主機宕機以後的恢復。
centos7以上的系統請使用systemctl start [email protected] 和systemctl start mysql命令。
啟動完成以後創建同步帳號:
CREATE USER ‘sstuser‘@‘localhost‘ IDENTIFIED BY ‘s3creV9228s@#%‘;
GRANT RELOAD, LOCK TABLES,REPLICATION CLIENT ON . TO‘sstuser‘@‘localhost‘;
請註意數據庫目錄和binlog等目錄的權限,一定要是mysql。修改權限請使用chown mysql:mysql 目錄名 -R 命令修改。啟動具體報錯請查看日誌文件。
如果是從其它版本的數據庫中遷移過來的數據,請使用mysql_upgrade -u root -p命令對數據庫文件進行更新。否則可能無法正常訪問數據表。
檢查日誌文件以後全部正常,數據庫能正常操作訪問以後第一臺主機就啟動完成了。
接下來是加入新節點。
在其它主機上安裝好程序,創建好相關的文件目錄把配置文件/etc/my.cnf復制過去。修改配置文件中的server-id、wsrep_node_address兩個參數。然後使用service mysql start 或systemctl start mysql命令啟動數據庫,新加入的節點將會自動從主數據庫中同步所有數據到新節點中。可以訪問主數據庫performance_schema.pxc_cluster_view表查看集群中節點的狀態。SYNCED表示可用,JOIN表示正在加入,DONOR表示正在同步。具體請查看percona的官方文檔。
新節點加入時請監控新節點的啟動日誌文件,排查相關錯誤。
啟動同步節點報錯
WSREP_SST: [ERROR] xtrabackup_checkpoints missing, failed innobackupex/SST on donor
檢查主數據庫目錄下的innobackup.backup.log 日誌文件查看具體原因。
所有節點全部加入集群以後,請把第一臺節點使用service mysql@bootstrap stop 或者systemctl stop [email protected]停止。再使用正常的命令啟動。這樣整個percona的galare集群就配置完成了。
二、部署負載均衡服務haproxy和keepalive高可用
yum install haproxy keepalive -y 安裝程序包。這裏需要兩個主機,配置不用太高。最好是數據庫以外的主機來進行安裝部署。這裏需要規劃出一個浮動地址用於高可用。
配置vi /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 50000 #整個服務的最大鏈接數
user root
group root
daemon
#turn on stats unix socket 做zabbix監控時需要
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option tcplog
option dontlognull
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout server 60m #做數據庫需要配置1小時左右,60m可以是1h效果一樣
timeout client 60m #做數據庫需要配置1小時左右
timeout http-keep-alive 10s
timeout check 3s
listen stats #網頁監控相關配置
bind :9099
stats uri /nstatus
stats enable
stats realm HAPorxy\ Stats\ Page
stats auth monitor:Hawatch2.tz.Com
stats admin if TRUE
listen mysql-cluster #負載均衡的服務配置
bind 0.0.0.0:3306
mode tcp
fullconn 13500 #提供的最大後端總鏈接數
balance leastconn #負載均衡的模式,經過測試這個模式是最適合mysql服務的。最小鏈接數優先
option httpchk
option tcplog
server db01 192.168.2.181:3306 maxqueue 30 maxconn 4500 check port 9200 inter 1000 rise 3 fall 3
server db02 192.168.2.183:3306 maxqueue 30 maxconn 4500 check port 9200 inter 1000 rise 3 fall 3
server db03 192.168.2.185:3306 maxqueue 30 maxconn 4500 check port 9200 inter 1000 rise 3 fall 3
db01可以是任意內容,每行代表一個後端主機不能重復。db01.example.com:3306 主機域名或者IP地址端口。maxqueue 建立後端連接時的最大列隊,防止服務器處理不過來後臺被宕機。maxconn 服務器最大鏈接數,需要小於數據庫的真實鏈接數配置。check port 9200 檢查後端服務是否正常的端口。
通過以上配置後可以正常啟動haproxy服務了。service haproxy start 或systemctl start haproxy。然後打開網頁後端進行查看服務器狀態。這時可能還無法正常提供服務,需要對mysql的後端做一些配置。
到後端的數據庫服務器上安裝xinetd。
yum install xinetd -y
/etc/xinetd.d/mysqlchk #提供檢查端口的配置文件。
/usr/bin/clustercheck #檢查結果的腳本,需要修改這個腳本中兩個參數。
MYSQL_USERNAME="${1-sstuser}"
MYSQL_PASSWORD="${2-s3creV9228s@#%}" 檢查狀態的帳號密碼可以用數據庫同步的帳號密碼。
然後啟動xinetd服務,service xinetd start或者systemctl start xinetd。啟動成功後再查看haproxy的監控頁面就會發現後端服務變成可用狀態了。
haproxy的日誌需要配置rsyslog服務。
vi /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
.info;mail.none;authpriv.none;cron.none;local2.none /var/log/messages
local2. /var/log/haproxy.log
上面的local2編號需要和haproxy配置文件中的一樣。配置完以後重啟service rsyslog restart。然後在/var/log/haproxy.log中就有日誌文件了。
把上面haproxy的復制一份到另外一臺主機上。配置rsyslog以後重啟rsyslog服務,再啟動haproxy就擁有了兩臺主機了。
配置keepalived實現高可用:
編輯vi /etc/keepalived/keepalived.conf 文件。
global_defs {
router_id mysql
}
vrrp_script check_ha {
script "/opt/share/selfTools/check_haproxy" #用於檢測服務的腳本。需要自己編寫,成功返回0失敗返回非0的值,目錄可以自己定義。
interval 2
}
vrrp_instance ha01 { #這個編號需要每個主機不一樣
state BACKUP #兩個都設置成BACKUP模式,可以避免頻繁切換引發應用不穩定。
interface eth0 #綁定的網卡名稱
virtual_router_id 22 #兩個主機需要一樣。
priority 100
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
check_ha
}
virtual_ipaddress {
192.168.2.191/24 dev eth0 scope global #浮動地址配置
}
}
腳本配置:/opt/share/selfTools/check_haproxy
#!/bin/bash
nc -z 127.0.0.1 3306 #檢查本機的haproxy服務端口是否存在
status=$?
nc -z 127.0.0.1 9099 #檢查haproxy的狀態監控端口是否存在
status=$(($?+$status))
exit $status #返回腳本運行的退出值
這裏需要在主機上安裝nc。yum install nc -y
啟動keepalived,service keepalived start 。然後檢查浮動地址情況。把配置文件復制一份到另外的主機上,修改vrrp_instance ha01的名稱。其它保持不變,啟動keepalived服務即可。
到這裏就算配置完成了,業務訪問浮動地址就能直接分配到後端的數據庫服務器上。
三、監控服務
數據庫集群監控,安裝percona-zabbix-templates-1.1.8-1.noarch 、php包。
復制userparameter_percona_mysql.conf文件到/etc/zabbix/zabbix_agentd.d/目錄下。
編輯文件vi /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php 填寫mysql的監控帳號和密碼然後保存。
檢查zabbix.conf文件中是否有Include=/etc/zabbix/zabbix_agentd.d/.conf這個配置。沒有請添加。
模版需要自己到zabbix監控裏面配置,我的模版無法把文件上傳上來。
percona的監控腳本還不能用於監控集群狀態。需要自行編寫腳本來監控。在zabbix的配置文件中添加兩個內容。
UserParameter=Galera.discovery,/opt/share/shell/galera/galera_discovery.sh
UserParameter=Galera.[],/opt/share/shell/galera/galera_status.sh $1
腳本/opt/share/shell/galera/galera_discovery.sh內容:
#!/bin/bash
sql="show status like ‘wsrep%‘;"
galeras=(
text=(wsrep_local_state_uuid wsrep_flow_control_interval wsrep_local_state_comment wsrep_incoming_addresses wsrep_ist_receive_status wsrep_evs_repl_latency wsrep_evs_state wsrep_gcomm_uuid wsrep_cluster_state_uuid wsrep_cluster_status wsrep_connected wsrep_provider_name wsrep_provider_vendor wsrep_provider_version wsrep_ready)
float=(wsrep_cert_interval wsrep_commit_window wsrep_commit_oool wsrep_commit_oooe wsrep_apply_window wsrep_apply_oool wsrep_apply_oooe wsrep_cert_deps_distance wsrep_flow_control_paused wsrep_local_recv_queue_avg wsrep_local_send_queue_avg)
printf ‘{"data":[‘
i=1
for option in ${galeras[@]}
do
if [[
printf ‘{"{#TEXT}":"‘$option
elif [[
printf ‘{"{#FLOAT}":"‘$option
else
printf ‘{"{#OTNAME}":"‘$option
fi
if [ $i -lt ${#galeras[@]} ];then
printf ‘"},‘
else
printf ‘"}]}\n‘
fi
i=$(($i+1))
done
腳本/opt/share/shell/galera/galera_status.sh內容:
#!/bin/bash
sql="show status like ‘$1‘;"
if [ -z $2 ];then
echo "set names utf8;$sql" |HOME=/opt/share/shell/galera mysql -N | awk ‘{print $2}‘
else
echo "set names utf8;$sql" |HOME=/opt/share/shell/galera mysql -h$2 -N | awk ‘{print $2}‘
fi
四、擴展解決方案
1、在使用HAproxy以後mysql中日誌與客戶端IP相關的信息將全部變成haproxy服務器的地址。
啟用haproxy的透傳功能,把客戶端IP通過haproxy傳給realserver。數據包到達realserver以後將無法直接把數據返回給客戶端的真實IP,這將無法建立tcp的鏈接。所以需要把數據包返回給haproxy服務器。haproxy拿到數據包以後需要截取到相關數據包傳給haproxy進程處理才能完成整個tcp的鏈接建立。具體看圖:
需要完成圖中的幾步才能完成整個建立過程。具體配置方法:
1)、配置haproxy。在配置的listen中加入source 0.0.0.0 usesrc clientip這樣的配置。
2)、配置數據包截取:
配置/etc/sysctl.conf,添加 一下內容
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.eth0.rp_filter = 0
執行命令,執行完以後還需要配置開啟自動運行。iptables相關規則可以保存後執行加載,路由表需要每次開機都進行創建。
iptables -t mangle -N MYSQL #單獨在mangle表中創建一個名為MYSQL的鏈表
iptables -t mangle -A PREROUTING -m state --state RELATED,ESTABLISHED -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp -m socket -j MYSQL #從mangle表中的PREROUTING鏈中截取數據包是tcp協議,並且為socket的數據包。轉發到MYSQL鏈表中。
iptables -t mangle -A MYSQL -j MARK --set-mark 1 #在MYSQL鏈表中把進來的數據包打上標簽為1
iptables -t mangle -A MYSQL -j ACCEPT #接受所有數據包通過。
ip rule add fwmark 1 lookup 3306 #經過上面的數據包標記,在系統內核中就能分辨相關的數據包內容。這裏新建一個路由表編號3306為數據包標記為1的路由。
ip route add local 0.0.0.0/0 dev lo table 3306 #在3306路由表中創建一條路由規則,把進入3306表中的數據包默認路由給本地環回口。這樣haproxy就能拿到相關的數據包進行處理了。
3)、以上兩步是在HAROXY的服務器上配置。這步將在後端的真實服務器上進行配置。
iptables -t mangle -N MYSQL #添加鏈表,意義同上
iptables -t mangle -A OUTPUT -p tcp --sport 3306 -j MYSQL #這裏需要從OUTPUT鏈表中截取數據包,其它鏈表無效。具體原因請看下面的LINUX數據包轉發圖。獲取源端口為3306的數據包,因為是OUTPUT出方向所以是源端口。
iptables -t mangle -A MYSQL -j MARK --set-mark 1 #進行數據包標記。
iptables -t mangle -A MYSQL -j ACCEPT #接受所有數據包通過
ip rule add fwmark 1 table 3306 #功能同上,創建新的路由表。
ip route add default via 192.168.2.191 table 3306 #添加默認路由,下一跳給到HAPROXY。
這裏可以不進行數據包的截取標記也可以讓業務正常,只需要添加一跳默認路由,ip route default via HAPROXY_IP。這樣就能實現,但是ssh等其它服務將不能正常連接。
4)、可以代替第三節。主要是如果直接更改就沒有對比了。下面的命令也是直接在數據庫服務器上做的。
iptables -t mangle -A PREROUTING -m state --state RELATED,ESTABLISHED -j CONNMARK --restore-mark #已經建立的鏈接自動附上標記
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT # 已經有標記的數據包直接放行,不進入下面匹配。提高處理效率。
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 3306 -m mac --mac-source 00:50:56:a0:13:a2 -j MARK --set-mark 1 #這裏的MAC地址是HAPROXY服務器的網卡地址。
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 3306 -m mac --mac-source 00:50:56:81:4F:08 -j MARK --set-mark 2 #我們有兩個haproxy所以要兩個標記
iptables -t mangle -A PREROUTING -j CONNMARK --save-mark #把這個做好標記的鏈路上所有數據包都保存好標記。
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark #前面做的都是客戶端訪問到主機時數據包的入方向,這句如果不加將無法路由出去。OUTPUT鏈是把數據包按照入方向標記好的記錄,重新賦予相關的標記。讓路由可以正確拿到出去的數據包。
ip rule add fwmark 1 table 3301
ip route add default via 192.168.2.150 table 3301 #這兩條是對數據包進行路由,IP地址是haproxy的真實網卡地址。也就是上面mac地址為00:50:56:a0:13:a2主機IP地址,非浮動地址。
ip rule add fwmark 2 table 3302
ip route add default via 192.168.2.153 table 3302 #這兩條和上面功能一樣,IP地址是mac地址為00:50:56:81:4F:08的主機IP地址。
這裏不用填寫浮動地址,這樣不管浮動地址在哪裏。或者訪問任何一個主機都可以正常連接數據庫。
如果按照前面第三節的方法處理以後,客戶端無法直接鏈接數據庫、而且正常情況下也無法去訪問沒有浮動地址的那個服務器。第四節的方法處理以後將和沒有使用集群一樣,鏈接和訪問沒有任何差異。
2、haproxy服務器的狀態監控。
在服務器zabbix中配置兩項/etc/zabbix/zabbix_agentd.conf。
UserParameter=ha.discovery,/opt/share/shell/zabbix-script/haproxy/haproxy_discovery.sh
UserParameter=Haproxy.[*],/opt/share/shell/zabbix-script/haproxy/haproxy_get.sh $1
haproxy_discovery.sh:
#!/bin/bash
node=(
options=(qcur qmax scur smax stot status)
printf ‘{"data":[‘
i=1
for name in ${node[@]}
do
n=1
for op in ${options[@]}
do
if [ $n -lt ${#options[@]} ];then
printf ‘{"{#NODE}":"‘$name-$op
else
printf ‘{"{#TEXT}":"‘$name-$op
fi
if [ $i -lt ${#node[@]} ] || [ $n -lt ${#options[@]} ];then
printf ‘"},‘
else
printf ‘"}]}\n‘
fi
n=$(($n+1))
done
i=$(($i+1))
done
haproxy_get.sh:
#!/bin/bash
cd
values=(
case ${values[1]} in
"qcur")
grep ${values[0]} status.txt | awk ‘{print $2}‘
;;
"qmax")
grep ${values[0]} status.txt | awk ‘{print $3}‘
;;
"scur")
grep ${values[0]} status.txt | awk ‘{print $4}‘
;;
"smax")
grep ${values[0]} status.txt | awk ‘{print $5}‘
;;
"stot")
grep ${values[0]} status.txt | awk ‘{print $6}‘
;;
"status")
grep ${values[0]} status.txt | awk ‘{print $7}‘
;;
esac
為減少對haproxy的沖擊。創建一個定時計劃任務,定期獲取狀態數據保存到文件中。
haproxy_status.sh:
#!/bin/bash
cd
echo "show stat" | socat /var/lib/haproxy/stats stdio | sed "s/#//g" | awk ‘BEGIN {FS=","}{print $2"\t"$3"\t"$4"\t"$5"\t"$6"\t"$8"\t"$18}‘ > status.txt
如果沒有socat命令需要使用yum安裝。/var/lib/haproxy/stats這個文件需要有權限訪問,用chmod 606來調整。
zabbix的調試可以在zabbix-server服務器上使用zabbix_get命令進行調試。如:
zabbix_get -s 192.168.2.150 -k ‘Haproxy.[db02-scur]‘ 其中的key是被監控主機自定義的字段名稱。
同樣模版的建立,請大家自行處理。無法上傳模版文件共享。
本文章只是提供一個拋磚引玉的作用,需要的基礎知識比較多,具體問題請自行解決。
yum install https://www.percona.com/redir/downloads/percona-release/redhat/latest/percona-release-0.1-6.noarch.rpm -y 安裝percona的倉庫文件。
yum install Percona-XtraDB-Cluster-57 percona-toolkit -y 安裝數據庫
修改配置文件:/etc/my.cnf
[mysqld]
datadir = /storage/DBdata #數據庫存放的目錄
pid-file = /usr/local/mysql/mysqld.pid
port = 3306
socket = /var/lib/mysql/mysql.sock
#####修改事務隔離級別####
transaction-isolation = READ-COMMITTED
default_storage_engine = InnoDB
default-time_zone = ‘+8:00‘ #修改mysql日誌中的時區。
log_timestamps=SYSTEM
#InnoDB
innodb_file_per_table = 1
innodb_flush_method = O_DIRECT
#name-resolve
skip-host-cache
explicit_defaults_for_timestamp = true
#character-set
collation-server = utf8_general_ci
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
max_connections = 5000 #允許的最大連接數
#fix up table open cache too small
table_open_cache = 1024
open_files_limit = 65535
ignore-db-dir=lost+found
#LOG
log-error=/var/log/mysqld.log
general_log_file=/var/log/mysql-general.log #調試時開啟下面的general_log=ON,正常運行後需要關閉
slow_query_log=ON
long_query_time = 5
slow_query_log_file = /var/log/mysql-slow.log
log_queries_not_using_indexes=false
server-id = 1 #集群中每個主機的ID需要不一樣。
log-bin = /usr/local/mysql/binlogs/mysql-bin #binlog的日誌,最好和數據庫目錄放在不同的物理磁盤中。日誌作用是用來做數據同步的。
expire_logs_days = 10 #保存的時間,如果其它節點宕機10天以後啟動加入集群將會做數據的完全同步。如果在宕機後的第九天加入集群將會接著關機時的狀態進行數據同步。
skip-name-resolve
relay-log = mysqld-relay-bin
innodb_support_xa = 1
relay_log_purge = 0
innodb_print_all_deadlocks = on
sync_binlog=2
#slave-skip-errors = all
#優化配置
join_buffer_size = 2M
sort_buffer_size = 2M
key_buffer_size=512M
read_rnd_buffer_size=2M
query_cache_type=1
query_cache_size=6M
tmp_table_size = 512M
innodb_thread_concurrency=64
innodb_buffer_pool_size=10G
max_binlog_size = 1G
max_relay_log_size = 1G
innodb_lock_wait_timeout=120
#innodb_data_file_path = ibdata1:1G:autoextend
#審計日誌配置 審計的配置第一次需要註釋掉,啟動完以後進入到mysql裏面命令安裝插件等操作
#audit_log_file=‘/var/log/mysql-audit.json‘
#audit_log_format=JSON
#audit_log_policy=QUERIES
#audit_log_rotate_on_size=4096
#audit_log_rotations=7
#audit_log_include_commands=‘create,update,insert,drop,grant,delete,select‘ #審計日誌的sql命令類型。
#新增配置
innodb_log_file_size=20M
binlog_stmt_cache_size=1M
binlog_cache_size=1M
table_open_cache=5000
#Start For Mysql Zabbix plugin
binlog_stmt_cache_size=1M
binlog_cache_size=1M
#End For Mysql Zabbix plugin
log-queries-not-using-indexes = false
gtid_mode=ON
enforce_gtid_consistency=on
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
#galera config 集群相關配置
wsrep_provider=/usr/lib64/libgalera_smm.so
wsrep_cluster_address=gcomm://192.168.2.181,192.168.2.183,192.168.2.185 #集群中的主機,根據實際情況填寫。
wsrep_slave_threads=16
innodb_autoinc_lock_mode=2
wsrep_node_address=192.168.2.181 #本機用來做數據同步的IP地址,這裏的地址可以和用來做服務的地址在不同網段。
wsrep_sst_method=xtrabackup-v2 #同步方式
pxc_strict_mode=MASTER #同步模式
wsrep_cluster_name=mysql-cluster #集群名稱
wsrep_sst_auth="sstuser:s3creV9228s@#%" #用於檢查同步情況的帳號和密碼,可以只授權本地主機訪問。
[client]
socket = /var/lib/mysql/mysql.sock
port = 3306
配置完第一臺主機後需要使用service mysql@bootstrap start啟動第一臺主機。註意這個命令只在初始化集群的時候使用,如果集群已經啟動過以後請使用service mysql start命令正常啟動。包括集群中所有主機宕機以後的恢復。
centos7以上的系統請使用systemctl start [email protected] 和systemctl start mysql命令。
啟動完成以後創建同步帳號:
CREATE USER ‘sstuser‘@‘localhost‘ IDENTIFIED BY ‘s3creV9228s@#%‘;
GRANT RELOAD, LOCK TABLES,REPLICATION CLIENT ON . TO‘sstuser‘@‘localhost‘;
請註意數據庫目錄和binlog等目錄的權限,一定要是mysql。修改權限請使用chown mysql:mysql 目錄名 -R 命令修改。啟動具體報錯請查看日誌文件。
如果是從其它版本的數據庫中遷移過來的數據,請使用mysql_upgrade -u root -p命令對數據庫文件進行更新。否則可能無法正常訪問數據表。
檢查日誌文件以後全部正常,數據庫能正常操作訪問以後第一臺主機就啟動完成了。
接下來是加入新節點。
在其它主機上安裝好程序,創建好相關的文件目錄把配置文件/etc/my.cnf復制過去。修改配置文件中的server-id、wsrep_node_address兩個參數。然後使用service mysql start 或systemctl start mysql命令啟動數據庫,新加入的節點將會自動從主數據庫中同步所有數據到新節點中。可以訪問主數據庫performance_schema.pxc_cluster_view表查看集群中節點的狀態。SYNCED表示可用,JOIN表示正在加入,DONOR表示正在同步。具體請查看percona的官方文檔。
新節點加入時請監控新節點的啟動日誌文件,排查相關錯誤。
啟動同步節點報錯
WSREP_SST: [ERROR] xtrabackup_checkpoints missing, failed innobackupex/SST on donor
檢查主數據庫目錄下的innobackup.backup.log 日誌文件查看具體原因。
所有節點全部加入集群以後,請把第一臺節點使用service mysql@bootstrap stop 或者systemctl stop [email protected]停止。再使用正常的命令啟動。這樣整個percona的galare集群就配置完成了。
二、部署負載均衡服務haproxy和keepalive高可用
yum install haproxy keepalive -y 安裝程序包。這裏需要兩個主機,配置不用太高。最好是數據庫以外的主機來進行安裝部署。這裏需要規劃出一個浮動地址用於高可用。
配置vi /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 50000 #整個服務的最大鏈接數
user root
group root
daemon
#turn on stats unix socket 做zabbix監控時需要
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option tcplog
option dontlognull
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout server 60m #做數據庫需要配置1小時左右,60m可以是1h效果一樣
timeout client 60m #做數據庫需要配置1小時左右
timeout http-keep-alive 10s
timeout check 3s
listen stats #網頁監控相關配置
bind :9099
stats uri /nstatus
stats enable
stats realm HAPorxy\ Stats\ Page
stats auth monitor:Hawatch2.tz.Com
stats admin if TRUE
listen mysql-cluster #負載均衡的服務配置
bind 0.0.0.0:3306
mode tcp
fullconn 13500 #提供的最大後端總鏈接數
balance leastconn #負載均衡的模式,經過測試這個模式是最適合mysql服務的。最小鏈接數優先
option httpchk
option tcplog
server db01 192.168.2.181:3306 maxqueue 30 maxconn 4500 check port 9200 inter 1000 rise 3 fall 3
server db02 192.168.2.183:3306 maxqueue 30 maxconn 4500 check port 9200 inter 1000 rise 3 fall 3
server db03 192.168.2.185:3306 maxqueue 30 maxconn 4500 check port 9200 inter 1000 rise 3 fall 3
db01可以是任意內容,每行代表一個後端主機不能重復。db01.example.com:3306 主機域名或者IP地址端口。maxqueue 建立後端連接時的最大列隊,防止服務器處理不過來後臺被宕機。maxconn 服務器最大鏈接數,需要小於數據庫的真實鏈接數配置。check port 9200 檢查後端服務是否正常的端口。
通過以上配置後可以正常啟動haproxy服務了。service haproxy start 或systemctl start haproxy。然後打開網頁後端進行查看服務器狀態。這時可能還無法正常提供服務,需要對mysql的後端做一些配置。
到後端的數據庫服務器上安裝xinetd。
yum install xinetd -y
/etc/xinetd.d/mysqlchk #提供檢查端口的配置文件。
/usr/bin/clustercheck #檢查結果的腳本,需要修改這個腳本中兩個參數。
MYSQL_USERNAME="${1-sstuser}"
MYSQL_PASSWORD="${2-s3creV9228s@#%}" 檢查狀態的帳號密碼可以用數據庫同步的帳號密碼。
然後啟動xinetd服務,service xinetd start或者systemctl start xinetd。啟動成功後再查看haproxy的監控頁面就會發現後端服務變成可用狀態了。
haproxy的日誌需要配置rsyslog服務。
vi /etc/rsyslog.conf
$ModLoad imudp
$UDPServerRun 514
.info;mail.none;authpriv.none;cron.none;local2.none /var/log/messages
local2. /var/log/haproxy.log
上面的local2編號需要和haproxy配置文件中的一樣。配置完以後重啟service rsyslog restart。然後在/var/log/haproxy.log中就有日誌文件了。
把上面haproxy的復制一份到另外一臺主機上。配置rsyslog以後重啟rsyslog服務,再啟動haproxy就擁有了兩臺主機了。
配置keepalived實現高可用:
編輯vi /etc/keepalived/keepalived.conf 文件。
global_defs {
router_id mysql
}
vrrp_script check_ha {
script "/opt/share/selfTools/check_haproxy" #用於檢測服務的腳本。需要自己編寫,成功返回0失敗返回非0的值,目錄可以自己定義。
interval 2
}
vrrp_instance ha01 { #這個編號需要每個主機不一樣
state BACKUP #兩個都設置成BACKUP模式,可以避免頻繁切換引發應用不穩定。
interface eth0 #綁定的網卡名稱
virtual_router_id 22 #兩個主機需要一樣。
priority 100
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
check_ha
}
virtual_ipaddress {
192.168.2.191/24 dev eth0 scope global #浮動地址配置
}
}
腳本配置:/opt/share/selfTools/check_haproxy
#!/bin/bash
nc -z 127.0.0.1 3306 #檢查本機的haproxy服務端口是否存在
status=$?
nc -z 127.0.0.1 9099 #檢查haproxy的狀態監控端口是否存在
status=$(($?+$status))
exit $status #返回腳本運行的退出值
這裏需要在主機上安裝nc。yum install nc -y
啟動keepalived,service keepalived start 。然後檢查浮動地址情況。把配置文件復制一份到另外的主機上,修改vrrp_instance ha01的名稱。其它保持不變,啟動keepalived服務即可。
到這裏就算配置完成了,業務訪問浮動地址就能直接分配到後端的數據庫服務器上。
三、監控服務
數據庫集群監控,安裝percona-zabbix-templates-1.1.8-1.noarch 、php包。
復制userparameter_percona_mysql.conf文件到/etc/zabbix/zabbix_agentd.d/目錄下。
編輯文件vi /var/lib/zabbix/percona/scripts/ss_get_mysql_stats.php 填寫mysql的監控帳號和密碼然後保存。
檢查zabbix.conf文件中是否有Include=/etc/zabbix/zabbix_agentd.d/.conf這個配置。沒有請添加。
模版需要自己到zabbix監控裏面配置,我的模版無法把文件上傳上來。
percona的監控腳本還不能用於監控集群狀態。需要自行編寫腳本來監控。在zabbix的配置文件中添加兩個內容。
UserParameter=Galera.discovery,/opt/share/shell/galera/galera_discovery.sh
UserParameter=Galera.[],/opt/share/shell/galera/galera_status.sh $1
腳本/opt/share/shell/galera/galera_discovery.sh內容:
#!/bin/bash
sql="show status like ‘wsrep%‘;"
galeras=(
echo "set names utf8;$sql" |HOME=/var/lib/zabbix mysql -N | awk ‘{print $1}‘
)text=(wsrep_local_state_uuid wsrep_flow_control_interval wsrep_local_state_comment wsrep_incoming_addresses wsrep_ist_receive_status wsrep_evs_repl_latency wsrep_evs_state wsrep_gcomm_uuid wsrep_cluster_state_uuid wsrep_cluster_status wsrep_connected wsrep_provider_name wsrep_provider_vendor wsrep_provider_version wsrep_ready)
float=(wsrep_cert_interval wsrep_commit_window wsrep_commit_oool wsrep_commit_oooe wsrep_apply_window wsrep_apply_oool wsrep_apply_oooe wsrep_cert_deps_distance wsrep_flow_control_paused wsrep_local_recv_queue_avg wsrep_local_send_queue_avg)
printf ‘{"data":[‘
i=1
for option in ${galeras[@]}
do
if [[
echo "${text[@]}" | grep "\b$option\b"
]] ;thenprintf ‘{"{#TEXT}":"‘$option
elif [[
echo "${float[@]}" | grep "\b$option\b"
]] ;thenprintf ‘{"{#FLOAT}":"‘$option
else
printf ‘{"{#OTNAME}":"‘$option
fi
if [ $i -lt ${#galeras[@]} ];then
printf ‘"},‘
else
printf ‘"}]}\n‘
fi
i=$(($i+1))
done
腳本/opt/share/shell/galera/galera_status.sh內容:
#!/bin/bash
sql="show status like ‘$1‘;"
if [ -z $2 ];then
echo "set names utf8;$sql" |HOME=/opt/share/shell/galera mysql -N | awk ‘{print $2}‘
else
echo "set names utf8;$sql" |HOME=/opt/share/shell/galera mysql -h$2 -N | awk ‘{print $2}‘
fi
四、擴展解決方案
1、在使用HAproxy以後mysql中日誌與客戶端IP相關的信息將全部變成haproxy服務器的地址。
啟用haproxy的透傳功能,把客戶端IP通過haproxy傳給realserver。數據包到達realserver以後將無法直接把數據返回給客戶端的真實IP,這將無法建立tcp的鏈接。所以需要把數據包返回給haproxy服務器。haproxy拿到數據包以後需要截取到相關數據包傳給haproxy進程處理才能完成整個tcp的鏈接建立。具體看圖:
需要完成圖中的幾步才能完成整個建立過程。具體配置方法:
1)、配置haproxy。在配置的listen中加入source 0.0.0.0 usesrc clientip這樣的配置。
2)、配置數據包截取:
配置/etc/sysctl.conf,添加 一下內容
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 2
net.ipv4.conf.all.rp_filter = 2
net.ipv4.conf.eth0.rp_filter = 0
執行命令,執行完以後還需要配置開啟自動運行。iptables相關規則可以保存後執行加載,路由表需要每次開機都進行創建。
iptables -t mangle -N MYSQL #單獨在mangle表中創建一個名為MYSQL的鏈表
iptables -t mangle -A PREROUTING -m state --state RELATED,ESTABLISHED -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp -m socket -j MYSQL #從mangle表中的PREROUTING鏈中截取數據包是tcp協議,並且為socket的數據包。轉發到MYSQL鏈表中。
iptables -t mangle -A MYSQL -j MARK --set-mark 1 #在MYSQL鏈表中把進來的數據包打上標簽為1
iptables -t mangle -A MYSQL -j ACCEPT #接受所有數據包通過。
ip rule add fwmark 1 lookup 3306 #經過上面的數據包標記,在系統內核中就能分辨相關的數據包內容。這裏新建一個路由表編號3306為數據包標記為1的路由。
ip route add local 0.0.0.0/0 dev lo table 3306 #在3306路由表中創建一條路由規則,把進入3306表中的數據包默認路由給本地環回口。這樣haproxy就能拿到相關的數據包進行處理了。
3)、以上兩步是在HAROXY的服務器上配置。這步將在後端的真實服務器上進行配置。
iptables -t mangle -N MYSQL #添加鏈表,意義同上
iptables -t mangle -A OUTPUT -p tcp --sport 3306 -j MYSQL #這裏需要從OUTPUT鏈表中截取數據包,其它鏈表無效。具體原因請看下面的LINUX數據包轉發圖。獲取源端口為3306的數據包,因為是OUTPUT出方向所以是源端口。
iptables -t mangle -A MYSQL -j MARK --set-mark 1 #進行數據包標記。
iptables -t mangle -A MYSQL -j ACCEPT #接受所有數據包通過
ip rule add fwmark 1 table 3306 #功能同上,創建新的路由表。
ip route add default via 192.168.2.191 table 3306 #添加默認路由,下一跳給到HAPROXY。
這裏可以不進行數據包的截取標記也可以讓業務正常,只需要添加一跳默認路由,ip route default via HAPROXY_IP。這樣就能實現,但是ssh等其它服務將不能正常連接。
4)、可以代替第三節。主要是如果直接更改就沒有對比了。下面的命令也是直接在數據庫服務器上做的。
iptables -t mangle -A PREROUTING -m state --state RELATED,ESTABLISHED -j CONNMARK --restore-mark #已經建立的鏈接自動附上標記
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT # 已經有標記的數據包直接放行,不進入下面匹配。提高處理效率。
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 3306 -m mac --mac-source 00:50:56:a0:13:a2 -j MARK --set-mark 1 #這裏的MAC地址是HAPROXY服務器的網卡地址。
iptables -t mangle -A PREROUTING -p tcp -m tcp --dport 3306 -m mac --mac-source 00:50:56:81:4F:08 -j MARK --set-mark 2 #我們有兩個haproxy所以要兩個標記
iptables -t mangle -A PREROUTING -j CONNMARK --save-mark #把這個做好標記的鏈路上所有數據包都保存好標記。
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark #前面做的都是客戶端訪問到主機時數據包的入方向,這句如果不加將無法路由出去。OUTPUT鏈是把數據包按照入方向標記好的記錄,重新賦予相關的標記。讓路由可以正確拿到出去的數據包。
ip rule add fwmark 1 table 3301
ip route add default via 192.168.2.150 table 3301 #這兩條是對數據包進行路由,IP地址是haproxy的真實網卡地址。也就是上面mac地址為00:50:56:a0:13:a2主機IP地址,非浮動地址。
ip rule add fwmark 2 table 3302
ip route add default via 192.168.2.153 table 3302 #這兩條和上面功能一樣,IP地址是mac地址為00:50:56:81:4F:08的主機IP地址。
這裏不用填寫浮動地址,這樣不管浮動地址在哪裏。或者訪問任何一個主機都可以正常連接數據庫。
如果按照前面第三節的方法處理以後,客戶端無法直接鏈接數據庫、而且正常情況下也無法去訪問沒有浮動地址的那個服務器。第四節的方法處理以後將和沒有使用集群一樣,鏈接和訪問沒有任何差異。
2、haproxy服務器的狀態監控。
在服務器zabbix中配置兩項/etc/zabbix/zabbix_agentd.conf。
UserParameter=ha.discovery,/opt/share/shell/zabbix-script/haproxy/haproxy_discovery.sh
UserParameter=Haproxy.[*],/opt/share/shell/zabbix-script/haproxy/haproxy_get.sh $1
haproxy_discovery.sh:
#!/bin/bash
node=(
echo "show stat" | socat /var/lib/haproxy/stats stdio | sed "s/#//g" | awk ‘BEGIN {FS=","}{print $2}‘ |sed ‘/FRONTEND/d;/BACKEND/d;1d;$d‘
)options=(qcur qmax scur smax stot status)
printf ‘{"data":[‘
i=1
for name in ${node[@]}
do
n=1
for op in ${options[@]}
do
if [ $n -lt ${#options[@]} ];then
printf ‘{"{#NODE}":"‘$name-$op
else
printf ‘{"{#TEXT}":"‘$name-$op
fi
if [ $i -lt ${#node[@]} ] || [ $n -lt ${#options[@]} ];then
printf ‘"},‘
else
printf ‘"}]}\n‘
fi
n=$(($n+1))
done
i=$(($i+1))
done
haproxy_get.sh:
#!/bin/bash
cd
dirname $0
values=(
echo $1|awk ‘BEGIN{FS="-"}{print $1" "$2}‘
)case ${values[1]} in
"qcur")
grep ${values[0]} status.txt | awk ‘{print $2}‘
;;
"qmax")
grep ${values[0]} status.txt | awk ‘{print $3}‘
;;
"scur")
grep ${values[0]} status.txt | awk ‘{print $4}‘
;;
"smax")
grep ${values[0]} status.txt | awk ‘{print $5}‘
;;
"stot")
grep ${values[0]} status.txt | awk ‘{print $6}‘
;;
"status")
grep ${values[0]} status.txt | awk ‘{print $7}‘
;;
esac
為減少對haproxy的沖擊。創建一個定時計劃任務,定期獲取狀態數據保存到文件中。
haproxy_status.sh:
#!/bin/bash
cd
dirname $0
echo "show stat" | socat /var/lib/haproxy/stats stdio | sed "s/#//g" | awk ‘BEGIN {FS=","}{print $2"\t"$3"\t"$4"\t"$5"\t"$6"\t"$8"\t"$18}‘ > status.txt
如果沒有socat命令需要使用yum安裝。/var/lib/haproxy/stats這個文件需要有權限訪問,用chmod 606來調整。
zabbix的調試可以在zabbix-server服務器上使用zabbix_get命令進行調試。如:
zabbix_get -s 192.168.2.150 -k ‘Haproxy.[db02-scur]‘ 其中的key是被監控主機自定義的字段名稱。
同樣模版的建立,請大家自行處理。無法上傳模版文件共享。
本文章只是提供一個拋磚引玉的作用,需要的基礎知識比較多,具體問題請自行解決。
Percona Mysql Galera多讀寫集群部署生產環境實記