1. 程式人生 > >MySQL大型叢集架構搭建

MySQL大型叢集架構搭建

轉載出處:http://blog.richyu.com.cn/?p=4
作者:付總(我大佬 )“此處手動滑稽”

mysql 主從搭建
#--------------------ALL---------------------------#
1、配置 yum 源,安裝 mysql-5.7.17
[local_soft]
name=Local Base Soft
baseurl=“ftp://192.168.1.254/public
enabled=1
gpgcheck=0

清理快取
yum clean all

#--------------------master------------------------#
在 mysql-master 上修改 my.cnf 開啟 binlog 並新增 server_id
bind-address = 0.0.0.0
server-id = 18
log_bin = mysql-bin
binlog-format = statement
relay-log = relay-log

重啟服務 systemctl restart mysqld

初始化master
reset master;

新增同步使用者
create user ‘repl’@’%’ IDENTIFIED BY ‘lper’;
grant replication client,replication slave on . to [email protected]’%’;

安裝備份工具 xtrabackup
yum install -y percona-xtrabackup-24

備份資料庫
slave-info 記錄 show master 的資訊
innobackupex --slave-info --user=“root” --password=“toor”
–host=“localhost” --no-timestamp ./backup

#--------------------slave-------------------------#
安裝 mysql server 和 xtrabackup
yum install -y mysql-community-server percona-xtrabackup-24

使用 innobackup 恢復備份
innobackupex --apply-log backup
innobackupex --copy-back ./backup

恢復許可權
chown -R mysql:mysql /var/lib/mysql

設定 mysql slave 的my.cnf 增加 server_id 及 binlog 配置
bind-address = 0.0.0.0
server-id = 17
log_bin = mysql-bin
binlog-format = statement
relay-log = relay-log

啟動 mysql 設定主從,binlog 檔案及其執行位置在 /var/lib/mysql/xtrabackup_info 查詢
reset slave;
change master to master_host=‘192.168.1.18’,
master_user=‘repl’,master_password=‘lper’,
master_log_file=“mysql-bin.000001”, master_log_pos=615;
start slave;

檢查驗證
show slave status\G

#------------------semi sync master----------------#
檢視 mysql 外掛
show plugins;

安裝半同步外掛
install plugin rpl_semi_sync_master soname ‘semisync_master.so’;
開啟半同步
set global rpl_semi_sync_master_enabled=1;
等待超時時間
設定此引數值(ms),為了防止半同步複製在沒有收到確認的情況下發生堵塞,如果Master在超時

之前沒有收到任何確認,將恢復到正常的非同步複製,並繼續執行沒有半同步的複製操作。
set global rpl_semi_sync_master_timeout=1000;

檢視狀態
show global variables like ‘%rpl_semi%’;
show global status like ‘%rpl_semi%’;

#------------------semi sync slave-----------------#
檢視 mysql 外掛
show plugins;

安裝半同步外掛
install plugin rpl_semi_sync_slave soname ‘semisync_slave.so’;
開啟半同步
set global rpl_semi_sync_slave_enabled=1;

檢視狀態
show global variables like ‘%rpl_semi%’;
重啟 IO 執行緒
stop slave io_thread;
start slave io_thread;

#----------------------my.cnf ---------------------#
plugin-load = “rpl_semi_sync_master=semisync_master.so”
plugin-load = “rpl_semi_sync_slave=semisync_slave.so”
rpl_semi_sync_slave_enabled = 1
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 3000
#----------------------mha node--------------------#
安裝 mha node 節點包
yum install gcc pcre-devel pkgconfig autoconf automake perl-ExtUtils-MakeMaker perl-CPAN perl-DBI perl-DBD-MySQL

安裝 mha4mysql-node
perl Makefile.PL
make
make install

#--------------------mha manager-------------------#

mha 官方網站 https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads

安裝 mha node 節點包
yum install -y gcc pcre-devel pkgconfig autoconf automake perl-ExtUtils-MakeMaker perl-CPAN perl-DBI perl-DBD-MySQL

安裝 mha4mysql-node
perl Makefile.PL
make
make install

安裝 mha manager 節點
安裝依賴軟體包
yum install -y perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes

安裝 mha 管理節點
perl Makefile.PL

[Core Features]

  • DBI …loaded. (1.627)
  • DBD::mysql …loaded. (4.023)
  • Time::HiRes …loaded. (1.9725)
  • Config::Tiny …loaded. (2.14)
  • Log::Dispatch …loaded. (2.41)
  • Parallel::ForkManager …loaded. (1.18)
  • MHA::NodeConst …loaded. (0.56)
    *** Module::AutoInstall configuration finished.
    Checking if your kit is complete…
    Looks good

make
make install

mha 是依靠 ssh 遠端配置管理 mysql 伺服器的,所以要求管理節點機器到所有 mysql
機器能做到 ssh 免密碼登入
/etc/ssh/ssh_config 配置不校驗 host key,不輸人 yes
StrictHostKeyChecking no

cd /root/.ssh
ssh-keygen -t rsa -b 2048 -N ‘’ -f id_rsa
for i in mysql{15…18};do
ssh-copy-id -i id_rsa.pub ${i}
done
把私鑰 id_rsa 拷貝給所有 mysql 主機
for i in mysql{15…18};do
scp id_rsa ${i}:.ssh/id_rsa
done

mha 切換 vip 是靠指令碼實現,vim 編輯指令碼 master_ip_failover 設定 vip
(line:35)
my $vip = ‘192.168.1.10/24’; # Virtual IP
cp master_ip_failover /usr/local/bin/
chmod 755 /usr/local/bin/master_ip_failover

新增 預設配置檔案 /etc/masterha_default.cnf 和 /etc/mha.cnf 配置檔案
touch /etc/masterha_default.cnf

cat /etc/mha.cnf
[server default]
manager_log=/var/log/mha.log
manager_workdir=/var/lib/mha

user=root
password=toor

repl_user=repl
repl_password=lper

ssh_user=root

ping_interval=1
remote_workdir=/var/lib/mha
master_ip_failover_script=/usr/local/bin/master_ip_failover

[server18]
candidate_master=1
hostname=mysql18

[server17]
candidate_master=1
hostname=mysql17

[server16]
hostname=mysql16
no_master=1

[server15]
hostname=mysql15
no_master=1

在當前的 master 上手工繫結 vip 執行檢查測試

檢查 ssh 免密碼登入
masterha_check_ssh --conf=/etc/mha.cnf

檢查 mysql 主從配置
masterha_check_repl --conf=/etc/mha.cnf

排除所有錯誤,新增 root 使用者遠端登入許可權
create user ‘root’@’%’ IDENTIFIED BY ‘toor’;
grant ALL ON . to [email protected]’%’;

新增引數 relay_log_purge=0

啟動 mha
masterha_manager --conf=/etc/mha.cnf --ignore_last_failover

驗證測試

#--------------------- mycat --------------------#
建立一個用於查詢的使用者
create user ‘read’@’%’ IDENTIFIED BY ‘daer’;
grant select on . to ‘read’@’%’;

在機器上安裝 java-1.8.0-openjdk-devel
拷貝 mycat 到 /usr/local/

配置 /usr/local/mycat/conf/server.xml
82: mydb
97: mydb

配置 /usr/local/mycat/conf/schema.xml

<?xml version="1.0"?>

<mycat:schema xmlns:mycat=“http://io.mycat/”>

<schema name="mydb" checkSQLschema="false" sqlMaxLimit="100" 

dataNode=“dn1”>


<dataHost name=“localhost1” maxCon=“1000” minCon=“10” balance=“3”
writeType=“0” dbType=“mysql” dbDriver=“native”

switchType=“1” slaveThreshold=“100”>
select user()

<writeHost host=“hostMaster” url=“192.168.1.10:3306”
user=“root”

password=“toor”>

<readHost host=“hostS2” url=“mysql15:3306” user=“read”

password=“daer” />
<readHost host=“hostS2” url=“mysql16:3306” user=“read”

password=“daer” />
<readHost host=“hostS2” url=“mysql17:3306” user=“read”

password=“daer” />
<readHost host=“hostS2” url=“mysql18:3306” user=“read”

password=“daer” />


</mycat:schema>

啟動 mycat ,驗證測試
/usr/local/mycat/bin/mycat start

配置檔案注意事項:
conf/server.xml 可以不修改,但要注意
TESTDB
虛擬庫名稱,要和後面對應
schemas是這個使用者下的邏輯資料庫可以有多個邏輯資料庫可以用“,”逗號隔開 使用者名稱和密碼是連線 mycat 的使用者名稱和密碼,與 mysql 例項的使用者名稱密碼無關 mycat預設的普通連線埠是8066,管理連線埠是9066 schema:邏輯資料庫 dataNode:節點
dataHost:節點對應的讀庫寫庫的地址和連線
balance指的負載均衡型別,目前的取值有4種:
balance=“0”, 不開啟讀寫分離機制,所有讀操作都發送到當前可用的writeHost上。
balance=“1”,全部的readHost與stand by writeHost參與select語句的負載均衡
balance=“2”,所有讀操作都隨機的在writeHost、readhost上分發。
balance=“3”,所有讀請求隨機的分發到wiriterHost對應的readhost執行,writerHost不負擔讀壓力

switchType指的是切換的模式,目前的取值也有4種:
switchType=’-1’ 表示不自動切換
switchType=‘1’ 預設值,表示自動切換
switchType=‘2’ 基於MySQL主從同步的狀態決定是否切換,心跳語句為 show slavestatus
switchType=‘3’ 基於MySQL galary cluster的切換機制(適合叢集)(1.4.1),心跳語句為 show status like ‘wsrep%’

WriteType引數設定:
writeType=“0”, 所有寫操作都發送到可用的writeHost上。
writeType=“1”,所有寫操作都隨機的傳送到readHost。
writeType=“2”,所有寫操作都隨機的在writeHost、readhost分上發。

配置完成以後連線 mycat 查詢
mysql -uroot -p123456 -h192.168.4.20 -P 8066 -e ‘select @@hostname;’
多查詢幾次,可以看到輪詢效果

第二臺 mycat
安裝 java-1.8.0-openjdk-devel
拷貝 /usr/local/mycat 到本機相同目錄,啟動服務即可

#--------------- haproxy keepalived--------------#
yum 安裝 haproxy
修改 /etc/haproxy/haproxy.cfg
listen mycat_3306 *:3306
mode tcp # mysql 得使用 tcp 協議
option tcpka # 使用長連線
balance leastconn # 最小連線排程演算法
server mycat_01 192.168.1.13:8066 check inter 3000 rise 1 maxconn 1000 fall 3
server mycat_02 192.168.1.14:8066 check inter 3000 rise 1 maxconn 1000 fall 3

啟動服務
可以在伺服器上使用 ss -atn|grep “ESTAB.*8066” 檢視後端和哪臺服務建立連線了

為防止 haproxy 單點故障,配置兩臺 haproxy 使用 keepalived 實現高可用
第二臺 haproxy 配置同第一臺
keepalived 配置
yum 安裝 keepalived
修改配置檔案 keepalived.conf

! Configuration File for keepalived
global_defs {
router_id mycat
}
vrrp_script chk_haproxy {
script “killall -0 haproxy” # cheaper than pidof
interval 2 # check every 2 seconds
}

vrrp_instance Mycat {
state BACKUP
interface eth0
track_interface {
eth0
}
virtual_router_id 150
priority 200
! nopreempt
advert_int 2
authentication {
auth_type PASS
auth_pass test_mycat
}
virtual_ipaddress {
192.168.1.100/24 brd 192.168.1.255 dev eth0 label eth0:1
}
track_script {
chk_haproxy weight=0 # +2 if process is present
}
}

           +-------------+      +-----------+       +--------------------------+
           | keepalived  |      |  +-----+  |       | +--------+    +--------+ |   
           |-------------|      |  |mycat|  |  ==>  | |mysql(M)|<==>|mysql(M)| |      
           |  +-------+  |      |  +-----+  |       | +--------+    +--------+ |   
           |  |haproxy|=>| ==>  |           |       |  MHA或其他多主高可用方案 |
           |  +-------+  |      |  +-----+  |       |-~-~-~-~-~-~~~~-~-~-~-~-~-|      

client --> vip | |高| | | |mycat| | ==> | ±-------+ ±-------+ |
| |可| | | ±----+ | | |mysql(S)| 從 |mysql(S)| |
| |用| | | | | ±-------+ 庫 ±-------+ |
| ±------+ | | ±----+ | | ±-------+ 集 ±-------+ |
| |haproxy|=>| ==> | |mycat| | ==> | |mysql(S)| 群 |mysql(S)| |
| ±------+ | | ±----+ | | ±-------+ ±-------+ |
±------------+ ±----------+ ±-------------------------+

#----------------------redis-----------------------#
原始碼安裝 redis
安裝編譯工具
yum install gcc make automake pkgconfig
新增使用者
adduser -s /sbin/nologin -d /var/lib/redis redis
編譯安裝 redis
make MALLOC=libc
make PREFIX=/usr/local/redis install
mkdir -p /usr/local/redis/conf
cp *.conf /usr/local/redis/conf/

配置 redis 1主2從 redis.conf
bind 0.0.0.0
port 6379
dir /var/lib/redis
daemonize yes

啟動 redis
./bin/redis-server conf/redis.conf

設定主從,檢視狀態
redis-cli -h redis02 -p 6379
redis02:6379> slaveof redis01 6379
OK

[[email protected] ~]# redis-cli -h redis03 -p 6379
redis03:6379> slaveof redis01 6379
OK

檢視狀態
redis-cli -h redis01 -p 6379 info replication

配置 redis 哨兵 sentinel.conf
bind 0.0.0.0
protected-mode no
daemonize yes
port 26379
dir /tmp
sentinel monitor mymaster redis01 6379 1
sentinel down-after-milliseconds mymaster 3000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 5000
sentinel client-reconfig-script mymaster /usr/local/bin/reconfig.sh

檢視哨兵狀態
redis-cli -h redis01 -p 26379 info sentinel

reconfig.sh
#!/bin/bash

args=( )

mymaster leader start old.ip old.port new.ip new.port

logger -p local0.info -t redis “${@:-NULL}”
vip=“192.168.1.100/32”
read oldip newip <<<"$4 $6"
if $(ip -o a s |grep -q ${oldip:-0.0.0.0});then
/sbin/ifconfig eth0:1 down &>/dev/null
elif $(ip -o a s|grep -q ${newip:-0.0.0.0});then
/sbin/ifconfig eth0:1 ${vip}
/sbin/arping -q -c 3 -A ${vip%/*} -I eth0
fi

reconfig 2
#!/bin/bash

mymaster leader start 192.168.1.13 6379 192.168.1.12 6379

VIP=“192.168.1.10/24”
local_ip=$(ip -o addr show dev eth0 label eth0|awk '{print
gensub("/.*","","",KaTeX parse error: Expected 'EOF', got '}' at position 3: 4)}̲') if [[ "{local_ip}" == “ 4 &quot; ] ] ; t h e n / u s r / s b i n / i f c o n f i g e t h 0 : 1 d o w n e l i f [ [ &quot; 4&quot; ]];then /usr/sbin/ifconfig eth0:1 down elif [[ &quot; {local_ip}” == “ 6 &quot; ] ] ; t h e n / u s r / s b i n / i f c o n f i g e t h 0 : 1 &quot; 6&quot; ]];then /usr/sbin/ifconfig eth0:1 &quot; {VIP}”
fi

#------------------------------------------------------------#
! Configuration File for keepalived
global_defs {
router_id mycat
}
vrrp_script chk_haproxy {
script “killall -0 haproxy” # cheaper than pidof
interval 2 # check every 2 seconds
}

vrrp_instance Mycat {
state BACKUP
interface eth0
track_interface {
eth0
}
virtual_router_id 150
priority 200
! nopreempt
advert_int 2
authentication {
auth_type PASS
auth_pass test_mycat
}
virtual_ipaddress {
192.168.1.100/24 brd 192.168.1.255 dev eth0 label eth0:1
}
track_script {
chk_haproxy weight=0 # +2 if process is present
}
}

vrrp_instance Mycat1 {
state BACKUP
interface eth0
track_interface {
eth0
}
virtual_router_id 151
priority 100
nopreempt
advert_int 2
authentication {
auth_type PASS
auth_pass test_mycat1
}
virtual_ipaddress {
192.168.1.101/24 brd 192.168.1.255 dev eth0 label eth0:2
}
track_script {
chk_haproxy weight=0 # +2 if process is present
}
}