近期项目组在使用mycat去做mysql的读写分离时有遇到一些问题,如在要求使用useCursorFetch=true时,后端路由转发可能会不正常,为此寻找替代mycat的中间件。项目只需求库级别(不涉及到分区表)的读写分离和读的负载均衡,maxscale较为符合,记录下在Centos7下安装maxscale以及简单的读写分离测试
一、环境准备
数据库是一主两从的机构(mysql的主从搭建不在此说明),maxscale安装在主库所在服务器上(也可以不与数据库安装在同一服务器上)
hostname | ip | status |
mysql-master | 192.168.2.18 | 主库 提供写服务 |
mysql-slave1 | 192.168.2.19 | 从库 提供读服务 |
mysql-slave2 | 192.168.2.20 | 从库 提供读服务 |
二、下载安装
Maxscale是由MariaDB官方提供的中间件,并负责升级和维护,可在官网中进行下载,另外可以查看官方提供的详细文档,本例中所有的安装方式都是选用maxscale-2.4版本。
1、以yum的方式安装
在网络条件运行的情况下,我会优先选用yum的方式进行安装部署,对此官网也提供了详细的说明文档:MariaDB Package Repository Setup and Usage,这里做简单的记录。
- 下载yum源文件
curl -LsS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup |
sudo bash -s -- --mariadb-maxscale-version="2.4" --os-type=rhel --os-version=7
正常完成会有如下提示:
- 确认下源文件中有所需的maxscale
yum search maxscale
- 下载安装
yum install maxscale
- 启动
systemctl start maxscale
2、以rpm的方式安装
- 下载安装rpm包
官网上下载自己所需版本的安装包。 - 安装
rpm -ivh maxscale-2.4.13-1.rhel.7.x86_64.rpm
[NOTE]
我的环境是直接安装成功了,有些环境可能会报错提示需要安装一些依赖,这里也说明一下:yum install libcurl libaio OpenSSL gnutls
- 启动
CentoOS7下使用rpm方式安装完成后会自己创建对应的maxscale.service文件,以及配置文件默认在/etc/maxscale.cnf,直接使用systemctl方式启动即可:systemctl start maxscale
3、以编译的方式安装
- 官网提供了编译源码的方式进行安装,具体安装过程可以参考官方文档:Building MariaDB MaxScale from Source Code
4、直接下载文件部署使用
- 另外还提供了压缩包,下载解压后可直接使用,当然也需要按照要求进行相应的配置,具体安装过程可以参考官方文档:Installing MariaDB MaxScale using a tarball
三、参数配置
- 以yum或rpm方式安装的maxscale,默认的参数文件是/etc/maxscale.cnf,也可以在启动的时候使用-f参数指定参数文件,如
maxscale -f /u01/maxscale.cnf
。每个版本的参数文件会所有不同,官网提供了详细的参数文件说明,本例记录了一些项目所需的参数说明。 - 先看一份配置好的参数文件
# MaxScale documentation:
# https://mariadb.com/kb/en/mariadb-maxscale-24/
# Global parameters
#
# Complete list of configuration options:
# https://mariadb.com/kb/en/mariadb-maxscale-24-mariadb-maxscale-configuration-guide/
[maxscale]
threads=auto
# log
syslog=0
# syslog=<0|1> 是否将log记录到/var/log/messages中
maxlog=1
# maxlog=<0|1> 将日志记录到file,默认在/var/log/maxscale/maxscale.log
log_info=1
# <0|1> 设置日志的级别为info
# logdir=/tmp
# 日志的存储位置,不设置的话默认在/var/log/maxscale/,需要对目录有读写权限
# datadir=
# 数据文件存储目录,默认在/var/lib/maxscale
# piddir=
# pid文件存储目录,默认在/var/run/maxscale
# Server definitions
#
# Set the address of the server to the network
# address of a MariaDB server.
#
[server1]
type=server
address=192.168.2.18
port=3306
protocol=MariaDBBackend
[server2]
type=server
address=192.168.2.19
port=3306
protocol=MariaDBBackend
[server3]
type=server
address=192.168.2.20
port=3306
protocol=MariaDBBackend
# Monitor for the servers
#
# This will keep MaxScale aware of the state of the servers.
# MariaDB Monitor documentation:
# https://mariadb.com/kb/en/mariadb-maxscale-24-mariadb-monitor/
[MariaDB-Monitor]
type=monitor
module=mariadbmon
servers=server1,server2,server3
user=scalemon
password=123456
monitor_interval=2000
# Service definitions
#
# Service Definition for a read-only service and
# a read/write splitting service.
#
# ReadConnRoute documentation:
# https://mariadb.com/kb/en/mariadb-maxscale-24-readconnroute/
# [Read-Only-Service]
# type=service
# router=readconnroute
# servers=server1
# user=myuser
# password=mypwd
# router_options=slave
# ReadWriteSplit documentation:
# https://mariadb.com/kb/en/mariadb-maxscale-24-readwritesplit/
[Read-Write-Service]
type=service
router=readwritesplit
servers=server1,server2,server3
user=maxscale
password=123456
max_slave_connections=100%
# connection_timeout=300
# max_connections=100
max_slave_replication_lag=60
# 允许主从最大延迟(s),超过此数值从库不接受读请求
# master_reconnection=1
# master_failure_mode=error_on_write
# Listener definitions for the services
#
# These listeners represent the ports the
# services will listen on.
#
# [Read-Only-Listener]
# type=listener
# service=Read-Only-Service
# protocol=MariaDBClient
# port=4008
[Read-Write-Listener]
type=listener
service=Read-Write-Service
protocol=MariaDBClient
port=4006
- 参数文件中主要是5个模块,Global parameters、Server definitions、Monitor for the servers、Service definitions和Listener definitions for the services。
- Global parameter是全局参数,上述文件中主要对线程数和日志做了设置
- threads=auto表示跟CPU核数一样也可以自定义其他数值;
- 对于log日志,只需要记录在专门的日志文件即可,无需在syslog再记录一份,日志级别需要查看每条查询的路由情况可以把info级别开启,后续需要注意日志文件逐渐变大,可做转储;
- 其余参数不进行配置使用默认的即可。
- Server definitions配置了后端数据库,参考上述文件即可,其中protocol目前只有MariaDBBackend协议。
- Monitor for the servers是配置监控后端数据库的相关参数,其中有几种模式,这里采用的是mariadbmon
- servers的值对应上一个模块中后端数据库,用逗号隔开;
- monitor_interval设置的是监控频率,单位是ms,默认是2000ms;
- user和password是监控数据库时所用到的数据库用户和密码,此用户需要在数据库上创建并赋权,需要replication和client权限
grant replication client on *.* to to scalemon@'%' identified by '123456';
- Service definitions是配置我们所用的服务策略,如readconnroute和readwritesplit等,项目主要是需要读写分离,即readwritesplit。
- router设置成readwritesplit;
- max_slave_connections设置成100%,表示读负载到所有的slave数据库
- max_slave_replication_lag设置的是从库最大延迟,单位是秒,即当从库的延迟大于所设置的值时,读请求不再路由到此从库上
- user和password是路由账号,maxscale使用该账号将不同的请求分发到不同的节点上。当客户端连接到maxscale这个节点上时,maxscale节点会使用该账号去查后端数据库,检查客户端登陆的用户是否有权限或密码是否正确等等;
grant select on mysql.* to maxscale@'%' identified by '123456';
grant show databases on *.* to maxscale@'%' identified by '123456';
- master_reconnection和master_failure_mode是设置主库宕机下的配置
master_failure_mode有三个值,fail_instantly、fail_on_write和error_on_write,默认是fail_instantly即当主库宕机时,立即关闭连接并不再接受新连接;fail_on_write和error_on_write分别代表是主库宕机的情况下,当有写请求连接来时,分别断开连接和报错,即主库宕机时只接受只读连接;如果主库恢复了,只读连接在不断开的情况下变成读写连接的话,就需要master_reconnection设置成1,即enable。
- Listener definitions for the services用于配置上述服务策略的监听
- service设置成上述服务策略中的对应名称
- protocol目前只支持MariaDBClient
- port监听的端口,读写分离默认的是4006,只读默认的是4008。
四、命令说明
1、maxscale
- 用于启动maxscale,可以添加参数,
maxscale --help
- 以yum和rpm方式安装,有些默认的参数如下:
config file : /etc/maxscale.cnf
configdir : /etc
logdir : /var/log/maxscale
cachedir : /var/cache/maxscale
libdir : /usr/lib64/maxscale
datadir : /var/lib/maxscale
execdir : /usr/bin
language : /var/lib/maxscale
piddir : /var/run/maxscale
persistdir : /var/lib/maxscale/maxscale.cnf.d
module configdir : /etc/maxscale.modules.d
connector plugins : /usr/lib64/mysql/plugin
2、maxctrl
- 在老的版本中是maxadmin,2.4及之后的版本开始统一使用maxctrl命令来操作maxscale,先看下基本格式
maxctrl --help
查看具体命令的使用方法,如查看list命令的使用方法:maxctrl help list
- 查看后端数据库
maxctrl list servers
- 查看maxscale的服务策略
maxctrl list services
[NOTE]
更多的命令可以自行结合help命令去尝试。
五、简单的测试
1、读写分离测试
- 创建一个用于测试的数据库用户:
grant all on *.* to scott@'%' identified by 'tiger';
- 通过maxscale访问数据库:
mysql -uscott -ptiger -h192.168.2.18 -P4006
- 验证读写分离
可以看到读的请求发送到了从库上,写的请求发送到的主库上,如果log日志开启了info级别,在日志中也可以清楚看到路由情况。
2、只读从库负载均衡测试
- 开启三个窗口执行:
mysql -uscott -ptiger -h192.168.2.18 -P4006 -BNe "select @@hostname;select sleep(100);"
可以看到三次读请求分别路由到了slave1、slave2、slave1上,实现了负载均衡
[NOTE]
对于负载均衡还可以设置权重,具体的设置方法可以参考官方文档进程参数调整。
3、从库延迟配置测试
- 开启从库延迟限制,即设置max_slave_replication_lag=60
- 在slave1上执行:
flush table with read lock;
- 在master上创建一个test数据库,并创建一张t1表,插入一条数据
- 通过maxscale连接数据库查询:
mysql -uscott -ptiger -h192.168.2.18 -P4006 -BNe "select @@hostname;"
一分钟后再次执行上述语句:
可以看到slave1上的延迟超过60s,读请求不再发送到slave1,而且路由到了没有延迟的slave2上。在slave1上解除表锁unlock tables;
后slave1重新接受读请求。
4、主库从库分别宕机测试
- 单独关闭slave1,模拟一台从库宕机
- 继续关闭slave2,模拟两台从库都宕机
读查询路由到了主库中,老的版本可能还需要配置detect_stale_master=true,2.4版本已经不再需要配置此参数。
- 开启两台从库,然后关闭主库
- 直接关闭主库,即默认master_failure_mode=fail_instantly
- 设置master_reconnection=1,master_failure_mode=error_on_wirte后关闭主库,然后再开启主库
可以看到通过maxscale还是可以连接数据库,并且可以执行只读查询,当要进行写操作时,有报错提示,说明此时数据库在只读模式下,然后重启主库之后,直接恢复,无需重新开个连接。
- 设置master_reconnection=1,master_failure_mode=fali_on_wirte后关闭主库,然后再开启主库
一样可以通过maxscal连接数据库,并且可以执行只读查询,当要进行写操作时,是fail的报错,然后重启主库之后,再进行写操作时,会自己重连主库,也是无需重新卡个新的连接。
六、其他
- maxscale配置简单,能实现读写分离和读的负载均衡,但是本身没有高可用的功能,不能提供数据库的高可用,本身节点也要配合类似keepalived才能实现高可用。
- 测试中发现只要开启事务,就会路由到主库上,据了解java中对事务本身可以定义只读事务、读写事务等,当然理想情况下希望只读事务也可以路由到从库中执行,这一点还需要再做测试