mysql external table_MySQL 5.7: 使用MySQL Router实现应用程序的高可用

本文介绍了如何使用MySQL Router为应用程序提供高可用性,避免主节点崩溃时的连接问题。MySQL Router作为单一连接点,提供负载均衡、读写分离和故障转移。安装配置MySQL Router涉及下载、启动脚本生成、监听端口查看,并通过MySQL Shell进行连接测试。
摘要由CSDN通过智能技术生成

MySQL Router

前面一片文章说了如何配置MySQL的分组复制. 基于分组复制的机制, 当主节点崩溃离开集群, 剩余的其他节点会相互协商, 然后选举一个新的主节点. 这里有一个问题, 就是应用程序端如果连接到了主节点, 这时主节点崩溃离开集群. 可用的数据库IP地址发生变化. 客户端应用程序这个时候还是会向失败的节点尝试连接, 虽然可以修改客户端应用程序的连接配置, 但是这种情况基本是不现实的.

虽然我们可以通过下面的SQL语句获取主节点的IP地址

SELECT * FROM performance_schema.replication_group_members

WHERE MEMBER_ID = (

SELECT VARIABLE_VALUE

FROM performance_schema.global_status

WHERE VARIABLE_NAME= 'group_replication_primary_member'

);

但是通过应用程序动态的获取可用数据库的IP地址. 这种方式感觉不怎么好. 很麻烦, 要写多余的代码.

配置MySQL Router首先需要MySQL Shell 工具, 在 MySQL Shell 部分有详细的说明

概述

下面是MySQL Router 和集群的基本关系图

f0682b730dc08961f347da88e87c76a5.png

上图充分说明了, MySQL Router 在InnoDB集群里面的角色. 主要作用是为数据库集群提供一个虚拟IP. 作为应用程序单一连接点. 通过这个单一的连接点实现负载均衡, 读写分离, 故障转移等数据库高可用方案.

推荐安装在应用程序所在的机器上, 原因包括:

通过Unix套接字连接, 而不是TCP/IP, 提升性能

降低网络延迟

MySQL实例不需要额外的账号, 只需要一个 router@198.51.100.45, 而不是 myapp@%

提升应用程序服务器的弹性

安装和配置 MySQL Router

wget https://dev.mysql.com/get/mysql-apt-config_0.8.9-1_all.deb

dpkg -i mysql-apt-config_0.8.9-1_all.deb

aptitude update

aptitude install -y mysql-router

生成配置和启动脚本

mysqlrouter --bootstrap 172.18.149.213:3306 --directory /data/mysqlrouter --user=root --conf-use-sockets --force

Please enter MySQL password for root:

Bootstrapping MySQL Router instance at /data/mysqlrouter...

MySQL Router has now been configured for the InnoDB cluster 'dc'.

The following connection information can be used to connect to the cluster.

Classic MySQL protocol connections to cluster 'dc':

- Read/Write Connections: localhost:6446

- Read/Write Connections: /data/mysqlrouter/mysql.sock

- Read/Only Connections: localhost:6447

- Read/Only Connections: /data/mysqlrouter/mysqlro.sock

X protocol connections to cluster 'dc':

- Read/Write Connections: localhost:64460

- Read/Write Connections: /data/mysqlrouter/mysqlx.sock

- Read/Only Connections: localhost:64470

- Read/Only Connections: /data/mysqlrouter/mysqlxro.sock

输入密码后, 文件就生成到 /data/mysqlrouter 目录了.

--conf-use-sockets 选项还会监听Unix套接字

关于 MySQL Router 命令行的所有参数说明, 参考这里: https://dev.mysql.com/doc/mys...

启动MySQL Router

cd /data/mysqlrouter

./start.sh

PID 3976 written to /data/mysqlrouter/mysqlrouter.pid

查看MySQL Router的监听端口

下面列出了MySQL Router 监听的TCP端口

netstat -anpt |grep router

tcp 0 0 0.0.0.0:64460 0.0.0.0:* LISTEN 3976/mysqlrouter

tcp 0 0 0.0.0.0:6446 0.0.0.0:* LISTEN 3976/mysqlrouter

tcp 0 0 0.0.0.0:6447 0.0.0.0:* LISTEN 3976/mysqlrouter

tcp 0 0 0.0.0.0:64470 0.0.0.0:* LISTEN 3976/mysqlrouter

tcp 0 0 172.18.149.215:44350 172.18.149.213:3306 ESTABLISHED 3976/mysqlrouter

各个端口的含义我们在之前创建MySQL Router配置时的输出已经说明了, 另外配置文件中也详细说明了每个端口的含义:

cat /data/mysqlrouter/mysqlrouter.conf

# 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

[logger]

level = DEBUG

[metadata_cache:dc]

router_id=1

bootstrap_server_addresses=mysql://172.18.149.213:3306,mysql://172.18.149.215:3306,mysql://172.18.149.214:3306

user=mysql_router1_4d98tioywyow

metadata_cluster=dc

ttl=300

[routing:dc_default_rw]

bind_address=0.0.0.0

bind_port=6446

socket=/data/mysqlrouter/mysql.sock

destinations=metadata-cache://dc/default?role=PRIMARY

mode=read-write

protocol=classic

[routing:dc_default_ro]

bind_address=0.0.0.0

bind_port=6447

socket=/data/mysqlrouter/mysqlro.sock

destinations=metadata-cache://dc/default?role=SECONDARY

mode=read-only

protocol=classic

[routing:dc_default_x_rw]

bind_address=0.0.0.0

bind_port=64460

socket=/data/mysqlrouter/mysqlx.sock

destinations=metadata-cache://dc/default?role=PRIMARY

mode=read-write

protocol=x

[routing:dc_default_x_ro]

bind_address=0.0.0.0

bind_port=64470

socket=/data/mysqlrouter/mysqlxro.sock

destinations=metadata-cache://dc/default?role=SECONDARY

mode=read-only

protocol=x

下面列举除了MySQL Router监听的Unix套接字(如果使用了--conf-use-sockets选项)

netstat -anpx |grep router

unix 2 [ ACC ] STREAM LISTENING 41668 3791/mysqlrouter /tmp/myrouter/mysql.sock

unix 2 [ ACC ] STREAM LISTENING 42187 3791/mysqlrouter /tmp/myrouter/mysqlro.sock

unix 2 [ ACC ] STREAM LISTENING 43361 3791/mysqlrouter /tmp/myrouter/mysqlx.sock

unix 2 [ ACC ] STREAM LISTENING 42189 3791/mysqlrouter /tmp/myrouter/mysqlxro.sock

我们看到有4个Unix套接字

Unix 套接字

说明

读写模式

mysql.sock

MySQL协议

读写

mysqlro.sock

MySQL协议

只读

mysqlx.sock

X 协议

读写

mysqlxro.sock

X 协议

只读

注意: 该表只是说明了每个Unix套接字承担的角色, 没有限制你连接到只读模式的端口执行写操作.

连接到 MySQL Router 执行SQL

mysql -u root -h 172.18.149.215 -P 6446 -p

# 创建数据库

mysql> create database b;

Query OK, 1 row affected (0.00 sec)

# 切换

mysql> use b;

Database changed

# 创建表

mysql> create table a (c int);

Query OK, 0 rows affected (0.00 sec)

# 插入值

# 出错了, 因为没有主键

mysql> insert into a values(1);

ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin.

# 添加主键列

mysql> alter table a add column a_id int(4);

Query OK, 0 rows affected (0.00 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> alter table a add primary key pk (a_id);

Query OK, 0 rows affected (0.00 sec)

Records: 0 Duplicates: 0 Warnings: 0

# 插入值

mysql> insert into a values (1,2);

Query OK, 1 row affected (0.01 sec)

OK, MySQL Router到这里就配置好了, 在应用程序代码里面直接连接到MySQL Router的IP地址可以了.

关于数据节点变更

MySQL Router 在初始化配置的时候是连接到集群节点读取集群的元数据的. 如果在集群中新增或减少节点. 需要同步更新MySQL Router的配置, 重新执行以下命令即可:

mysqlrouter --bootstrap 172.18.149.213:3306 --directory /data/mysqlrouter --user=root --conf-use-sockets --force

当然, 更新了MySQL Router的配置的配置, 需要重启MySQL Router:

cd /data/mysqlrouter

./stop.sh

./start.sh

关于 MySQL Router 的部署问题

MySQL Router 目前只支持500并发连接(https://dev.mysql.com/doc/mys... 官方建议把 MySQL Router 部署到和应用程序相同的一台机器上. 通过MySQL Router 的 --conf-use-sockets 启动选项, 我们可以把MySQL Router作为一个本地代理来使用.

为了解决MySQL Router的单点问题. 我们可以在MySQL Router的上层在搭建一个负载均衡服务器. 我现在的环境全部是基于阿里云的, 因此很自然的选择了阿里云的SLB作为负载均衡解决方案. 如果自建服务器可以选择LVS, HAProxy等方案.

在MySQL Router之上再做负载均衡. 管理上更复杂了, 这里还是采用一个应用程序部署一个本地MySQL Router的策略.

MySQL Shell

交互式代码执行

支持的语言: Javascript, Python, SQL

批处理

输出格式: 制表符, 表格, JSON

多行支持

日志

MySQL协议支持, X Protocol支持

安装

wget https://dev.mysql.com/get/mysql-apt-config_0.8.9-1_all.deb

dpkg -i mysql-apt-config_0.8.9-1_all.deb

aptitude update

aptitude install -y mysql-shell

连接方式: 通过URL的方式

mysqlsh --uri ${uri}

URI 支持系列各种形式

mysqlx://user@localhost:33065

mysql://user@localhost:3333

mysqlx://user@server.example.com/

mysqlx://user@198.51.100.14:123

mysqlx://user@[2001:db8:85a3:8d3:1319:8a2e:370:7348]

mysqlx://user@198.51.100.1/world%5Fx

mysqlx://user@198.51.100.2:33060/world

连接方式: 通过参数方式

--dbuser (-u) value

--dbpassword value

--host (-h) value

--port (-P) value

--schema (-D) value

--password (-p)

--socket (-S)

参数别名

--user is equivalent to --dbuser

--password is equivalent to --dbpassword

--database is equivalent to --schema

覆盖问题

参数的优先级比URL高, 下面的例子通过 otheruser 用户进行连接而不是URL中指定的 user

mysqlsh --uri user@localhost:33065 --user otheruser

# MySQL协议

mysqlsh --mysql -u user -h localhost

# X协议

mysqlsh --mysqlx -u user -h localhost -P 33065

通过Javascript连接

# X协议

var session=mysqlx.getSession('root@localhost:33060', 'password');

# MySQL协议

var session = mysql.getClassicSession('root@localhost:3306', 'password');

在代码中使用加密连接

var session=mysqlx.getSession({host: 'localhost',

dbUser: 'root',

dbPassword: 'password',

ssl_ca: "path_to_ca_file",

ssl_cert: "path_to_cert_file",

ssl_key: "path_to_key_file"

});

安装X插件的几种方式

如果从支持X Protocol的客户端连接到数据库, 在数据库端需要安装X Plugin以提供对 X Protocol的支持, 安装X Plugin只需要对 mysql.plugin 表有 INSERT 权限即可.

1.通过 mysqlsh 安装

# 安装需要的仓库, 选中 MySQL Tools & Connectors (Currently selected: Enabled)

wget https://dev.mysql.com/get/mysql-apt-config_0.8.9-1_all.deb

dpkg -i mysql-apt-config_0.8.9-1_all.deb

执行如下命令, 输入密码:

mysqlsh -u root -h localhost --classic --dba enableXProtocol

如果看到如下输出, 标识安装完成:

mysqlsh -u root -h 172.18.149.213 --classic --dba enableXProtocol

Creating a Classic Session to 'root@172.18.149.213'

Enter password:

Your MySQL connection id is 70

Server version: 5.7.20-log MySQL Community Server (GPL)

No default schema selected; type \use to set one.

enableXProtocol: Installing plugin mysqlx...

enableXProtocol: done

2.通过MySQL客户端

mysql -u user -p

mysql> INSTALL PLUGIN mysqlx SONAME 'mysqlx.so';

插件的加载需要 mysql.session 用户, mysql.session 用户在 MySQL 5.7.19 中已经添加. 早期的版本需要执行 mysql_upgrade, 否则加载X插件的时候回报错:

There was an error when trying to access the server with user: mysql.session@localhost. Make sure the user is present in the server and that mysql_upgrade was ran after a server update..

验证

mysqlsh -u root --sqlc -e "show plugins"

mysql -u root -p -e "show plugins"

mysql> select * from plugin;

+-------------------+----------------------+

| name | dl |

+-------------------+----------------------+

| group_replication | group_replication.so |

| mysqlx | mysqlx.so |

+-------------------+----------------------+

如果在输出中看到 mysqlx.so 标识X插件安装成功. X插件安装过程会自动创建一个用户: mysqlxsys@localhost

卸载X插件

UNINSTALL PLUGIN mysqlx;

删除插件的同时也会删除 mysqlxsys@localhost 用户.

参考资料

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值