MySQL集群PXC入门及实践
Posted godba
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL集群PXC入门及实践相关的知识,希望对你有一定的参考价值。
一、学习动机
伴随互联网行业的兴起,mysql应用场景越来越广泛,比如:打车软件、电商平台、直播平台、电子支付、媒体社交。比较传统的IT行业居然也开始探索使用开源的MySQL来代替Oracle了,所以说不得不学啊。
身边常见的,校园出成绩那一年,我们会感觉网站异常的卡顿,因为访问人数太多。
单机单点的数据库,一旦这台机子宕机(机器出现故障、机房停电、...),那整个网站将无法正常访问。这时候集群就出现了,一台机器出现问题了,另外的机器还在正常运行,网站依旧可以访问。
集群案例:滴滴出行、淘宝、京东、斗鱼直播、支付宝、微信、QQ
二、案例
1.天猫双十一
2019年天猫双十一交易额最终定格在2684亿,再次刷新双十一交易额记录。2018年的天猫双十一总交易额2135亿元,今年比去年超出549亿元,再次刷新天猫双十一全天交易额记录。4分钟成交额突破1000亿
交易峰值(下订单的峰值):32.5万/秒
支付峰值:25.6万/秒
数据库峰值:4200万/秒
支持这么漂亮的数字完美运行,除了数据库集群技术还有云服务器、负载均衡、RDS云数据库等技术
2.微信红包
2017年除夕当天,全国人民总共收发142亿个红包,峰值42万/秒
央视春晚微信摇一摇互动总量达110万亿次,峰值8.1亿/秒
三、学习目标和方式
1.学习目标:
1)向大型互联网应用看起,学习架构设计和业务处理
2)掌握PXC集群MySQL方案的原理
3)掌握PXC集群的强一致性
4)掌握PXC集群的高可用方案
2.学习方式:由浅入深,循序渐进;案例有小到大,逐步扩展
四、硬件环境需求
1.win10 x64专业版或者企业版(PXC不支持windows,需要用到虚拟机,所以最好不要使用home版或者32位的系统)/Linux/MacOS
2.Docker虚拟机
3.内存8GB以上
五、单节点数据库的弊端
1.大型互联网程序用户群里庞大,所以架构必须要特殊设计
2.单节点的数据库无法满足性能上的要求,就像校园网查成绩的时候,如果1万人同时查,你可能拿到就是一个白屏,无论你是收费的还是免费的数据库,单节点都满足不了这种并发需求
3.单节点的数据库没有冗余设计,无法满足高可用,一旦这个机器出现问题,没有其他节点的数据库顶替,那网站将无法正常访问
单节点数据库测试,5000个连接,5000个并发查询,平均就1个连接1个查询,安装好数据库,配置好环境变量,[mysqld]下面配置最大连接量为6000(max_connections=6000),执行下面的命令:
mysqlslap -hlocalhost -uroot -pabc123456 -P3306 --concurrency=5000--iterations=1 --auto-generate-sql --auto-generate-sql-load-type=mixed--auto-generate-sql-add-autoincrement --engine=innodb --number-of-queries=5000
得到下面的结论:
这才5000个并发,需要的时间就达到了34秒,如果设置10000个并发,将如何呢?
数据库拒绝了很多请求,把没有拒绝的执行了,需要的时间是167秒,这就是单击单点在面对并发的时候数据库的承受能力。
六、PXC高可用集群方案
PXC是percona公司的percona xtraDB cluster,简称PXC。它是基于Galera协议的高可用集群方案。可以实现多个节点间的数据同步复制以及读写,并且可保障数据库的服务高可用及数据强一致性。
这样一个最基本的PXC集群,它保证了每个节点的的数据都是一致的,不会出现数据写入了数据库1而没有写入数据库2的情况,这种的集群在遇到单表数据量超过2000万的时候,mysql性能会受损,所以一个集群还不够,我们需要把数据分到另一个集群,这个称为“切片”,就是把大量的数据拆分到不同的集群中,每个集群的数据都是不一样的,看下面的截图:
这样一来,PXC集群1存前面1000万条数据,PXC集群2存后面1000万条数据,当一个sql语句请求的时候,通过MyCat这个阿里巴巴的开源中间件,可以把sql分到不同的集群里面去。这种的分片按照数量就是2个分片。
这个切分算法也比较多,比如按照日期、月份、年份、某一列的固定值,或者最简单的按照主键值切分,主键对2求模,余0的存分片1,余1的存分片2,这样MyCat就会把2000万条数据均匀地分配到2个集群上。
PXC虽然保证了数据的强一致性,但是这是以牺牲性能为代价的,所以适合保存重要的数据,比如订单。
七、Replication集群方案
这种集群,在第一个节点插入以后,就马上返回给客户端执行成功了,然后再做每个节点之间的同步,如果某一个同步操作失败了,那用户请求的时候拿到的数据就不同步了,但是它的优势是速度快,不会牺牲任何地性能,适合保存不那么重要的数据,比如日志。
八、PXC与Replication集群结合
九、系统架构方案
更加清晰和详细架构请看下面的截图
十、APP的架构设计
客户端包括web浏览器端,移动手机端,用户通过客户端发送一个请求后,nginx接收到请求后,会做负载均衡,定向到当前最适合(相对没那么繁忙)处理这个请求的服务器端,服务端接收到请求后,再访问数据库,一些热点数据需要做缓存,比如淘宝首页的商品。从上面的图中看,服务器端的某一个出现故障后,nginx会将请求定向到剩下的能正常运行的服务器上面,而数据库端也是采用的集群,这样就达到了高可用,就是任意一台机器出现故障,对整个网站的运行不会产生太大的影响,这里可能有人会问如果nginx这台服务器出现问题了怎么办?可以做虚拟ip(vip),配置主从入口,就是nginx1和nginx2的虚拟ip是一样的,其中有一个是主入口,在主入口没有出现问题的时候,从机是不会工作的,当主入口机出现问题了,从入口机就会顶替,如果主从都出现问题了,那网站将无法访问。
服务器端的spring与spring之间的调用又是如何的?现在都是分布式调用,比较经典的是dubbo+zookeeper。这里有同步调用和异步调用
同步调用:提出问题的一方直接调用处理问题的一方
异步调用:提出问题的一方将问题交个消息中间件,由消息中间件去将问题发放给处理问题的一方,在这里,提出问题的一方称为“生产者”,处理问题的一方称为“消费者”,他们彼此是不知道对方是谁,达到业务解耦的效果,这样做的好处是以后在部署项目、程序的升级、接口的变更的时候,它的影响面就很小。比如说生产者项目开发地有问题,然后用其他语言再做了一个项目,对消费者不会产生任何影响,只要生产生能正常往消息队列里面发送消息就好;再比如用户注册一个淘宝账号,我们连带着把支付宝账号也给你开通,然后其他的投资的项目也给用户一些优惠(给你2张淘票票的电影票,免费一个月的虾米音乐会员等等),对应淘宝这一端,它发起一个消息传达给消息队列,至于接收端是支付宝还是淘票票还是虾米音乐,淘宝这一端不知道也不需要关心,等以后阿里再有什么投资项目需要给新用户优惠的时候,只需要从消息队列里接收消息就可以,对生产者而言,没有任何影响。如果是同步调用(dubbo或者webservice调用),其中一端有修改,另一端必然也要改,这种强耦合是不好的。
以下是异步调用方案图:
PXC就属于一套近乎完美的MySQL高可用集群架构方案;
优点总结:
1.可以达到时时同步,无延迟现象发生
2.完全兼容MySQL
3.对于集群中新节点的加入,维护起来很简单
4.数据的强一致性
不足之处总结:
1.只支持Innodb存储引擎
2.存在多节点update更新问题,也就是写放大问题
3.在线DDL语句,锁表问题
4.sst针对新节点加入的传输代价过高的问题
理论知识学习完了,接下来带大家安装PXC
实战过程:
环境介绍:3台centos 7
walt001192.168.150.138
walt002192.168.150.139
walt003192.168.150.143
安装之前的注意事项:
三台机器的防火墙iptables都要关闭,三台机器的server-id不能一样。
PXC软件包下载:
https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.6/binary/tarball/percona-xtrabackup-2.4.6-Linux-x86_64.tar.gz
Percona-XtraDB-Cluster下载
https://www.percona.com/downloads/Percona-XtraDB-Cluster-56/Percona-XtraDB-Cluster-5.6.26-25.12/binary/tarball/Percona-XtraDB-Cluster-5.6.26-rel74.0-25.12.1.Linux.x86_64.tar.gz
这里我下载的是:Percona-XtraDB-Cluster-5.6.26-rel74.0-25.12.1.Linux.x86_64
接下来三台机器上都需要针对基础软件包进行安装,使用yum安装即可,解决依赖性。
三台机器都需要操作的步骤:
· 把IP和主机名写到hosts文件里(这个不是主要项,方便主机名解析而已,我没有完全一样的hosts结果也成功,不成功 不用在这里纠结)
[root@xxx]# cat /etc/hosts
192.168.150.138 walt001
192.168.150.139 walt002
192.168.150.143 walt003
因为pxc本身包含mysql主程序,为防止端口占用删除多余数据库安装包
yum remove mariadb-* -y
安装依赖
yum install perl-IO-Socket-SSL.noarch perl-DBD-MySQL.x86_64perl-Time-HiRes openssl openssl-devel socat -y
提前告诉你,如果系统是最小化安装事先做这两个软连接避免初始化报库文件缺失错误。
[root@xxx ~]# ln -sv /usr/lib64/libcrypto.so.10 /lib64/libcrypto.so.6
[root@xxx ~]# ln -sv /usr/lib64/libssl.so.10/lib64/libssl.so.6
定位到解压目录
[root@xxx ~]# cd /usr/local/
[root@xxx local]# tarxvf /rrot/percona-xtrabackup-2.4.6-Linux-x86_64.tar.gz
[root@xxx local]# tarxvf /root/Percona-XtraDB-Cluster-5.6.26-rel74.0-25.12.1.Linux.x86_64.tar.gz
建个软连接,方便使用
[root@xxx local]# ln -svPercona-XtraDB-Cluster-5.6.26-rel74.0-25.12.1.Linux.x86_64 mysql
[root@xxx local]# useradd -s /sbin/nologinmysql
[root@xxx local]# chown mysql.mysql -R mysql
[root@xxx local]# cp percona-xtrabackup-2.4.6-Linux-x86_64/bin/*mysql/bin/
[root@xxx local]# mkdir -p /data/mysql
[root@xxx local]# chown mysql.mysql -R /data/mysql/
先配置第一台机器,并成功启动后再配置其他两台
在第一台主机上创建配置文件:
创建配置文件:
[root@xxx local]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket = /tmp/mysql.sock
pid-file=/data/mysql/mysql.pid
character_set_server = utf8
max_connections = 3000
back_log= 3000
skip-name-resolve
sync_binlog=0
innodb_flush_log_at_trx_commit=1
server-id = 1
#pxc主要配置项
default_storage_engine=Innodb
innodb_autoinc_lock_mode=2
binlog_format=row
wsrep_cluster_name=pxc_zs #集群名称
wsrep_slave_threads=4 #开启的复制线程数,cpu核数*2
wsrep_cluster_address=gcomm://192.168.150.138,192.168.150.39,192.168.150.143 #集群所有服务器ip都加进来
wsrep_node_address=192.168.150.138 #本机ip
wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sst:zs
把这个文件写好了,传到其他两台机器的 /etc 下面,修改 server-id 和 wsrep_node_address
每个主机的server-id 和wsrep_node_address 保持不同即可
初始化数据:
/usr/local/mysql/scripts/mysql_install_db –basedir=/usr/local/mysql–datadir=/data/mysql/ –defaults-file=/etc/my.cnf –user=mysql
复制进程文件到系统服务目录,启动第一节点的服务:
[root@xxx local]#cd /usr/local/mysql/support-files
[root@xxx support-files]#cp mysql.server /etc/init.d/mysql
[root@xxx support-files]# /etc/init.d/mysqlbootstrap-pxc
创建环境变量,让系统变量读到MySQL的路径:
[root@xxx opt]# echo “export PATH=$PATH:/usr/local/mysql/bin”> /etc/profile.d/mysql.sh && source /etc/profile.d/mysql.sh
登陆或者初始化的时候提示缺少库文件,find命令依次查找库文件做软连接到/lib64
[root@xxx ~]# find / -name “libreadline*
/usr/lib64/libreadline.so.6
/usr/lib64/libreadline.so.6.2
[root@xxx ~]# ln -sv /usr/lib64/libreadline.so.6/lib64/libreadline.so.5
[root@xxx ~]# ln -sv /usr/lib64/libcrypto.so.10 /lib64/libcrypto.so.6
[root@xxx ~]# ln -sv /usr/lib64/libssl.so.10/lib64/libssl.so.6
启动成功之后,维护数据库环境并创建用户
进入数据库 ,默认密码是空的
#mysql -uroot -p
mysql> delete from mysql.user where user!='root'or host!='localhost';
mysql> grant all privileges on *.* to 'sst'@'%'identified by 'zs';
mysql> grant all privileges on *.* to 'sst'@'localhost'identified by 'zs';
mysql> flush privileges; #mysql5.6以后这个命令可以不用,授权都是立即生效的
当第一个主节点成功启动,并创建了授权的用户后,开始配置其他的机器
安装步骤和上面相同,只要保证配置文件的server-id 和wsrep_node_address 不同即可
wsrep_node_address 填写当前机器的IP
启动命令和第一台不同,用下面的命令启动:
[root@xxx mysql]# /etc/init.d/mysqlstart
第二台动后查看集群状态:
在第一个机器上执行:
[root@xxx mysql]#mysql -v #空密码的状态下这个命令可以直接登录mysql
mysql> show status like ‘wsrep%’;
故障处理:
2019-06-15 20:27:03 5870 [ERROR] WSREP: Failed to read 'ready <addr>' from: wsrep_sst_xtrabackup-v2 --role 'joiner' --address '192.168.244.147' --datadir '/var/lib/mysql/' --defaults-file '/etc/my.cnf' --defaults-group-suffix '' --parent '5870' ''
Read: '(null)'
2019-06-15 20:27:03 5870 [ERROR] WSREP: Process completed with error: wsrep_sst_xtrabackup-v2 --role 'joiner' --address '192.168.244.147' --datadir '/var/lib/mysql/' --defaults-file '/etc/my.cnf' --defaults-group-suffix '' --parent '5870' '' : 2 (No such file or directory)
2019-06-15 20:27:03 5870 [ERROR] WSREP: Failed to prepare for 'xtrabackup-v2' SST. Unrecoverable.
2019-06-15 20:27:03 5870 [ERROR] Aborting
特别是下面的报错信息,根据https://mariadb.com/kb/en/mariadb/problem-with-the-galera-wsrep_sst_method-xtrabackup-v2/的解决思路,还以为是socat的版本太低。
后来才发现,是SElinux没有关闭。。。
另外,在节点加入集群的过程中,如果报有关xtrabackup-v2的错误,不妨先将wsrep_sst_method的方式设置为rsync或者mysqldump,看能否成功,我的是改为rsync后成功了,用wsrep_sst_method为啥报错还待研究。
2. 以systemctlstart mysql@bootstrap.service启动的节点,必须以systemctlstop mysql@bootstrap.service关闭,如果以systemctl stop mysql关闭,则没效果。
以上是关于MySQL集群PXC入门及实践的主要内容,如果未能解决你的问题,请参考以下文章