PhxSQL 是由微信后台团队自主研发的一款服务高可用、数据强一致的分布式数据库服务。该服务基于 Percona5.6 搭建,目标在于解决 MySQL 在容灾和数据一致性方面的不足,并大幅简化了 MySQL 容灾切换的运维操作。
作者:Junchao Chen (junechen@tencent.com), Haochuan Cui (lynncui@tencent.com), Duokai Huang (mariohuang@tencent.com), Ming Chen (mingchen@tencent.com) 和 Sifan Liu (stephenliu@tencent.com)
总览
- 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-wechat/phxpaxos
phxrpc 项目地址: http://github.com/tencent-wechat/phxrpc
colib 项目地址: http://github.com/tencent-wechat/libco
PhxSQL 编译
如果是直接使用二进制包,请跳过这节。
PhxSQL 主要目录结构
- PhxSQL
- phxsqlproxy
- phxbinlogsvr
- percona
- phx_percona
- plugin
- phxsync_phxrpc
- semisync
- third_party
- glog
- leveldb
- protobuf
- phxpaxos
- colib
- phxrpc
- tools
- phxrpc_package_config
主要目录介绍
目录名 | |
---|---|
phxsqlproxy | phxsqlproxy 模块,负责接入请求。 |
phxbinlogsvr | 负责 MySQL binlog 数据同步,master 管理等。 |
percona | percona5.6.31-77.0 的官方源代码 |
phx_percona/plugin/phxsync_phxrpc | percona 用于跟 phxbinlogsvr 同步 binlog 的插件。 |
phx_percona/plugin/semisync | 因兼容问题,修改了 semisync 的部分代码,目录内为修改过的文件。 |
third_party/glog | Google Glog 第三方库 |
third_party/leveldb | Google Leveldb 第三方库 |
third_party/protobuf | Google Protobuf 3.0+ 第三方库 |
third_party/phxpaxos | paxos 协议库。用于 phxbinlogsvr 之间同步 binlog |
third_party/colib | 协程基础库。phxsqlproxy 使用 |
third_party/phxrpc | rpc 框架。phxbinlogsvr 使用 |
事前准备
安装第三方库
PhxSQL 需要用到一些第三方库(glog, leveldb, protobuf, phxpaxos, colib, phxrpc),下载后安装到 PhxSQL 的 third_party 目录下或者把安装目录链接到 PhxSQL 的 third_party 目录下。
需保证第三方库 glog, protobuf 在 configure 时带上-fPIC 选项(configure CXXFLAGS=-fPIC),并指定--prefix=当前目录绝对路径。
比如 configure CXXFLAGS=-fPIC --prefix=/home/root/phxsql/third_party/glog
.
下载 percona-server-5.6.31-77.0.tar.gz
将 percona-server-5.6\_5.6.31-77.0
源代码放到 PhxSQL 目录下,更名或链接为 percona**(请注意只能使用 percona-server-5.6_5.6.31-77.0 版本)**
生成安装环境
- 在 PhxSQL 目录下执行
sh autoinstall.sh && make && make install
- 若想打包二进制运行包(集群运行时所需要的所有文件和配置)
make package
install
完成后,二进制会生成到PhxSQL
目录下的sbin
目录,运行所需要的相关文件和配置会安装到 PhxSQL 目录下的install_package
目录。打包二进制运行包会把install_package
进行 tar 格式的打包,并生成phxsql.tar.gz
。若想更改install
的安装目录,可在sh autoinstall.sh
后加入-prefix=
路径
PhxSQL 部署和运行
准备机器
PhxSQL 需要在 2 台或以上的机器集群上运行(建议集群内机器数目 n>=3 且 n 为奇数)
初始化 PhxSQL
- 把
phxsql.tar.gz
传到集群内的所有机器,对集群内每台机器按以下步骤进行安装- 解压
phxsql.tar.gz
- 进入
phxsql/tools
, 并使用python install.py --help
查看安装参数。(例子:python2.7 install.py -i"your_inner_ip" -p 54321 -g 6000 -y 11111 -P 17000 -a 8001 -f/tmp/data/
)
- 解压
- 任意找一台机器,
cd phxsql/sbin
, 执行
./phxbinlogsvr_tools_phxrpc -f InitBinlogSvrMaster -h"ip1,ip2,ip3" -p 17000
(17000 为 phxbinlogsvr 监听的端口) - 看到 master 初始化完成的消息后,集群即可使用。
- 可通过
mysql -uroot -h"your_inner_ip" -P$phxsqlproxy_port
进入 PhxSQL 执行读写操作确认 PhxSQL 已正常运行
简单测试
- 在 PhxSQL 目录下进入 tools 目录
- 执行
test_phxsql.sh port ip1 ip2 ip3
,port
为phxsqlproxy_port
,ip
为集群机器ip
配置文件说明
PhxSQL 一共有 3 个配置文件
1. my.cnf: MySQL 的配置,请根据你的业务需求进行修改(安装前请修改 tools/etc_template/my.cnf
,安装后请修改 etc/my.cnf
)
2. phxbinlogsvr.conf
Section name | Key name | comment |
---|---|---|
AgentOption | AgentPort | Phxbinlogsvr 监听 MySQL 访问的端口,用于 MySQL 和 binlogsvr 之间的通信 |
EventDataDir | Phxbinlogsvr 数据存放目录 | |
MaxFileSize | Phxbinlogsvr 每个数据文件的大小,数据文件过大会导致启动过慢,数据文件过小会导致文件数过多,单位为 B | |
MasterLease | Phxbinlogsv 的 master 租约时间,单位为 s | |
CheckPointTime | Phxbinlogsvr 会删除 CheckPointTime 时间前的数据,但如果被删数据中存在其他 MySQL 还没学到的,则不会删除该部分数据,单位为分钟 | |
MaxDeleteCheckPointFileNum | Phxbinlogsvr 删数据时,每次删除的最大文件数 | |
FollowIP | 机器为 folloer 机器,只负责拉取 FollowIP 机器上的数据,不参与集群的投票 | |
PaxosOption | PaxosLogPath | Phxbinlogsvr 中 paxos 库的数据目录 |
PaxosPort | Phxbinlogsvr 中 paxos 库的通信端口 | |
PacketMode | Phxbinlogsvr 在 paxos 协议中是否增大包的大小限制, 1 为每个包的大小为 100m,但超时限制变为 1 分钟,0 为每个包的大小为 50m,超时限制 2s 起(动态变化) | |
Server | IP | Phxbinlogsvr 的监听 ip |
Port | Phxbinlogsvr 的监听端口 | |
LogFilePath | Phxbinlogsvr 的日志目录 | |
LogLevel | Phxbinlogsvr 的日志级别 |
3. phxsqlproxy.conf
Section name | Key name | comment |
---|---|---|
Server | IP | phxsqlproxy 的监听 ip |
Port | phxsqlproxy 的监听端口 | |
QSLogFilePath | phxsqlproxy 的日志目录 | |
QSLogLevel | phxsqlproxy 的日志级别 |
PhxSQL 使用
phxsqlproxy 为 PhxSQL 的接入层,所有的请求均经过 phxsqlproxy,再透传给 MySQL。
phxsqlproxy 提供两个端口进行读写
读写端口
该端口号为 phxsqlproxy.conf 配置中的端口号, 用户连接上 proxyA 的此端口,proxyA 会自动把请求路由到 Master 机器,然后再对 Master 机器上的 MySQL 进行操作。
只读端口
该端口号为读写端口号 +1, 用户连接上此端口时,会对本机的 MySQL 进行操作(但若本机为 master,则 phxsqlproxy 会把请求转发到其他 phxsqlproxy 的只读端口)。
PhxSQL 的使用
- 通过 mysql 命令连接上
phxsqlproxy
,然后执行命令mysql -uroot -h$phxsqlproxyip -P$phxsqlproxyport -ppwd
- 进行 sql 命令操作
phxsqlproxyip 为集群内的任意一台 phxsqlproxy 的 ip
phxsqlproxyport 为 phxsqlproxy 端口(读写/只读)
PhxSQL 管理
PhxSQL 提供一个工具 phxbinlogsvr_tools_phxrpc
来方便管理者对 PhxSQL 的运营管理。
PhxSQL 集群中对 MySQL 的管理使用两个账号管理员帐号和数据同步账号。管理员账号默认账号密码为("root
",""),数据同步账号默认账号密码为("replica
","replica123
")。账号密码的更改通过工具才执行(工具会直接操作 MySQL 数据,不需要人工进行 MySQL 操作)。
phxbinlogsvr_tools -f GetMasterInfoFromGlobal -h <host> -p <port>
**功能:**集群的 master 机器 ip 和超时时间
参数:
- Host: 集群中的其中一台机器 ip
- Port: phxbinlogsvr 的监听 port
phxbinlogsvr_tools -f SetMySqlAdminInfo -h <host> -p <port> -u <admin username> -d <admin pwd> -U <new admin username> -D <new admin pwd>
功能: 设置 PhxSQL 管理员账号密码
参数:
- Host: 集群中的其中一台机器 ip
- Port: phxbinlogsvr 的监听 port
- Admin username: 当前的管理员账号(默认为 root)
- Admin pwd: 当前的管理员密码(默认为空)
- New admin username: 新的管理员账号
- New admin pwd: 新的管理员密码
phxbinlogsvr_tools -f SetMySqlReplicaInfo -h <host> -p <port> -u <admin username> -d <admin pwd> -U <new replica username> -D <new replica pwd>
功能: 设置 PhxSQL 同步数据账号密码
参数:
- Host: 集群中的其中一台机器 ip
- Port: phxbinlogsvr 的监听 port
- Admin username: 当前的管理员账号(默认为 root)
- Admin pwd: 当前的管理员密码(默认为空)
- New replica username: 新的同步数据账号
- New replica pwd: 新的同步数据密码
phxbinlogsvr_tools_phxrpc -f GetMemberList -h <host> -p <port>
**功能:**集群的 master 机器 ip 和超时时间
参数:
- Host: 集群中的其中一台机器 ip
- Port: phxbinlogsvr 的监听 port
phxbinlogsvr 成员管理
移除成员
执行工具命令将机器 A 移除集群 phxbinlogsvr_tools_phxrpc -f RemoveMember -h<host> -p<port> -m <机器A的ip>
执行成功后,机器 A 将会在一段时间后不在接收数据
添加成员
-
执行工具将机器 A 加入到集群
phxbinlogsvr_tools -f AddMember -h<host> -p<port> -m <机器A的ip>
-
在新机器 A 上安装好 PhxSQL
根据 "
初始化PhxSQL
" 步骤安装 PhxSQL -
执行成功后,机器 A 的 phxbinlogsvr 将会在一段时间后开始接收数据
-
从集群内任意一台机器的 percona 导出一份镜像数据
-
kill 掉机器 A 上的 phxbinlogsvr, 并通过本地的 MySQL 端口进入 MySQL,执行
set super_read_only = 0; set read_only = 0
; -
将镜像数据导入到机器 A 上的 percona,并 kill 掉机器 A 上的 phxbinlogsvr
-
一段时间(~1 分钟)后,机器 A 开始正常工作
phxbinlogsvr 故障处理
当机器出现问题,PhxSQL 无法正常启动时,可以选择在该机器上重装 PhxSQL,重装过程可参考 4.2
在重装过程中,phxbinlogsvr
可能会拉取集群内其他机器 checkpoint
来启动,待 checkpoint
拉取结束后,phxbinlogsvr
会自杀(为了确保数据安全),日志中会出现 "All sm load state ok, start to exit process"
,此时须重新启动 phxbinlogsvr
,启动后会正常运行。
当 MySQL 数据出现问题时,phxbinlogsvr 会停止工作,此时需要检查 MySQL 的 binlog 数据是否正常。
当出现问题时,可观察日志中带有 err 标志的红色字体的日志,来确认是否有异常。
性能测试
机型信息
CPU : Intel(R) Xeon(R) CPU E5-2420 0 @ 1.90GHz * 24
内存 : 32G
磁盘 : SSD Raid10
网络互 Ping 耗时
Master -> Slave : 3 ~ 4ms
Client -> Master : 4ms
压测工具和参数
sysbench --oltp-tables-count=10 --oltp-table-size=1000000 --num-threads=500 --max-requests=100000 --report-interval=1 --max-time=200
压测结果
Client 线程数 | 测试集群 | 测试集合 | |||||
---|---|---|---|---|---|---|---|
insert.lua (100% 写) | select.lua (0% 写) | OLTP.lua (20% 写) | |||||
QPS | 耗时 | QPS | 耗时 | QPS | 耗时 | ||
200 | PhxSQL | 5076 | 39.34/56.93 | 46334 | 4.21/5.12 | 25657 | 140.16/186.39 |
200 | MySQL 半同步 | 4055 | 49.27/66.64 | 47528 | 4.10/5.00 | 20391 | 176.39/226.76 |
500 | PhxSQL | 8260 | 60.41/83.14 | 105928 | 4.58/5.81 | 46543 | 192.93/242.85 |
500 | MySQL 半同步 | 7072 | 70.60/91.72 | 121535 | 4.17/5.08 | 33229 | 270.38/345.84 |
注:耗时分别为测试结果的平均耗时/95% 分线耗时,单位 ms |
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于