最近在研究MySQL数据库的高可用性和强一致性,略有心得,记录一下!
前言
以前在开发电商项目时,使用的是主流的方法:通过对MySQL进行主从复制,及利用Amoeba实现数据库读写分离,来搭建一个较为稳定且能承受并发量大的服务数据库。然而在使用过程中,慢慢发现无论是一主两从还是一主多从也好,这两种方式的同步都会有时间差,在非常大的并发下,同步的时间差就会暴露出来,导致可能查询的数据读到脏数据。所以分布式数据库也许才是最好的解决方案。
在寻找不同数据库高可用方案时,找到keepalived,MHA以及引入zookeeper的等等方案,这些方法在强一致性、数据库选择的灵活性、整体系统的复杂性和维护性上都有一定的不足。对于企业来说,数据的高可用性和强一致性是最为看重的,一旦因为一次意外丢失了数据,很有可能会让企业陷入不小的风险当中。
通过寻找和了解,很快找到两个开源的且比较适合的可用方案,分别是阿里的AliSQL和腾讯的PhxSQL。两个开源的且兼容MySQL的数据库经对比,不难发现这两个研究的方向还是有点不一样的:
AliSQL是MySQL的一个分支,通过对MySQL进行优化(侵入到MySQL内部,内核级开发),对数据库作了功能及性能上的优化。
PhxSQL是使用分布式协议paxos写了一个binlog同步的插件,它解决了数据一致性的问题,保证多节点的MySQL使用该插件同步binlog可以达到binlog的强一致性。保证数据库的高可用和强一致的同时,对MySQL的侵入性较小。
显而易见,对于电商项目,阿里的AliSQL是一个不错的选择;对于企业项目,腾讯的PhxSQL实用性会更高一点。
PhxSQL简介
PhxSQL是由微信后台团队自主研发的一款数据强一致、服务高可用的分布式数据库服务。PhxSQL提供Zookeeper级别的强一致和高可用,完全兼容MySQL。源码地址
- PhxSQL具有服务高可用、数据强一致、高性能、运维简单、和MySQL完全兼容的特点。
- 服务高可用:PhxSQL集群内只要多数派节点存活就能正常提供服务;出于性能的考虑,集群会选举出一个Master节点负责写入操作;当Master失效,会自动重新选举新的Master。
- 数据强一致:PhxSQL采用多节点冗余部署,在多个节点之间采用paxos协议同步流水,保证了集群内各节点数据的强一致。
- 高性能:PhxSQL比MySQL SemiSync的写性能更好,得益于Paxos协议比SemiSync协议更加高效;
- 运维简单:PhxSQL集群内机器出现短时间故障,能自动恢复数据,无需复杂的运维操作;PhxSQL更提供一键更换(新增/删除)集群内的机器,简化运维的工作。
- MySQL完全兼容:PhxSQL是基于Percona的研发,完全兼容MySQL的操作命令。 可通过MySQL提供的mysqlclient/perconaserverclient直接操作PhxSQL。
项目中包含PhxSQL源代码,源代码编译时所需要的一些第三方库,及可直接在Linux环境下运行的二进制包。其中代码使用到了微信团队自研的另外三个开源项目(phxpaxos,phxrpc,colib)。若需编译源代码,需额外下载,也可以在clone时通过--recurse-submodule获得代码。
phxpaxos项目地址: http://github.com/Tencent/phxpaxos
phxrpc项目地址: http://github.com/Tencent/phxrpc
colib项目地址: http://github.com/Tencent/libco
PhxSQL编译
安装部署PhxSQL之前,需要对开源项目进行编译,打包。
1. (注意)在按照官方文档一步一步编译之前,首先安装依赖包,如果不能联网的话,请自行下载好相关的rpm包:
yum -y install readline*yum -y install zlib*
yum -y localinstall libstdc++-static
yum -y localinstall glibc-static
yum -y localinstall nscd
2. 按照以下链接的编译步骤即可完成编译:
官方的中文详细编译手册:https://github.com/Tencent/phxsql/wiki/中文详细编译手册
3. 编译完成后,生成安装文件:
(1)在PhxSQL目录下执行sh autoinstall.sh && make && make install
(2)若想打包二进制运行包(集群运行时所需要的所有文件和配置)make package
(3)install
完成后,二进制会生成到PhxSQL
目录下的sbin
目录,运行所需要的相关文件和配置会安装到PhxSQL目录下的install_package
目录。打包二进制运行包会把install_package
进行tar格式的打包,并生成phxsql.tar.gz
。若想更改install
的安装目录,可在sh autoinstall.sh
后加入-prefix=
路径
PhxSQL部署
1. PhxSQL需要在2台或以上的机器集群上运行(建议集群内机器数目n>=3 且 n为奇数)。
本人搭建时选用了3台机器:
IP1 |
192.168.8.236 |
master |
IP2 |
192.168.8.237 |
slave1 |
IP3 |
192.168.8.238 |
slave2 |
2. my.cnf的修改:MySQL的配置根据你的业务需求进行修改(安装前请修改tools/etc_template/my.cnf,安装后请修改etc/my.cnf)。
本人在安装前,在my.cnf中的[mysqld]后添加:
lower_case_table_names = 1
此处修改原因是:在Linux下,mysql安装完后是默认:区分表名的大小写,不区分列名的大小写!而MySQL在Windows下都不区分大小写。因为尝试过在安装之后再修改是不成功的,为了防止数据库出错,所以在安装前修改。
3. 按照以下链接的部署步骤即可完成部署:
官方的中文部署手册:https://github.com/Tencent/phxsql/wiki/中文部署手册
此处顺便整理下本人的部署过程,有兴趣可以对比下:
(1)第一次安装时
groupadd mysql //创建mysql用户组useradd -g mysql mysql //在mysql用户组中创建用户,mysqlpasswd mysql //设置用户密码,此处本人设置为root
(2)编译完成的二进制包改名为 phxsql.tar.gz 并放在 /home 目录中(三台机器都要执行)
tar xvf phxsql.tar.gz //解压编译好的二进制包mkdir /home/phxsqldata //创建数据存放目录
注意:不要放在 /root 目录下,亲测因为权限问题,安装后会出各种奇怪的错误。
查看 /home 目录,即可找到以下的部署路径:
安装路径 |
/home/phxsql |
数据路径 |
/home/phxsqldata |
编译后的安装包 |
/home/phxsql.tar.gz |
(3)开始安装部署(每台机器都要执行,只需要修改最后一句,对应为当前机器的IP即可)
cd /home/phxsql/tools //进入phthon2.7命令的目录python2.7 install.py -i "192.168.8.236" -p 54321 -g 6000 -y 11111 -P 17000 -a 8001 -f /home/phxsqldata/
(4)安装完成后查看服务和端口是否可用
ps -ef | grep phxsqlproxyps -ef | grep mysqlps -ef | grep phxbinlogsvrnetstat -ntlp
出现下图的红色方框中的服务和端口,即代表安装成功:
如果存在没有正常启动的二进制,执行 python2.7 restart.py -p 二进制名,启动相应二进制。
(5)此处是为了操作方便,配置下环境变量,就可以在任何地方使用phxbinlogsvr_tools_phxrpc、mysql等命令
vim /etc/profile
在此文件中增加以下两句话,保存即可:
export PATH=/home/phxsql/sbin:$PATHexport PATH=/home/phxsql/percona.src/bin/:$PATH
重新加载 profile 文件:
source /etc/profile
(6)建立集群(官方说在任意一台机器上执行即可,但经过测试,貌似在设置的主机上跑才不容易出错)
phxbinlogsvr_tools_phxrpc -f InitBinlogSvrMaster -h"192.168.8.236,192.168.8.237,192.168.8.238" -p 17000
(7)出现以上红色框框的部分就代表集群已经搭建成功了,可以用命令查看集群内的成员及主机信息(上图可以看到)
phxbinlogsvr_tools_phxrpc -f GetMemberList -h"192.168.8.236" -p 17000phxbinlogsvr_tools_phxrpc -f GetMasterInfoFromGlobal -h"192.168.8.236" -p 17000
(8)这里特别说下,集群安装部署失败需要重新安装部署,此时最好在 kill 掉端口的同时也要 kill 掉服务,及相关目录中存放的数据,防止后面重新部署时出现相同的服务导致集群有问题。
killall -9 phxbinlogsvr_phxrpc phxsqlproxy_phxrpc mysqld rm -rf /home/phxsqldatarm -rf /home/phxsql
然后回到第(2),重新开始即可。
(9)登陆PhxSQL并测试
通过Phxsqlproxy登陆PhxSQL的Master进行读写:
mysql -uroot -h "192.168.8.236" -P 54321
通过Phxsqlproxy登陆PhxSQL的slave读取数据:
mysql -uroot -h "192.168.8.237" -P 54322mysql -uroot -h "192.168.8.238" -P 54322
(10)重启机器或者修复好集群机器后,需要要重新启动Phxsql各组件
cd /home/phxsql/toolspython2.7 restart.py -p mysqlpython2.7 restart.py -p phxbinlogsvrpython2.7 restart.py -p phxsqlproxy
PhxSQL官方文档
中文详细编译手册
中文部署手册
PhxSQL 成员管理
从现有MySQL数据库迁移
PhxSQL官方文章
MySQL半同步复制的数据一致性探讨
PhxSQL架构介绍
PhxSQL强一致同步基础PhxPaxos库原理介绍
谈谈PhxSQL的设计和实现哲学(上)
谈谈PhxSQL的设计和实现哲学(下)