本节介绍如何将MySQL路由器与InnoDB群集一起使用以实现高可用性。无论您是否部署了沙箱集群或生产集群,MySQL路由器都可以使用该--bootstrap选项基于InnoDB集群的元数据进行自我配置 。这将自动配置MySQL路由器,以将连接路由到群集的服务器实例。客户端应用程序连接到MySQL路由器提供的端口,而无需了解InnoDB集群拓扑。万一发生意外故障,InnoDB集群会自动进行自我调整,并且MySQL Router会检测到更改。这消除了客户端应用程序处理故障转移的需要。
注意
不要尝试手动配置MySQL路由器以重定向到InnoDB集群的端口。始终使用该 --bootstrap选项,因为这可确保MySQL Router从InnoDB集群的元数据中获取其配置。请参阅 群集元数据和状态。
建议的MySQL Router部署与应用程序位于同一主机上。使用沙箱部署时,所有内容都在单个主机上运行,因此,您将MySQL Router部署到同一主机上。使用生产部署时,建议将一个MySQL路由器实例部署到用于承载一个客户端应用程序的每台计算机上。也可以将MySQL路由器部署到应用程序实例通过其连接的通用计算机上。
假设已经安装了MySQL Router(请参阅“ 安装MySQL Router”),请使用该 --bootstrap选项提供属于InnoDB集群的服务器实例的位置。MySQL路由器使用附带的元数据缓存插件来检索InnoDB集群的元数据,该元数据由构成InnoDB集群及其在集群中的角色的服务器实例地址列表组成。您传递MySQL路由器应从中检索InnoDB群集元数据的服务器的类似URI的连接字符串。例如:
shell> mysqlrouter --bootstrap icadmin@ic-1:3306 --user=mysqlrouter
系统会提示您输入要用于MySQL路由器的实例密码和加密密钥。该加密密钥用于加密MySQL路由器用于连接集群的实例密码。还会显示可用于连接到InnoDB集群的端口。在上述示例中,MySQL Router引导过程创建了一个 mysqlrouter.conf文件,其设置基于从从传递给该--bootstrap选项的地址中检索到的集群元数据icadmin@ic-1:3306。基于检索到的InnoDB集群元数据,MySQL Router自动配置mysqlrouter.conf文件,包括一个metadata_cache部分。如果您使用的是MySQL Router 8.0.14及更高版本,则 --bootstrap选项自动配置MySQL路由器来跟踪和存储活动的MySQL InnoDB集群元数据服务器地址,该地址由dynamic_state。这样可以确保在重启MySQL路由器时,它知道哪个MySQL InnoDB集群元数据服务器地址是最新的。有关更多信息,请参见 dynamic_state文档。
在早期的MySQL Router版本中,元数据服务器信息是在Router的初始引导操作期间定义的,并像bootstrap_server_addresses配置文件中一样静态存储 ,该文件包含集群中所有服务器实例的地址。例如:
[metadata_cache:prodCluster]
router_id=1
bootstrap_server_addresses=mysql://icadmin@ic-1:3306,mysql://icadmin@ic-2:3306,mysql://icadmin@ic-3:3306
user=mysql_router1_jy95yozko3k2
metadata_cluster=prodCluster
ttl=300
提示
如果使用MySQL Router 8.0.13或更早版本,则在引导MySQL Router后通过添加另一个服务器实例来更改群集的拓扑时,需要 bootstrap_server_addresses 根据更新的元数据进行更新。使用该--bootstrap选项重新启动MySQL Router ,或手动编辑 文件bootstrap_server_addresses 部分mysqlrouter.conf并重新启动MySQL Router。
生成的MySQL路由器配置将创建用于连接到群集的TCP端口。默认情况下,将创建用于使用经典MySQL协议和X协议与集群通信的端口。要使用X协议,服务器实例必须安装并配置了X插件,这是MySQL 8.0及更高版本的默认设置。默认的可用TCP端口为:
6446 -对于经典的MySQL协议读写会话,MySQL路由器将传入的连接重定向到主服务器实例。
6447 -对于经典的MySQL协议只读会话,MySQL路由器将传入的连接重定向到辅助服务器实例之一。
64460 -对于X协议读写会话,MySQL路由器将传入的连接重定向到主服务器实例。
64470 -对于X协议只读会话,MySQL路由器将传入的连接重定向到辅助服务器实例之一。
根据您的MySQL路由器配置,端口号可能与上述端口号不同。例如,如果您使用 --conf-base-port选项或 group_replication_single_primary_mode 变量。启动MySQL Router时,将列出确切的端口。
传入连接的重定向方式取决于所使用群集的类型。当使用单一主群集时,默认情况下,MySQL路由器发布一个X协议和一个经典的MySQL协议端口,客户端连接到该端口以进行读写会话,并将客户端重定向到群集的单一主端口。对于多主群集,读写会话以循环方式重定向到主实例之一。例如,这意味着到端口6446的第一个连接将重定向到ic-1实例,到端口6446的第二个连接将重定向到ic-2实例,依此类推。对于传入的只读连接,MySQL路由器也以循环方式将连接重定向到辅助实例之一。routing_strategy 选项。
自举并配置后,启动MySQL Router。如果您在系统范围内使用该--bootstrap选项进行安装,请 发出:
shell>mysqlrouter &
如果使用--directory选项将MySQL Router安装到目录中 ,请使用start.sh安装目录中的 脚本。或者,设置服务以在系统启动时自动启动MySQL路由器,请参阅 启动MySQL路由器。您现在可以如上所述将MySQL客户端(例如MySQL Shell)连接到传入的MySQL路由器端口之一,并查看客户端如何透明地连接到InnoDB集群实例之一。
shell>mysqlsh --uri root@localhost:6442
要验证您实际连接到的实例,只需针对port状态变量发出SQL查询 。
mysql-js> \sql
Switching to SQL mode... Commands end with ;
mysql-sql> select @@port;
+--------+
| @@port |
+--------+
| 3310 |
+--------+
测试高可用性
要测试高可用性是否有效,请通过杀死实例来模拟意外的停止。群集检测到实例已离开群集并重新配置自身的事实。集群本身如何真正进行重新配置取决于您使用的是单主集群还是多主集群,以及实例在集群中扮演的角色。
在单主要模式下:
如果当前主节点离开集群,则将辅助实例之一选作新的主实例,实例的优先级最低 server_uuid。MySQL Router将读写连接重定向到新选出的主数据库。
如果当前辅助节点离开群集,则MySQL路由器将停止将只读连接重定向到该实例。
有关更多信息,请参见 第18.1.3.1节“单主模式”。
在多主要模式下:
如果当前的“ R / W”实例离开群集,则MySQL路由器会将读写连接重定向到其他主数据库。如果剩下的实例是群集中的最后一个主实例,则群集已完全消失,您将无法连接到任何MySQL路由器端口。
有关更多信息,请参见 第18.1.3.2节“多主模式”。
有多种方法可以模拟离开群集的实例,例如,您可以在实例上强制停止MySQL服务器,或者在dba.killSandboxInstance()测试沙箱部署时使用AdminAPI 。在此示例中,假设有一个具有三个服务器实例的单主要沙箱群集部署,并且侦听端口3310的实例是当前主要实例。模拟实例意外离开集群:
mysql-js> dba.killSandboxInstance(3310)
群集检测到更改并自动选择一个新的主数据库。假设您的会话连接到默认的经典经典MySQL协议端口6446,MySQL路由器应检测到群集拓扑的更改,并将会话重定向到新选择的主服务器。要验证这一点,请使用以下\sql 命令在MySQL Shell中切换到SQL模式,然后选择实例的 port变量以检查您的会话已重定向到哪个实例。注意第一个SELECT语句失败,因为与原始主数据库的连接已丢失。这意味着当前会话已经关闭,MySQL Shell为您自动重新连接,并且当您再次发出命令时,将确认新端口。
mysql-js> \sql
Switching to SQL mode... Commands end with ;
mysql-sql> SELECT @@port;
ERROR: 2013 (HY000): Lost connection to MySQL server during query
The global session got disconnected.
Attempting to reconnect to 'root@localhost:6446'...
The global session was successfully reconnected.
mysql-sql> SELECT @@port;
+--------+
| @@port |
+--------+
| 3330 |
+--------+
1 row in set (0.00 sec)
在此示例中,端口3330的实例已被选为新的主实例。这表明InnoDB集群为我们提供了自动故障转移,MySQL Router已自动将我们重新连接到新的主实例,并且我们具有高可用性。
MySQL路由器和元数据服务器
当MySQL路由器针对群集进行引导时,它将服务器实例的地址记录在其配置文件中。如果在引导MySQL路由器后将任何其他实例添加到群集,它们将不会自动检测到,因此不会用于连接路由。
为确保新添加的实例正确路由,您必须针对群集引导MySQL路由器以读取更新的元数据。这意味着您必须重新启动MySQL Router并包括该--bootstrap选项。
使用群集的路由器
您可以针对群集或副本集引导MySQL路由器的多个实例。从8.0.19版本开始,要显示所有已注册的MySQL路由器实例的列表,请发出:
Cluster.listRouters()
结果提供有关每个已注册的MySQL路由器实例的信息,例如元数据中的名称,主机名,端口等。例如,发出:
mysql-js> Cluster.listRouters()
{
"clusterName": "example",
"routers": {
"ic-1:3306": {
"hostname": "ic-1:3306",
"lastCheckIn": "2020-01-16 11:43:45",
"roPort": 6447,
"roXPort": 64470,
"rwPort": 6446,
"rwXPort": 64460,
"version": "8.0.19"
}
}
}
返回的信息显示:
MySQL路由器实例的名称。
上次签入时间戳,它是由存储在元数据中的MySQL路由器定期ping生成的
运行MySQL路由器实例的主机名
MySQL路由器为经典MySQL协议连接发布的只读和读写端口
MySQL路由器为X协议连接发布的只读和读写端口
此MySQL路由器实例的版本。version8.0.19中增加了对返回的支持 。如果针对早期版本的MySQL Router运行此操作,则版本字段为null。
另外,该 Cluster.listRouters() 操作可以显示不支持MySQL Shell支持的元数据版本的实例列表。使用该 onlyUpgradeRequired选项,例如通过发出 Cluster.listRouters({'onlyUpgradeRequired':'true'})。返回的列表仅显示已向MySQL路由器实例注册的实例,Cluster这些实例需要升级其元数据。请参见 第21.3.2节“升级InnoDB集群元数据”。
MySQL Router实例不会自动从元数据中删除,因此,例如,当您引导更多实例时,InnoDB群集元数据包含的实例引用数量正在不断增加。要从群集的元数据中删除已注册的MySQL路由器实例,请使用 版本8.0.19中添加的 操作。使用该 操作获取要删除的MySQL路由器实例的名称,并将其作为传递。例如,假设您在集群中注册的MySQL路由器实例为: Cluster.removeRouterMetadata(router)Cluster.listRouters()router
mysql-js> Cluster.listRouters(){
"clusterName": "testCluster",
"routers": {
"myRouter1": {
"hostname": "example1.com",
"lastCheckIn": null,
"routerId": "1",
"roPort": "6447",
"rwPort": "6446"
"version": null
},
"myRouter2": {
"hostname": "example2.com",
"lastCheckIn": "2019-11-27 16:25:00",
"routerId": "3",
"roPort": "6447",
"rwPort": "6446"
"version": "8.0.19"
}
}
}
基于这样的事实,命名实例 “ myRouter1 ”有null对 “ lastCheckIn ”和“ 版本 ”,我们决定通过发出删除从元数据这个旧的实例:
mysql-js>cluster.removeRouterMetadata('myRouter1')
通过从InnoDB集群元数据中删除指定的MySQL路由器实例,可以从集群中注销该实例。
配置MySQL路由器用户
当MySQL路由器连接到InnoDB集群或InnoDB ReplicaSet时,它需要一个具有正确特权的用户帐户。从MySQL路由器8.0.19版开始,可以使用--account选项指定此内部用户 。在以前的版本中,MySQL Router在群集的每个引导程序上创建内部帐户,这可能导致随着时间的推移建立许多帐户。从MySQL Shell 8.0.20版本开始,您可以使用AdminAPI设置MySQL路由器所需的用户帐户。使用setupRouterAccount(user, [options])创建MySQL用户帐户或升级现有帐户的操作,以便MySQL Router可以使用该帐户在InnoDB群集或InnoDB ReplicaSet上进行操作。这是使用InnoDB集群和InnoDB ReplicaSet配置MySQL路由器的推荐方法。
要将新的MySQL路由器帐户添加 myRouter1到变量引用的InnoDB集群中 testCluster,请发出:
mysqlsh>testCluster.setupRouterAccount(myRouter1)
在这种情况下,未指定任何域,因此将使用通配符(%)字符创建帐户,以确保创建的用户可以从任何域进行连接。要将帐户限制为只能从example.com域连接 ,请发出:
mysqlsh> testCluster.setupRouterAccount([email protected])
该操作提示输入密码,然后使用正确的权限设置MySQL路由器用户。如果InnoDB集群或InnoDB ReplicaSet具有多个实例,则创建的MySQL Router用户将传播到所有实例。设置用户后,可以使用该--account 选项来引导MySQL路由器。例如,假设您创建了一个adminAccount使用该 setupAdminAccount()操作命名的集群管理员。要使用myRouter1操作创建的用户引导MySQL路由器setupRouterAccount() ,请发出:
mysqlrouter --bootstrap adminAccount@ic-1:3306 --account=myRouter1
如果已经配置了MySQL路由器用户,例如,如果您使用的是8.0.20之前的版本,则可以使用该 setupRouterAccount()操作来重新配置现有用户。在这种情况下,将update设置为true 的选项传递 。例如,要重新配置myOldRouter用户,请发出:
mysqlsh> testCluster.setupRouterAccount(myOldRouter, {'update':1})