mysql router是mysql官方提供的一个轻量级中间件,是innodb cluster的一部分,可在应用程序和后端mysql服务器之间提供透明路由;它主要用以解决mysql主从库集群的高可用、负载均衡、易扩展等问题。mysql router为数据库集群提供一个虚拟ip作为应用程序单一连接点,通过这个单一的连接点实现负载均衡,读写分离,故障转移等数据库高可用方案。
本教程操作环境:windows7系统、mysql8版本、dell g3电脑。
一、介绍
1.1mysql router简介
mysql router是mysql官方提供的一个轻量级中间件,是innodb cluster的一部分,可在应用程序和后端mysql服务器之间提供透明路由。主要用以解决mysql主从库集群的高可用、负载均衡、易扩展等问题。router作为一个流量转发层,位于应用与mysql服务器之间,其功能类似于lvs。
1.2为什么要用mysql router?
基于组复制(mgr)的机制,当主节点宕机离开集群,剩余的其他节点会基于paxos协议选举一个新的主节点。这里有一个问题,应用程序端如果连接到了主节点,这时主节点宕机离开集群,可用的数据库ip地址发生变化,客户端应用程序这个时候还是会向失败的节点尝试连接,虽然可以修改客户端应用程序的连接配置,但是这种情况基本是不现实的。
1.3mysql router关系图
结合mysql group replication和mysql shel如下:
上图充分说明了mysql router在innodb集群里面的角色,主要作用是为数据库集群提供一个虚拟ip作为应用程序单一连接点,通过这个单一的连接点实现负载均衡,读写分离,故障转移等数据库高可用方案。
mysql router推荐安装在应用程序所在的机器上,原因包括:
- 通过本地unix套接字连接,而不是tcp/ip,提升性能
- 降低网络延迟
- mysql实例不需要额外的账号,只需要一个router@198.51.100.45, 而不是myapp@%
- 提升应用程序服务器的可扩展性
1.4mysql cluster简介
cluster是这个高可用方案中的一个虚拟节点,它会在mgr的所有成员上创建一个名为mysql_innodb_cluster_metadata的数据库,存储集群的元数据信息,包括集群信息、集群成员、组复制信息、连接的mysql router等信息,以提供mysql router查询。它相当于对组复制上的成员做了一层逻辑上的封装,以一个集群的模式展现出来,各节点的状态与对应实例在组复制中成员的状态实时同步,但是集群的节点与组复制的成员只在创建集群时同步,后期组复制的成员变更并不自动同步到集群中,可以在集群中做手动的节点增减,这样使得面向应用端的具体实例实现了更可控更灵活的高可用。
二、环境准备
主机名 | ip地址 | 角色 |
---|---|---|
oratest51 | 172.16.9.51 | primary |
oratest52 | 172.16.9.52 | seconde |
test61 | 172.16.9.61 | seconde |
node4 | 172.16.8.68 | mysql router |
操作系统:centos linux release 7.2.1511
mysql版本:mysql-5.7.26-linux-glibc2.12-x86_64
mysql router版本:mysql-router-8.0.17-linux-glibc2.12-x86_64
mysql shell版本:mysql-shell-8.0.17-linux-glibc2.12-x86-64bit
三、安装和配置mysql router
mysql router有两种部署模式:
- bootstrap模式:支持failover,必须结合innodb cluster使用,在--directory指定的路径下自动生成安装目录,配置文件里的端口为6446和6447。
- 简单模式:不支持failover,无需结合innodb cluster使用,一般在主从复制或者主主复制等模式下使用,使用/usr/local/mysqlrouter/share/doc/mysqlrouter/sample_mysqlrouter.conf这个配置文件部署。
3.1bootstrap模式安装mysql router
注意: 使用bootstrap的方式安装mysql router的前提条件是mgr已装好,mysql shell已装好,innodb cluster已经配置好
3.1.1使用yum源的方式安装mysql router
# wget -p /software/ https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm # rpm -uvh /software/mysql80-community-release-el7-3.noarch.rpm # yum -y install mysql-router
3.1.2查看mysql router的默认配置
[root@node4 yum.repos.d]# mysqlrouter --help mysql router ver 8.0.16 for linux on x86_64 (mysql community - gpl) copyright (c) 2015, 2019, oracle and/or its affiliates. all rights reserved. oracle is a registered trademark of oracle corporation and/or its affiliates. other names may be trademarks of their respective owners. configuration read from the following files in the given order (enclosed in parentheses means not available for reading): /etc/mysqlrouter/mysqlrouter.conf (/root/.mysqlrouter.conf) plugins path: /usr/lib64/mysqlrouter default log directory: /var/log/mysqlrouter default persistent data directory: /var/lib/mysqlrouter default runtime state directory: /run/mysqlrouter
通过mysqlrouter --help可以看到默认的一些路径:
- 配置文件:/etc/mysqlrouter/mysqlrouter.conf
- 插件路径:/usr/lib64/mysqlrouter
- 日志路径:/var/log/mysqlrouter
- 持久化数据路径:/var/lib/mysqlrouter
- 运行时状态路径:/run/mysqlrouter
如果在mysqlrouter命令行使用--config或-c选项传入用户定义的配置文件,则不会加载默认配置文件。
3.1.3初始化mysql router,地址填primary的地址
[root@node4 tmp]# mysqlrouter --bootstrap root@172.16.9.51:3306 --directory /data/mysqlrouter --conf-use-sockets --user=root please enter mysql password for root: warning: the mysql server does not have ssl configured and metadata used by the router may be transmitted unencrypted. # bootstrapping mysql router instance at '/data/mysqlrouter'... - checking for old router accounts - no prior router accounts found - creating mysql account mysql_router1_zhi3m2uhudci@'%' for cluster management - storing account in keyring - adjusting permissions of generated files - creating configuration /data/mysqlrouter/mysqlrouter.conf # mysql router configured for the innodb cluster 'st' #innodb集群名 after this mysql router has been started with the generated configuration $ mysqlrouter -c /data/mysqlrouter/mysqlrouter.conf the cluster 'st' can be reached by connecting to: ## mysql classic protocol - read/write connections: localhost:6446, /data/mysqlrouter/mysql.sock - read/only connections: localhost:6447, /data/mysqlrouter/mysqlro.sock ## mysql x protocol - read/write connections: localhost:64460, /data/mysqlrouter/mysqlx.sock - read/only connections: localhost:64470, /data/mysqlrouter/mysqlxro.sock
--bootstrap:引导并配置router以便与mysql innodb集群一起运行。
3.1.4编辑配置文件,一般只需要配置bootstrap_server_addresses这一行即可
# file automatically generated during mysql router bootstrap [default] user=root logging_folder=/data/mysqlrouter/log runtime_folder=/data/mysqlrouter/run data_folder=/data/mysqlrouter/data keyring_path=/data/mysqlrouter/data/keyring master_key_path=/data/mysqlrouter/mysqlrouter.key connect_timeout=15 read_timeout=30 #dynamic_state=/data/mysqlrouter/data/state.json [logger] level = info [metadata_cache:st] router_id=14 bootstrap_server_addresses=mysql://oratest51:3306,mysql://oratest52:3306,mysql://test61:3306 user=mysql_router14_ebhje7bsnckc metadata_cluster=st ttl=300 use_gr_notifications=0 [routing:st_default_rw] bind_address=0.0.0.0 bind_port=6446 socket=/data/mysqlrouter/mysql.sock destinations=metadata-cache://st/default?role=primary routing_strategy=first-available protocol=classic [routing:st_default_ro] bind_address=0.0.0.0 bind_port=6447 socket=/data/mysqlrouter/mysqlro.sock destinations=metadata-cache://st/default?role=secondary routing_strategy=round-robin-with-fallback protocol=classic [routing:st_default_x_rw] bind_address=0.0.0.0 bind_port=64460 socket=/data/mysqlrouter/mysqlx.sock destinations=metadata-cache://st/default?role=primary routing_strategy=first-available protocol=x [routing:st_default_x_ro] bind_address=0.0.0.0 bind_port=64470 socket=/data/mysqlrouter/mysqlxro.sock destinations=metadata-cache://st/default?role=secondary routing_strategy=round-robin-with-fallback protocol=x
3.1.5启动mysql router
[root@node2 mysqlrouter]# cd /data/mysqlrouter/ [root@node2 mysqlrouter]# sh start.sh
启动过程较慢,日志里可以看到启动信息
3.1.6测试连接mysql router
默认情况下,使用6446作为rw端口,使用6447作为ro端口
# mysql -uroot -p123456 -h172.16.8.68 -p6446 # mysql -uroot -p123456 -h172.16.8.68 -p6447 # netstat -ntlp |grep mysqlrouter
3.2简单模式安装mysql router
3.2.1下载软件包并上传到服务器
[root@node4 etc]# mkdir /software;cd /software [root@node4 etc]# wget https://cdn.mysql.com//downloads/mysql-router/mysql-router-8.0.17-linux-glibc2.12-x86_64.tar.xz
3.2.2解压到指定目录
[root@node4 etc]# tar -jxvf /software/mysql-router-8.0.17-linux-glibc2.12-x86_64.tar.xz -c /usr/local/ [root@node4 etc]# cd /usr/local [root@node4 etc]# mv mysql-router-8.0.17-linux-glibc2.12-x86_64/ mysqlrouter
3.2.3设置环境变量
[root@node4 etc]# echo 'export path=/usr/local/mysqlrouter/bin/:$path' >> /etc/profile [root@node4 etc]# source /etc/profile
3.2.4编辑配置文件
# mkdir -p /usr/local/mysqlrouter/etc # cp /usr/local/mysqlrouter/share/doc/mysqlrouter/sample_mysqlrouter.conf /usr/local/mysqlrouter/etc # mv /usr/local/mysqlrouter/etc/sample_mysqlrouter.conf /usr/local/mysqlrouter/etc/mysqlrouter.conf # vim /usr/local/mysqlrouter/etc/mysqlrouter.conf ##部分省略 [default] logging_folder =/usr/local/mysqlrouter/log/ plugin_folder = /usr/local/mysqlrouter/lib/mysqlrouter/ config_folder = /usr/local/mysqlrouter/etc/ runtime_folder = /usr/local/mysqlrouter/run/ data_folder = /usr/local/mysqlrouter/data/ keyring_path = /var/lib/keyring-data master_key_path = /var/lib/keyring-key [logger] level = info [routing:masters] bind_address = 172.16.8.68:7002 destinations = 172.16.9.61:3306 mode = read-write connect_timeout = 2 [routing:slaves] bind_address = 172.16.8.68:7001 destinations = 172.16.9.51:3306,172.16.9.52:3306 mode = read-only connect_timeout = 1 ##部分省略
/usr/local/mysqlrouter/share/doc/mysqlrouter/sample_mysqlrouter.conf这个是mysql router的参照配置文件,所以这里先把模板复制出来。
mysql router默认会寻找安装目录下的"mysqlrouter.conf"和家目录下的".mysqlrouter.conf"。也可以在二进制程序mysqlrouter命令下使用"-c"或者"--config"手动指定配置文件。
mysql router的配置文件是片段式的,常用的就3个片段:[default]、[logger]、[routing:name],片段名称区分大小写,且只支持单行"#"或";"注释。
- bind_address:添加mysql router所在机器的ip
- destinations:后端的mysql服务器ip+端口
- mode:提供两种mode,read-only和read-write,read-write的调度方式为first-available,read-only的调度方式为round-robin
- connect_timeout:连接超时时间
- routing_strategy:路由策略,有round-robin和first-available策略
如果是多主模式,配置文件如下
[routing:mutili_rw] bind_address=172.16.8.68 bind_port=7003 destinations=172.16.9.51:3306,172.16.9.52:3306,172.16.9.61:3306 mode=read-write connect_timeout=2 protocol=classic
3.2.5创建上一步中配置文件里指定的目录
[root@node4 etc]# mkdir -p /usr/local/mysqlrouter/run/ [root@node4 etc]# mkdir -p /usr/local/lib/mysqlrouter [root@node4 etc]# mkdir -p /usr/local/mysqlrouter/etc/ [root@node4 etc]# mkdir -p /usr/local/mysqlrouter/run/ [root@node4 etc]# mkdir -p /usr/local/mysqlrouter/data/ [root@node4 etc]# mkdir -p /usr/local/mysqlrouter/log/
3.2.6启动mysql router
[root@node4 etc]# mysqlrouter --config /usr/local/mysqlrouter/etc/mysqlrouter.conf &
3.2.7查看mysql router的端口监听是否已开启
[root@node4 etc]# netstat -ntlp |grep mysqlrouter tcp 0 0 172.16.8.68:7001 0.0.0.0:* listen 9221/mysqlrouter tcp 0 0 172.16.8.68:7002 0.0.0.0:* listen 9221/mysqlrouter
mysql router的停止暂时没有停止脚本,如果要停止需要用kill -9的方式杀掉进程
四、功能测试
以下测试都是在innodb cluster下,mysql router的安装模式是bootstrap
4.1路由验证
4.1.1测试通过mysql router连接6446 rw端口,查看连接的是否为primary
[root@node4 mysqlrouter]# for ((i=0;i<=5;i++));do mysql -h172.16.8.101 -uroot -p123456 -p6446 -e"select @@hostname;";done; mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest51 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest51 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest51 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest51 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest51 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest51 | +------------+
测试结果: 使用6446 rw端口会访问到后端innodb cluster的primary
4.1.2测试通过mysql router连接6447 ro端口,查看连接的是否为seconde节点,rr算法是否生效
[root@node4 mysqlrouter]# for ((i=0;i<=5;i++));do mysql -h172.16.8.101 -uroot -p123456 -p6447 -e"select @@hostname;";done; mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest52 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest52 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest52 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+
测试结果: 使用6447 ro端口会连接到后端innodb cluster集群中所有的seconde节点,并且以rr(round-robin)的策略调度
4.2高可用测试
4.2.1模拟其中一台seconde节点宕机,查看mysql router是否会自动取消该节点的路由
(1) 停掉一台seconde节点
[root@oratest52 ~]# systemctl status mysql [root@oratest52 ~]# systemctl stop mysql [root@oratest52 ~]# systemctl status mysql
(2) 在innodb cluster中查看集群状态,可以看到oratest52已经处于missing状态
mysql 172.16.9.51:3306 js > cluster.status() { "clustername": "st", "defaultreplicaset": { "name": "default", "primary": "oratest51:3306", "ssl": "disabled", "status": "ok_no_tolerance", "statustext": "cluster is not tolerant to any failures. 1 member is not active", "topology": { "oratest51:3306": { "address": "oratest61:3306", "mode": "r/o", "readreplicas": {}, "role": "ha", "status": "online" }, "oratest52:3306": { "address": "oratest52:3306", "mode": "n/a", "readreplicas": {}, "role": "ha", "shellconnecterror": "mysql error 2003 (hy000): can't connect to mysql server on 'oratest52' (111)", "status": "(missing)" }, "test61:3306": { "address": "test51:3306", "mode": "r/w", "readreplicas": {}, "role": "ha", "status": "online" } }, "topologymode": "single-primary" }, "groupinformationsourcemember": "test61:3306" }
(3) 在mgr中查看gr状态,可以看到已经没有oratest52这台机器
mysql> select * from performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+ | channel_name | member_id | member_host | member_port | member_state | +---------------------------+--------------------------------------+-------------+-------------+--------------+ | group_replication_applier | 48cdca42-a386-11e9-95f1-0050569d2587 | test61 | 3306 | online | | group_replication_applier | e9ee5267-a386-11e9-ac35-0050569d9ef5 | oratest51 | 3306 | online | +---------------------------+--------------------------------------+-------------+-------------+--------------+
(4) 测试通过6447 ro端口连接,查看是否会自动剔除宕机的oratest52节点
[root@node4 ~]# for ((i=0;i<=5;i++));do mysql -h172.16.8.101 -uroot -p123456 -p6447 -e"select @@hostname;";done; mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+
测试结果: mysql router会自动剔除宕机的oratest52节点,read请求只会转发到后端正常的mysql实例,过程无需人工干预。
4.2.2启动上一步中停止的mysql实例,确认mgr和innodb cluster一切正常后,查看mysql router是否会自动加入这台已恢复的实例进行转发
(1) 启动oratest52的mysql服务
[root@oratest52 ~]# systemctl start mysql
(2)启动mgr,并确认mgr状态正常
mysql> start group_replication; query ok, 0 rows affected (2.92 sec) mysql> select * from performance_schema.replication_group_members; +---------------------------+--------------------------------------+-------------+-------------+--------------+ | channel_name | member_id | member_host | member_port | member_state | +---------------------------+--------------------------------------+-------------+-------------+--------------+ | group_replication_applier | 48cdca42-a386-11e9-95f1-0050569d2587 | test61 | 3306 | online | | group_replication_applier | 50bc1160-a386-11e9-92c9-0050569dc0da | oratest52 | 3306 | online | | group_replication_applier | e9ee5267-a386-11e9-ac35-0050569d9ef5 | oratest51 | 3306 | online | +---------------------------+--------------------------------------+-------------+-------------+--------------+
(3) 检查innodb cluster是否正常
mysql 172.16.9.51:3306 js > cluster.status() { "clustername": "st", "defaultreplicaset": { "name": "default", "primary": "oratest51:3306", "ssl": "disabled", "status": "ok", "statustext": "cluster is online and can tolerate up to one failure.", "topology": { "oratest51:3306": { "address": "oratest61:3306", "mode": "r/o", "readreplicas": {}, "role": "ha", "status": "online" }, "oratest52:3306": { "address": "oratest52:3306", "mode": "r/o", "readreplicas": {}, "role": "ha", "status": "online" }, "test61:3306": { "address": "test51:3306", "mode": "r/w", "readreplicas": {}, "role": "ha", "status": "online" } }, "topologymode": "single-primary" }, "groupinformationsourcemember": "test61:3306" }
(4) 查看恢复正常的实例,能不能自动加入mysql router进行转发,可以看到oratest52可以被正常调度
[root@node4 mysqlrouter]# for ((i=0;i<=5;i++));do mysql -h172.16.8.101 -uroot -p123456 -p6447 -e"select @@hostname;";done; mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest52 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest52 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest52 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+
测试结果: 恢复正常的mysql实例可以自动加入mysql router并进行转发,无需人工干预。
4.2.3模拟停掉primary节点,测试mysql router如何处理发送rw端口的请求,mysql router怎样获取新的primary节点
(1) 当前primary节点是oratest51,在primary节点上停止mysql,确认停止成功
[root@oratest51 data]# systemctl status mysql [root@oratest51 data]# systemctl stop mysql [root@oratest51 data]# systemctl status mysql [root@oratest51 data]# ps -ef |grep mysql
(2) 查看innodb cluster状态,可以看到oratest51已经处于missing状态,primary节点已经切换到了test61
mysql 172.16.9.61:3306 js > cluster.status(); { "clustername": "st", "defaultreplicaset": { "name": "default", "primary": "test61:3306", "ssl": "disabled", "status": "ok_no_tolerance", "statustext": "cluster is not tolerant to any failures. 1 member is not active", "topology": { "oratest51:3306": { "address": "oratest51:3306", "mode": "n/a", "readreplicas": {}, "role": "ha", "shellconnecterror": "mysql error 2003 (hy000): can't connect to mysql server on 'oratest51' (111)", "status": "(missing)" }, "oratest52:3306": { "address": "oratest52:3306", "mode": "r/o", "readreplicas": {}, "role": "ha", "status": "online" }, "test61:3306": { "address": "test61:3306", "mode": "r/w", "readreplicas": {}, "role": "ha", "status": "online" } }, "topologymode": "single-primary" }, "groupinformationsourcemember": "test61:3306" }
(3) 测试连接到rw 6446端口,查看是否可以正常连接到新的primary节点test61,并且写入数据否正常
[root@node2 mysqlrouter]# for ((i=0;i<=5;i++));do mysql -h172.16.8.101 -uroot -p123456 -p6446 -e"select @@hostname;";done; mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+
测试结果: 当primary节点挂掉之后,mysql router会自动去连接新的primary节点
4.2.4启动上一步中停掉的oratest51,将状态恢复正常,测试mysql router能不能自动加入这台已恢复的节点并调度
(1) 启动oratest51,将状态恢复正常
[root@oratest51 ~]# systemctl start mysql [root@oratest51 ~]# systemctl status mysql [root@oratest51 ~]# mysql -uroot -p123456 mysql> start group_replication; mysql> select * from performance_schema.replication_group_members; +---------------------------+--------------------------------------+------------+-------------+--------------+ | channel_name | member_id |member_host | member_port | member_state | +---------------------------+--------------------------------------+------------+-------------+--------------+ | group_replication_applier | 48cdca42-a386-11e9-95f1-0050569d2587 |test61 | 3306 | online | | group_replication_applier | 50bc1160-a386-11e9-92c9-0050569dc0da |oratest52 | 3306 | online | | group_replication_applier | e9ee5267-a386-11e9-ac35-0050569d9ef5 |oratest51 | 3306 | online | +---------------------------+--------------------------------------+------------+-------------+--------------+ 3 rows in set (0.00 sec) mysql> quit [root@oratest51 local]# mysqlsh mysql js > shell.connect('root@172.16.9.51:3306') mysql 172.16.9.51:3306 js > var cluster = dba.getcluster() mysql 172.16.9.51:3306 js > cluster.status(); { "clustername": "st", "defaultreplicaset": { "name": "default", "primary": "test61:3306", "ssl": "disabled", "status": "ok", "statustext": "cluster is online and can tolerate up to one failure.", "topology": { "oratest51:3306": { "address": "oratest51:3306", "mode": "r/o", "readreplicas": {}, "role": "ha", "status": "online" }, "oratest52:3306": { "address": "oratest52:3306", "mode": "r/o", "readreplicas": {}, "role": "ha", "status": "online" }, "test61:3306": { "address": "test61:3306", "mode": "r/w", "readreplicas": {}, "role": "ha", "status": "online" } }, "topologymode": "single-primary" }, "groupinformationsourcemember": "test61:3306" }
(2) 测试ro端口的router调度
[root@node4 mysqlrouter]# for ((i=0;i<=5;i++));do mysql -h172.16.8.101 -uroot -p123456 -p6447 -e"select @@hostname;";done; mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest52 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest51 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest52 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest51 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | oratest52 | +------------+ mysql: [warning] using a password on the command line interface can be insecure. +------------+ | @@hostname | +------------+ | test61 | +------------+
测试结果: 恢复正常的实例加入集群后,会自动加入到mysql router并进行调度
五、运维相关
5.1数据库节点变更
mysql router在初始化配置的时候是连接到集群节点读取集群的元数据的。如果在集群中新增或减少节点,需要同步更新mysql router的配置,否则无法生效
# mysqlrouter --bootstrap 172.16.9.51:3306 --directory /data/mysqlrouter --user=root --conf-use-sockets --force
更新了mysql router的配置的配置,需要重启mysql router:
#systemctl restart mysqlrouter #systemctl status mysqlrouter
六、问题汇总
6.1初始化mysql router前,需要停止group_replication
6.2使用--bootstrap初始化mysql router报错unable to connect to the metadata server
报错如下
[root@oratest51 data]# mysqlrouter --bootstrap root@172.16.9.51:3310 --directory /data/mysqlrouter --conf-use-sockets --user=root please enter mysql password for root: error: unable to connect to the metadata server: error connecting to mysql server at 172.16.9.51:3310: can't connect to mysql server on '172.16.9.51' (111) (2003)
原因: 需要配置连接用户的权限
解决办法: 给连接用户配置所有权限,如下:
mysql> grant all privileges on *.* to root@'%' identified by "123456"; mysql> flush privileges;
6.3使用--bootstrap初始化mysql router报错缺少mysql_innodb_cluster_metadata.schema_version表
[root@oratest51 data]# mysqlrouter --bootstrap root@172.16.9.51:3306 --directory /data/mysqlrouter --conf-use-sockets --user=root please enter mysql password for root: error: expected mysql server '172.16.9.51:3306' to contain the metadata of mysql innodb cluster, but the schema does not exist. checking version of the metadata schema failed with: error executing mysql query: table 'mysql_innodb_cluster_metadata.schema_version' doesn't exist (1146) see https://dev.mysql.com/doc/refman/en/mysql-innodb-cluster-creating.html for instructions on setting up a mysql server to act as an innodb cluster metadata server
原因: 没有创建innodb cluster集群,创建innodb cluster集群后会自动生成这张表。mysql_innodb_cluster_metadata.schema_version表的用途是mysql router在进行调度分配的时候,需要读取这张表的内容来做调度策略。
解决办法: 创建innodb cluster集群
6.4启动mysql router hang住不动,查看日志报错error: bootstrap_server_addresses is not allowed when dynamic state file is used
具体如下:
[root@node2 log]# tailf /root/mysqlrouter/log/mysqlrouter.log 2019-08-02 15:37:52 routing info [7f9721e2d700] [routing:st_default_ro] started: listening using /root/mysqlrouter/mysqlro.sock 2019-08-02 15:37:52 routing info [7f972162c700] [routing:st_default_rw] started: listening using /root/mysqlrouter/mysql.sock 2019-08-02 15:37:52 routing info [7f9720e2b700] [routing:st_default_x_ro] started: listening using /root/mysqlrouter/mysqlxro.sock 2019-08-02 15:37:52 routing info [7f9713fff700] [routing:st_default_x_rw] started: listening on 0.0.0.0:64460, routing strategy = first-available 2019-08-02 15:37:52 routing info [7f9713fff700] [routing:st_default_x_rw] started: listening using /root/mysqlrouter/mysqlx.sock 2019-08-02 15:37:52 routing info [7f9713fff700] [routing:st_default_x_rw] stopped 2019-08-02 15:37:52 routing info [7f9721e2d700] [routing:st_default_ro] stopped 2019-08-02 15:37:52 routing info [7f972162c700] [routing:st_default_rw] stopped 2019-08-02 15:37:52 routing info [7f9720e2b700] [routing:st_default_x_ro] stopped 2019-08-02 15:37:52 main error [7f9726f1b880] error: bootstrap_server_addresses is not allowed when dynamic state file is used
原因: 开启了dynamic_state
解决办法: 在配置文件中注释掉dynamic_state所在行,例如下列第11行
1 # file automatically generated during mysql router bootstrap 2 [default] 3 user=root 4 logging_folder=/root/mysqlrouter/log 5 runtime_folder=/root/mysqlrouter/run 6 data_folder=/root/mysqlrouter/data 7 keyring_path=/root/mysqlrouter/data/keyring 8 master_key_path=/root/mysqlrouter/mysqlrouter.key 9 connect_timeout=15 10 read_timeout=30 11 #dynamic_state=/root/mysqlrouter/data/state.json
6.5启动mysql router hang住不动,查看日志报错unable to fetch live group_replication member data from any server in replicaset 'default'
具体如下:
[root@node2 log]# tailf /root/mysqlrouter/log/mysqlrouter.log 2019-08-02 15:46:41 metadata_cache warning [7f3030405700] while updating metadata, could not establish a connection to replicaset 'default' through test61:3306 2019-08-02 15:46:51 metadata_cache warning [7f3030405700] while updating metadata, could not establish a connection to replicaset 'default' through oratest52:3306 2019-08-02 15:47:01 metadata_cache warning [7f3030405700] while updating metadata, could not establish a connection to replicaset 'default' through oratest51:3306 2019-08-02 15:47:01 metadata_cache error [7f3030405700] unable to fetch live group_replication member data from any server in replicaset 'default'
原因: mysql router所在节点没有配置本机dns解析
解决办法: 在/etc/hosts中添加mgr实例的解析
七、个人总结
- mysql router有两种部署模式:
- bootstrap模式:支持failover,必须结合innodb cluster使用,在--directory指定的路径下自动生成安装目录,配置文件里的端口为6446和6447。
- 简单模式:不支持failover,无需结合innodb cluster使用,一般在主从复制或者主主复制等模式下使用,使用/usr/local/mysqlrouter/share/doc/mysqlrouter/sample_mysqlrouter.conf这个配置文件部署。
- mysql router使用的是一个ip地址(可以理解为vip)加一个rw端口和一个ro端口实现读写分离,router自身不能判断应用程序的请求是读还是写,因此做读写分离时,必须指定两个端口,如果应用程序不便指定两个端口,也可以全部指定rw端口,这样的话从节点就只作高可用,不做读写分离。
- mysql router自身存在单点故障隐患,官方推荐在每个应用程序所在机器上部署router,本机器连接本机器的router。也可以在router的上层在搭建一个高可用服务,如果是自建机房可以选择keepalived、pacemaker等方案;
- 通过bootstrap生成的配置文件,只需要在bootstrap_server_addresses这一栏里配置就可以了,格式如下:
bootstrap_server_addresses=mysql://oratest51:3306,mysql://oratest52:3306,mysql://test61:3306
登录后复制 - mysql router的后端mysql实例挂掉之后,无需人工干预,mysql router会自动剔除挂了的mysql实例,当挂了的mysql实例恢复后会自动加入mysql router的后端服务器,也无需人工干预。
- mgr架构可以实现高可用,但是要实现failover,则需要安装innodb cluster了。mysql shell和mysql router是innodb cluster集群的一部分
- mysql router非常轻量级,性能损耗小于1%,官方建议每台应用上部署一个mysqlrouter节点,优点是节省网络带宽。缺点是mysqlrouter太轻量级了,只能提供简单的基于端口的读写路由(port based routing)和基于权重轮询的负载均衡(weighted balance),不支持基于sql的读写分离(query based routing)和空闲优先的负载均衡(application layer balancer)
【相关推荐:mysql视频教程】
以上就是mysql router是什么的详细内容,更多请关注代码网其它相关文章!
发表评论