服务器环境:
[root@node155 ~]# rpm -qa | grepmaxscale
maxscale-2.4.2-1.x86_64
[root@node155 ~]# cat /etc/redhat-release
CentOS release 6.9 (Final)
[root@node155 ~]# uname -a
Linux node155 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 2119:29:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
配置拓扑图:
本文利用一主两从的复制架构介绍Maxscale读写分离的实现,环境如下:
角色
|
主机名
|
IP地址
|
操作系统
|
软件版本
|
备注
|
Maxscale
|
node96
|
10.1.20.96
|
CentOS release 6.9 (Final) x86_64
|
maxscale-2.4.2-1.x86_64
|
读写分离中间件
|
MasterDB
|
node93
|
10.1.20.93
|
CentOS release 6.9 (Final) x86_64
|
MySQL-5.7.18
|
读写操作
|
SlaveDB01
|
node95
|
10.1.20.95
|
CentOS release 6.9 (Final) x86_64
|
MySQL-5.7.18
|
只读操作
|
SlaveDB02
|
node94
|
10.1.20.94
|
CentOS release 6.9 (Final) x86_64
|
MySQL-5.7.18
|
只读操作
|
目前的主从结构:
node93 10.1.20.93 master
node94 10.1.20.94 slave
node95 10.1.20.95slave
node96 10.1.20.96 maxscale
先在master主库上创建相关的账户:
在开始配置之前,需要在 master中为MaxScale 创建两个用户,用于监控模块,路由以及连接模块。
创建监控用户,用于[MySQL Monitor]段的配置中:
> create databasemaxscale_schema; # maxscale监控用的心跳信息会写到这个库里面
> create userscalemon@"%"; identified by "123456";
> grant RELOAD, SUPER, replication slave, replicationclient on *.* to scalemon@'%';
> grant all on maxscale_schema.* toscalemon@'%';
> GRANT SHOW DATABASES ON*.* TO scalemon@'%';
创建路由用户,用于[Read-Write Service]段的配置中:
> create usermaxscale@'%' identified by "123456";
> grant select on mysql.* tomaxscale@'%';
在maxscale服务器上部署:
rpm -ivh maxscale-2.4.2-1.x86_64.rpm
主要生成文件如下:
/etc/maxscale.cnf.template
/etc/prelink.conf.d
/etc/prelink.conf.d/maxscale.conf
/usr/bin/cdc.py
/usr/bin/cdc_kafka_producer.py
/usr/bin/cdc_last_transaction.py
/usr/bin/cdc_one_schema.py
/usr/bin/cdc_schema.py
/usr/bin/cdc_users.py
/usr/bin/dbfwchk
/usr/bin/maxadmin
/usr/bin/maxavrocheck
/usr/bin/maxbinlogcheck
/usr/bin/maxctrl
/usr/bin/maxkeys
/usr/bin/maxpasswd
/usr/bin/maxscale
/usr/bin/maxscale_generate_support_info.py
/usr/lib64/maxscale
/usr/lib64/maxscale/libauroramon.so
/usr/lib64/maxscale/libauroramon.so.1.0.0
/usr/lib64/maxscale/libavro-common.so
/usr/lib64/maxscale/libavro-common.so.1.0.0
/usr/lib64/maxscale/libavrorouter.so
/usr/lib64/maxscale/libavrorouter.so.1.0.0
/usr/lib64/maxscale/libbinlogfilter.so
服务器参数优化:
vim /etc/security/limits.conf:
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
vim/etc/sysctl.conf :
fs.file-max=65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_syn_backlog = 65536
net.ipv4.tcp_max_tw_buckets = 20000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_max_orphans= 262144
应用内核配置文件:
#sysctl -p
修改配置文件:
cat /etc/maxscale.cnf
[maxscale]
threads=auto
ms_timestamp=1 #timestamp精度
syslog=1 #将日志写入到syslog中
maxlog=1 #将日志写入到maxscale的日志文件中
#log_to_shm=0 #不将日志写入到共享缓存中,开启debug模式时可打开加快速度
log_warning=1 #记录告警信息
log_notice=1 #记录notice
log_info=1 #记录info
log_debug=0 #不打开debug模式
log_augmentation=1 #日志递增
# Server definitions
#
# Set the address ofthe server to the network
# address of a MySQLserver.
#
# 需要把master和slave地址都配上,maxscale会自动分辨出哪个是master和slave
[server1]
type=server
address=10.1.20.93
port=3306
protocol=MySQLBackend
server_weight=1
[server2]
type=server
address=10.1.20.94
port=3306
protocol=MySQLBackend
server_weight=10
[server3]
type=server
address=10.1.20.95
port=3306
protocol=MySQLBackend
server_weight=10
# Monitor for theservers
#
# This will keepMaxScale aware of the state of theservers.
# MySQL Monitordocumentation:
#https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Monitors/MySQL-Monitor.md
[MySQL Monitor]
type=monitor
module=mysqlmon
servers=server1,server2,server3 # 这里要把全部server都写上,以便maxscale去监测
user=scalemon #这里的帐号密码是在数据库主库新创建的帐号
passwd=123456
monitor_interval=10000 # 每隔10s检查一次,探测间隔,单位毫秒
detect_replication_lag=true # 检查复制延迟的情况
detect_stale_master=true # 当所有的slave都不可用时,select查询请求会转发到master, 当集群中只剩下主或主从复制全出错时,是否允许主提供服务
auto_failover=true #是否故障自动切换
auto_rejoin=true #故障实例恢复后自动加入集群
detect_standalone_master=true #探测独立的master,是否允许集群中最后一个实例成为主库
failcount=3 #在集群中最后一个实例成为主库前检查其它从库是否存活的次数,默认为5
detect_stale_slave=true #告诉 MaxScale 我们需要一个稳定的 slave,master down掉后,slave可以继续提供读服务
#触发器定义 注意,以下两句的上下顺序不能变,不然无法生效
script=/opt/mysql_monitor.sh #定义事件触发脚本执行
events=master_down #事件触发器当master down时,执行上面的脚本,maxscale内置了很
多的events
# Service definitions
#
# Service Definitionfor a read-only service and
# a read/writesplitting service.
#
# ReadConnRoutedocumentation:
#https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Routers/ReadConnRoute.md
# 需要把master和slave地址都配上
[Read-Only Service] #配置读服务,虽然字面意思为读服务,也可以执行DML,DDL等操作,取决于对用户的授权,因此可以理解为连接服务
type=service
router=readconnroute
servers=server1,server2,server3
user=maxscale # 读写分离的账户和密码
passwd=123456 # 读写分离的账户和密码
router_options=slave
# ReadWriteSplitdocumentation:
#https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Routers/ReadWriteSplit.md
# 配置的读写分离,需要把master和slave地址都配上
[Read-Write Service]
type=service
router=readwritesplit ##读写分离路由模式
servers=server1,server2,server3
user=maxscale # 读写分离的账户和密码,该用户从后端mysql获取用户信息,对客户端进行身份验证,必须具有mysql.user table的select权限
passwd=123456 # 读写分离的账户和密码
max_slave_connections=100% # 所有的slave提供select查询服务
max_slave_replication_lag =5 # slave超时5秒,就把请求转发到其他slave 允许最大主从延迟,当主从延迟超过该值时,不再向从库分发读请求
use_sql_variables_in =all #
# This service enablesthe use of the MaxAdmininterface
# MaxScaleadministration guide:
#https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Reference/MaxAdmin.md
[MaxAdmin Service]
type=service
router=cli
# Listener definitionsfor the services
#
# These listenersrepresent the ports the
# services will listenon.
#
[Read-Only Listener]
type=listener
service=Read-OnlyService
protocol=MySQLClient
port=4008
[Read-Write Listener]
type=listener
service=Read-Write Service
protocol=MySQLClient
port=4006
[MaxAdmin Listener]
type=listener
service=MaxAdmin Service
protocol=maxscaled
启动maxscale:
service maxscale start
[root@node155 ~]# service maxscale status
Checking MaxScale status: MaxScale (pid 24390) 正在运行...[确定]
[root@node155 ~]# netstat -lntup | grep maxscale
tcp 0 0127.0.0.1:8989 0.0.0.0:* LISTEN 24390/maxscale
tcp 0 0 :::4006 :::* LISTEN 24390/maxscale
tcp 0 0 :::4008 :::* LISTEN 24390/maxscale
可以看到读写分离端口4006和只读端口4008已经启动
4006:读写分离端口
4008:只读端口
ss -lnt 可以看到4006端口启动了。
可以使用之前的业务账号连接到maxscale的4006端口上,(不能使用root用户登录,会报错,也可以通过配置文件允许root登录)
例如:
mysql -utest -ptest -P 4006 -h10.1.20.96
注意begin;select@@hostname;commit;这种的select会在主库上执行。此外,执行存储过程或者函数时候也是会自动在主库去执行的。
执行SQL > begin;select@@hostname; commit;insert into t2 select 3; select @@hostname;
对应的在/var/log/maxscale/maxscale.log记录如下:
很明显的可以看:开启事务、插入等操作会被转发到主库去处理。而单纯的select则会被转发到某个从库去处理。
maxscale不能对master进行故障切换,可以配合使用MHA来进行。MHA的故障切换后,maxscale可以自动识别哪台机器是master。然后自动将求发送到新的主从结构中。