mysql-pxc+HAproxy高可用部署实践

PXC简介:

 Percona XtraDB Cluster是MySQL的完全开源高可用性解决方案。它将Percona ServerPercona XtraBackupGalera库集成在一起,以实现同步多主复制。

   PXC属于一套近乎完美的mysql高可用集群解决方案,相比那些比较传统的基于主从复制模式的集群架构MHA和MM+keepalived,galera cluster最突出特点就是解决了诟病已久的数据复制延迟问题,基本上可以达到实时同步。而且节点与节点之间,他们相互的关系是对等的。本身galera cluster也是一种多主架构。galera cluster最关注的是数据的一致性,对待事物的行为时,要么在所有节点上执行,要么都不执行,它的实现机制决定了它对待一致性的行为非常严格,这也能非常完美的保证MySQL集群的数据一致性;

    对galera cluster的封装有两个,虽然名称不同,但实质都是一样的,使用的都是galera cluster。一个MySQL的创始人在自己全新的MariaDB上实现的MAriaDB cluster;一个是著名的MySQL服务和工具提供商percona实现的percona xtradb cluster,简称PXC

   要搭建PXC架构至少需要3个mysql实例来组成一个集群,三个实例之间不是主从模式,而是各自为主,所以三者是对等关系,不分从属,这就叫multi-master架构。客户端写入和读取数据时,连接哪个实例都是一样的。读取到的数据时相同的,写入任意一个实例之后,集群自己会将新写入的数据同步到其他实例上,这种架构不共享任何数据,是一种高冗余架构。

pxc特性:

PXC的优点:

1、实现mysql数据库集群架构的高可用性和数据的 强一致性。
2、完成了真正的多节点读写的集群方案。
3、改善了传统意义上的主从复制延迟问题,基本上达到了实时同步。
4、新加入的节点可以自动部署,无须提供手动备份,维护起来很方便。
5、由于是多节点写入,所以数据库故障切换很容易。

PXC的缺点:

1、只支持InnoDB引擎;当前版本(5.6.20)的复制只支持InnoDB引擎,其他存储引擎的更改不复制。然而,DDL(Data Definition Language) 语句在statement级别被复制,并且,对mysql.*表的更改会基于此被复制。例如CREATE USER...语句会被复制,但是 INSERT INTO mysql.user...语句则不会,(也可以通过wsrep_replicate_myisam参数开启myisam引擎的复制,但这是一个实验性的参数)。
2、由于群集级别的乐观并发控制,COMMIT在该阶段可能仍中止事务发布。可以有两个事务写入同一行并在不同的Percona XtraDB Cluster节点中提交,而其中只有一个可以成功提交。失败的将被中止。对于集群级中止,Percona XtraDB集群返回死锁错误代码:
(错误: 1213 SQLSTATE : 40001 (ER_LOCK_DEADLOCK ))。
3、写入效率取决于节点中最弱的一台,因为PXC集群采用的是强一致性原则,一个更改操作在所有节点都成功才算执行成功;
4、所有表都要有主键;
5、不支持LOCK TABLE等显式锁操作;
6、锁冲突、死锁问题相对更多;
7、不支持XA事务,因为可能会在提交时回滚;
8、集群吞吐量/性能取决于短板;
9、新加入节点采用SST时代价高;
10、存在写扩大问题;
11、如果并发事务量很大的话,建议采用InfiniBand网络,降低网络延迟;

PXC端口号:

3306-数据库对外服务的端口号。
4444-请求SST的端口(SST是指数据库一个备份全量文件的传输。)
4567-组成员之间进行沟通的一个端口号
4568-用于传输IST(相对于SST来说的一个增量)

准备三台虚拟机:

192.168.0.232       mysql-pxc001
192.168.0.233       mysql-pxc002
192.168.0.234       mysql-pxc003

软件安装:

1、先清理原环境:

yum remove percona*

 

2、检查端口是否占用:

3306 4444 4567 4568
netstat -lntup

 

3、禁用selinux:

#临时关闭
setenforce 0
#永久关闭
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
#查询
getenforce

 

4、配置percona的yum源:

yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm

 

5、下载pxc软件程序:

yum install Percona-XtraDB-Cluster-57 -y

 

6、启动Percona XtraDB Cluster server

systemctl start mysql

 

7、获取临时生成的超级用户帐密信息

grep 'temporary password' /var/log/mysqld.log

 

8、登录数据库

mysql -u root -p

 

9、更改root用户密码

ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';

 

10、停止mysql服务 

systemctl stop mysql

 (以上步骤在三个节点都要执行、软件yum安装很慢,可配置清华源,待验证;)

集群配置

1、编辑/etc/my.cnf

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysql.log
log-bin=/var/lib/mysqlbin
binlog_format=row
secure-file-priv=/tmp
server-id=51
log-slave-updates=1 
relay_log_purge = 0
skip-name-resolve
expire_logs_days=30
pid-file=/var/run/mysqld/mysqld.pid

# 集群名称
wsrep_cluster_name=pxc-cluster
# 集群中节点的ip
wsrep_cluster_address=gcomm://192.168.0.232,192.168.0.233,192.168.0.234

# 当前节点信息
wsrep_node_name=mysql-pxc001
wsrep_node_address=192.168.0.232

# --------------------以下信息不用修改----------------------
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sstuser:passw0rd
pxc_strict_mode=ENFORCING
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
wsrep_provider=/usr/lib64/galera3/libgalera_smm.so

[mysqld_safe]
pid-file = /var/run/mysqld/mysqld.pid
socket   = /var/lib/mysql/mysql.sock
nice     = 0
[mysql]
socket=/var/lib/mysql/mysql.sock

 

在第二个、第三个节点上重复同样的配置,但需要修改以下两个配置项:
第二个节点:

wsrep_node_name=mysql-pxc002
wsrep_node_address=192.168.0.233

 

第三个节点:

wsrep_node_name=mysql-pxc003
wsrep_node_address=192.168.0.234

 

2.启动第一个节点:

systemctl start mysql@bootstrap.service

 

采用bootstrap启动,其实是告诉数据库,这是第一个节点,不用从其他节点做数据同步。利用这种方式启动,相当于wsrep_cluster_address方式设置为gcomm://

查看服务状态:

systemctl status mysql@bootstrap

 

进入数据库查看状态:

mysql -uroot -p
show status like '%wsrep%';

 

wsrep_cluster_size                           当前集群大小
wsrep_local_state_comment            数据同步状态 Synced表示处于ready状态

状态机变化阶段(wsrep_local_state_comment):
1)OPEN: 节点启动成功,尝试连接到集群,如果失败则根据配置退出或创建新的集群
2)PRIMARY: 节点处于集群PC(primary component)中,尝试从集群中选取donor进行数据同步
3)JOINER: 节点处于等待接收/接收数据文件状态,数据传输完成后在本地加载数据
4)JOINED: 节点完成数据同步工作,尝试保持和集群进度一致
5)SYNCED:节点正常提供服务:数据的读写,集群数据的同步,新加入节点的sst请求
6)DONOR(贡献数据者):节点处于为新节点准备或传输集群全量数据状态,对客户端不可用

3.配置XtraBackup鉴权信息

在上面的配置文件中,有个wsrep_sst_auth参数。该参数是用于其它节点加入到该集群中,利用XtraBackup执行State Snapshot Transfer(类似于全量同步)的。
需要登录数据库做如下配置:

CREATE USER 'sstuser' IDENTIFIED BY 'passw0rd';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO 'sstuser';
FLUSH PRIVILEGES;

 

4.新增节点到集群
如果第1步中,我们已经配置好了/etc/my.cnf,那可以直接启动mysql服务:
登录第二个节点,执行:

systemctl start mysql

 

查看服务状态:

systemctl status mysql

 

进入mysql查看状态:

show status like 'wsrep%';

 

此时可以看到wsrep_cluster_size已经变为2。
同理,在第三个节点上执行同样的操作,wsrep_cluster_size最终应该为3.
至此,集群配置结束。

集群验证

为了验证集群的同步复制是否生效,我们采用以下思路来做验证:

  • 在node2上创建percona数据库
  • 在node3上为percona数据库创建表
  • 在node1上添加一些记录到表中
  • 查看各个node上的数据是否一致

1.在mysql-pxc001上创建percona数据库

CREATE DATABASE percona;

 

 

2.在mysql-pxc002上查看数据库

3.再mysql-pxc003上创建表

create table student (id int primary key,name varchar(30));

 

4.在mysql-pxc002上插入一条数据

insert into percona.student values (1,'xiaoming');

 

5.各节点访问,验证数据一致性

启动关闭:

当galera cluster集群单个节点或所有节点停机情况分析
单个节点停机
节点停机重启,重新加入集群,通过IST增量同步数据,来保持集群数据的一致性。IST的实现由wsrep_provider_options="gcache.size=1G"参数决定,一般设置为1G。参数大小由什么决定,根据停机时间,若停机一小时,需要确认一小时产生多大的binlog来算出参数大小。如果停机时间过长,部分数据gcache没有,此时该节点SST全量同步数据。

  1. 所有节点关闭,应采用轮巡滚动关闭的方式:a节点关闭修复,加回集群;b节点关闭修复,加回集群...原则就是保持cluster中最少一个成员存活,进行滚动重启。
    3,集群所有节点都关闭了,没有存活的节点的情况:每个节点数据库关闭后,都会保存最后一个GTID,启动集群时要先启动最后一个关闭的节点,启动顺序和关闭顺序相反。
  2. 避免关闭和启动节点时数据丢失
    3.1 原则保持cluster集群中最少有一个成员存货,然后进行滚动重启

3.2 利用主从的概念,把一个从节点转化为PXC/Galera集群中的节点

增加或者删除节点:

增加节点:
1,如果是之前旧节点恢复了只需要启动就可以了,会自动加入集群。
2,如果是新搭建的机器,还是按照之前安装集群的方法装好这台机器,然后修改其他节点的/etc/my.cnf中的wsrep_cluster_address=gcomm://,修改其他节点的my.cnf文件后不需要重启。

删除节点:
直接停掉该节点的mysql,修改my.cnf中wsrep_cluster_address=gcomm://,然后修改其他节点/etc/my.cnf把停掉的节点ip在wsrep_cluster_address=gcomm://中删除掉,修改完my.cnf后不需要重启。

PXC集群恢复排错:

gvwstate.dat : ThisfileisusedforPrimaryComponentrecoveryfeaturegrastate.dat:ThisfilecontainstheGalerastateinformation.

 

情景1:三个节点挂了2个(正常关闭):
node1,node2挂了,node3存活
在node1,node2上执行:

#service mysql start --wsrep_sst_donor=node3

 

注意:当某个node被宣威donor时,使用rsync或者dump时,该节点无法提供服务。即使使用xtrabackup这个节点性能也会收到影响,建议手动选择donar,避免高负载的机器被用来做donar,不指定则随机选择。

情景2:三个节点全部挂了(正常关闭):
在node1上执行:

#systemctl start mysql@bootstrap.service

 

 在node2,node3上执行:

#systemctl start mysql

 

情景3:node1,node2不见了(非正常关闭),node3无法单独形成仲裁,同时它会变成non-primary状态并且不会处理任何请求。
在node3上执行命令:

mysql> select * fromtest.t1;
ERROR 1047 (08S01): Unknowncommand

查看节点日志:
140814 0:42:13[Note]WSREP: commitfailedforreason: 3
140814 0:42:13[Note]WSREP: conflictstate: 0
140814 0:42:13[Note]WSREP: clusterconflictduetocertificationfailureforthreads:
140814 0:42:13[Note]WSREP: Victimthread:
THD: 7, mode: local, state: executing, conflict: certfailure, seqno: -1SQL: insertintotvalues (1)

 

解决办法:
在node3上执行(告诉node3你可以自己组成一个新集群):

SETGLOBAL wsrep_provider_options='pc.bootstrap=true';

 

注意:在执行命令之前一定要确认node1,node2确实挂了,否则会造成数据不一致。

情景4,所有节点突然掉电

#cat  /var/lib/mysql/grastate.dat# GALERA saved state
version: 2.1
uuid: 220dcdcb-1629-11e4-add3-aec059ad3734
seqno: -1
cert_index:

因为突然掉电,不确定哪个节点的数据是最新的,查看gvwstate.dat文件找出最新的seqno
#cat /var/lib/mysql/gvwstate.dat  
my_uuid: 76de8ad9-2aac-11e4-8089-d27fd06893b9
#vwbeg
view_id: 3 6c821ecc-2aac-11e4-85a5-56fe513c651f 3
bootstrap: 0
member: 6c821ecc-2aac-11e4-85a5-56fe513c651f 0
member: 6d80ec1b-2aac-11e4-8d1e-b2b2f6caf018 0
member: 76de8ad9-2aac-11e4-8089-d27fd06893b9 0
#vwend

 

实际上在 PXC5.6.19以后的系统会根据这个文件自动找到seqno最大的节点,从而自动启动数据恢复过程,不需要人工干预。如果实在不行就在该文件中找到最新的节点,手动在该节点上执行SET GLOBAL wsrep_provider_options='pc.bootstrap=true'(同情景2处理方法一样);

两节点集群排错:
解决方法:
在其中一个节点上初始化所有集群,并且将该节点设为新的Primary Component

mysql> SET GLOBAL wsrep_provider_options='pc.bootstrap=YES';
如果你想该节点可以同时处理请求,执行如下命令:
mysql> SET GLOBAL wsrep_provider_options='pc.ignore_sb=TRUE';

 

注意:在多主节点中执行这个很危险,会有脑裂的风险。所以该命令尽量只在主从环境中执行。

perconaXtraDB cluster中有两种参数可用于在通信断开时防止节点降级为non-primary状态。分别为pc.ignore_quorum和pc.ignore_sb。
pc.ignore_quorum参数设置为true的时候,节点忽略quorum算法,节点正常运行。
pc.ignore_sb是当节点通讯关闭,发生脑裂时,忽略为防止脑裂时数据不一致而无法执行语句的机制,可以在各个节点正常运行命令。

例1:
在各节点my.cnf中加入wsrep_provider_options = "pc.ignore_quorum =true" 参数,断开节点间网络。
可以看到两个节点都没有降级到non-primary状态,不会降级并且可以各自处理请求。但是当网络恢复之后,点不会自动恢复到同步状态,不会发生数据同步,双节点各自形成一个cluter。
如果要恢复集群模式,只能通过SST方式将数据同步,但是会造成一个节点的数据丢失!

例2:
在各节点my.cnf中加入wsrep_provider_options = "pc.ignore_sb = true" 参数,断开节点间网络。
可以看到两个节点都没有降级到non-primary状态,向两个节点插入不同的数据后恢复网络,集群不会恢复到原来的状态,
重启备节点,由于备节点多插入了数据,seqno比主节点的高,所以重启失败。节点间无法构成集群,只能删除数据重新进行SST。

HAproxy负载均衡pxc集群

1.安装HAproxy

yum install haproxy -y

 

2.编辑配置文件

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000
listen admin_stats
    bind 0.0.0.0:8888
    balance roundrobin
    mode http
	stats uri  /dbs
	stats realm  Global\statistics
	stats auth  admin:admin
	
	
listen proxy
    bind 0.0.0.0:3307
    balance roundrobin
    mode tcp
	option  tcplog
	option  mysql-check user  haproxy
        server mysql_1 192.168.0.232:3306 check  weight 1 maxconn 2000
        server mysql_2 192.168.0.233:3306 check  weight 1 maxconn 2000
	server mysql_1 192.168.0.234:3306 check  weight 1 maxconn 2000
	option tcpka

 

3.在mysql数据库创建用于haproxy心跳检测的用户haproxy(只有登陆权限,权限最小化)

create user 'haproxy'@'%';
#这个%可以具体到只有haproxy可以进行连接

 

4.访问haproxy的页面进行检测mysql的节点状态

在此可以down掉一个mysql节点做检测,绿色会变红,此处不做截图

5.通过负载均衡端口进行登陆测试

至此测试完成;关于haproxy的单点问题我们可以基于keepalived做高可用!

参考文档

https://www.atatech.org/articles/134058?spm=ata.13269325.0.0.4eeb49fa1Ms26m#13

https://www.percona.com/doc/percona-xtradb-cluster/5.7/howtos/virt_sandbox.html

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值