MySQL Shell 9.0  /  MySQL InnoDB ClusterSet  /  将 MySQL Router 集成到 InnoDB ClusterSet

8.5 将 MySQL Router 集成到 InnoDB ClusterSet

MySQL Router 将客户端应用程序流量路由到 InnoDB ClusterSet 部署中的适当集群。您可以为与 InnoDB ClusterSet 部署一起使用的 MySQL Router 实例设置全局策略,并使用各个 MySQL Router 实例的设置覆盖此策略。

当您将 MySQL Router 实例引导到 InnoDB ClusterSet 部署时,它会了解 ClusterSet 的完整拓扑结构,并可以适当地管理写入和读取流量。如果发生受控切换或紧急故障转移,则与 InnoDB ClusterSet 连接的 MySQL Router 实例将了解这一点并将流量路由到新的主集群,除了您已配置为将流量发送到特定集群的任何实例。如果集群无效,MySQL Router 实例会停止对其进行读写流量,除了您已配置为在这种情况下继续发送读取流量的任何实例。

对于您正在与 InnoDB ClusterSet 一起使用的每个 MySQL Router 实例,您可以选择将其配置为遵循主集群,或者仅连接到特定的目标 InnoDB 集群。您可以使用 MySQL Shell 在线切换这些模式。

遵循主集群

在此模式下,MySQL Router 将应用程序流量(写入和读取)都定向到 InnoDB ClusterSet 部署中当前为主集群的集群。此模式为默认模式。

命名目标集群

在此模式下,MySQL Router 将应用程序流量定向到您指定的 InnoDB 集群。这可以是 InnoDB ClusterSet 部署中的主集群,也可以是副本集群。如果目标集群当前为主集群,MySQL Router 会打开写入端口,应用程序可以写入该实例。如果目标集群当前是只读副本集群,MySQL Router 只允许读取流量,并拒绝写入流量。如果由于切换或故障转移到或从目标集群导致这种情况发生变化,MySQL Router 会相应地更改允许的请求类型。如果应用程序仅执行读取请求(可以在副本集群上执行),并且您希望将该流量路由到本地集群,此模式很有用。

您还可以配置 MySQL Router 以允许或禁止对已标记为 INVALIDATED 的集群进行读取流量。处于此状态的集群当前无法作为 InnoDB ClusterSet 部署的一部分正常运行,并且无法接收写入。虽然集群不一定存在任何技术问题,但其数据正在变得过时。默认情况下,MySQL Router 不允许对无效集群进行读取和写入(drop_all 设置),但您可以选择允许读取(accept_ro 设置)。

要将 MySQL Router 引导到 InnoDB ClusterSet,您需要使用 InnoDB 集群管理员帐户,或 InnoDB 集群服务器配置帐户,该帐户也具有所需的权限。然后,MySQL Router 使用 MySQL Router 管理员帐户连接到 InnoDB ClusterSet 部署中的实例。您需要在引导操作期间指定这两个帐户的用户名和密码。有关更多信息,请参见 第 8.3 节,“InnoDB ClusterSet 用户帐户”

重要

如果您正在使用现有 InnoDB 集群作为您的 InnoDB ClusterSet 部署中的主集群,并且您之前已将 MySQL Router 引导到该集群,请按照此过程的相关部分再次使用 --force 选项将它引导到 InnoDB ClusterSet,然后停止并重新启动 MySQL Router。MySQL Router 实例的静态配置文件中的设置需要更新为 InnoDB ClusterSet。

要将 MySQL Router 集成到 InnoDB ClusterSet 部署,请按照以下步骤操作

  1. 如果您尚未这样做,请根据您的拓扑结构安装 MySQL Router 实例。推荐的 MySQL Router 部署是在与客户端应用程序相同的主机上。使用沙箱部署时,所有内容都在一台主机上运行,因此您将 MySQL Router 部署到同一主机。使用生产部署时,建议将一个 MySQL Router 实例部署到用于托管您的一个客户端应用程序的每台机器。还可以将 MySQL Router 部署到您的应用程序实例通过其连接的公共机器。有关说明,请参见 安装 MySQL Router

  2. 使用 InnoDB 集群管理员帐户连接到 InnoDB ClusterSet 部署中的任何活动成员服务器实例。您也可以使用 InnoDB 集群服务器配置帐户,该帐户也具有所需的权限。使用 dba.getClusterSet()cluster.getClusterSet() 命令获取 ClusterSet 对象。使用适当的帐户连接到服务器实例时,获取 ClusterSet 对象非常重要。无论您在连接时指定哪个帐户,对象中存储的默认用户帐户都用于某些操作。例如

    mysql-js> \connect [email protected]:3310
    ...
    mysql-js> myclusterset = dba.getClusterSet()
    <ClusterSet:testclusterset>

    在此示例中

    • admin2@127.0.0.1:3310 是集群中在线的任何成员服务器实例的 URI 类连接字符串。

      URI 类连接字符串由以下元素组成

    • admin2 是 InnoDB 集群管理员帐户的用户名。

    • 127.0.0.1:3310 是成员服务器实例的主机和端口,如 cluster.status() 命令所示。

    • 返回的 ClusterSet 对象分配给变量 myclusterset

  3. 通过在 MySQL Shell 中连接到集群中的任何成员服务器并发出 clusterSet.status() 命令来验证 InnoDB ClusterSet 部署是否正常。例如

    mysql-js> myclusterset.status({extended: 1})

    选择扩展输出以查看 InnoDB ClusterSet 拓扑中集群的详细状态。这将提供每个成员服务器的主机和端口,以便您可以选择一个服务器来引导 MySQL Router。有关更多信息,请参见 第 8.6 节,“InnoDB ClusterSet 状态和拓扑”

  4. 对于每个 MySQL Router 实例,在 MySQL Router 安装的实例上运行适当的 shell 中的 mysqlrouter 命令,以将 MySQL Router 引导到 InnoDB ClusterSet。在此示例中,使用 force 选项是因为 MySQL Router 之前已引导到主 InnoDB 集群

    $> mysqlrouter --bootstrap [email protected]:3310 --account=myRouter1 --name='Rome1' --force
    Please enter MySQL password for icadmin:
    # Bootstrapping system MySQL Router instance...
    
    Please enter MySQL password for myRouter1:
    - Creating account(s) (only those that are needed, if any)
    - Verifying account (using it to run SQL queries that would be run by Router)
    - Storing account in keyring
    - Creating configuration C:/Program Files/MySQL/MySQL Router 8.0/mysqlrouter.conf
    
    # MySQL Router configured for the ClusterSet 'testclusterset'
    
    After this MySQL Router has been started with the generated configuration
    
        > net start mysqlrouter
    or
        > C:\Program Files\MySQL\MySQL Router 8.0\bin\mysqlrouter.exe -c C:/Program Files/MySQL/MySQL Router 8.0/mysqlrouter.conf
    
    ClusterSet 'testclusterset' can be reached by connecting to:
    
    ## MySQL Classic protocol
    
    - Read/Write Connections: localhost:6446
    - Read/Only Connections:  localhost:6447
    
    ## MySQL X protocol
    
    - Read/Write Connections: localhost:6448
    - Read/Only Connections:  localhost:6449

    在此示例中

    • icadmin@127.0.0.1:3310 是 InnoDB ClusterSet 部署中在线的任何成员服务器实例的 URI 类连接字符串。该实例可以位于主集群中,也可以位于副本集群中。如果该实例不是主集群中的主服务器,InnoDB ClusterSet 会将事务路由到该服务器,前提是 InnoDB ClusterSet 部署正常。

      URI 类连接字符串由以下元素组成

    • icadmin 是使用 cluster.setupAdminAccount() 命令在主集群上设置的 InnoDB 集群管理员帐户的用户名,然后复制到副本集群。引导操作会提示您输入帐户的密码。InnoDB 集群管理员帐户的密码在 InnoDB ClusterSet 部署中的所有服务器实例上都相同。

    • 127.0.0.1:3310 是成员服务器实例的主机和端口,如 clusterSet.status() 命令所示。

    • myRouter1 是使用 cluster.setupRouterAccount() 命令在主集群上设置的 MySQL Router 管理员帐户的用户名。该帐户在 InnoDB ClusterSet 部署中的所有服务器实例上都相同。引导操作会提示您输入帐户的密码。

    • --name 可用于为 MySQL Router 实例分配非默认名称,使其在 InnoDB ClusterSet 状态命令的输出中易于识别。

    • --force 是在您再次引导 MySQL Router 以用于之前已将它引导到其中的现有 InnoDB 集群时所需的。

    MySQL Router 连接到服务器实例并检索 InnoDB ClusterSet 元数据。该过程与您将 MySQL Router 引导到单个 InnoDB 集群时相同。有关此过程的更多详细信息,请参见 第 6.10.3 节,“部署 MySQL Router”

  5. 引导每个 MySQL Router 实例后,通过在 MySQL Shell 中连接到 InnoDB ClusterSet 中的任何成员服务器并发出 clusterSet.listRouters() 命令来验证它现在是否已正确引导到 InnoDB ClusterSet 部署。该命令会返回所有已注册的 MySQL Router 实例的详细信息,或者您指定的路由器实例。例如

    mysql-js> myclusterset.listRouters()
    {
        "domainName": "testclusterset",
        "routers": {
           "mymachine::Rome1": {
                "hostname": "mymachine",
                "lastCheckIn": 2021-10-15 11:58:37,
                "roPort": 6447,
                "roXPort": 6449,
                "rwPort": 6446,
                "rwXPort": 6448,
                "targetCluster": "primary",
                "version": "8.0.27"
            },
            "mymachine2::Rome2": {
                "hostname": "mymachine2",
                "lastCheckIn": 2021-10-15 11:58:37,
                "roPort": 6447,
                "roXPort": 6449,
                "rwPort": 6446,
                "rwXPort": 6448,
                "targetCluster": "primary",
                "version": "8.0.27"
            }
        }
    }

    有关更多信息,请参见 InnoDB ClusterSet 的 MySQL Router 状态

  6. 要查看为每个 MySQL Router 实例设置的路由选项以及 InnoDB ClusterSet 部署的全局策略,请在 MySQL Shell 中连接到 InnoDB ClusterSet 部署中的任何成员服务器并发出 clusterSet.routingOptions() 命令。例如

    mysql-js> myclusterset.routingOptions()
    {
        "domainName": "testclusterset",
        "global": {
            "invalidated_cluster_policy": "drop_all",
            "target_cluster": "primary"
        },
        "routers": {
            "mymachine::Rome1":  {
                "target_cluster": "primary"
                "invalidated_cluster_policy": "accept_ro"
            },
            "mymachine2::Rome2": {}
        }
    }

    默认情况下,MySQL Router 实例将流量发送到主集群,并禁止对标记为 INVALIDATED 的集群的读写流量。有关更多信息以及 clusterSet.routingOptions() 命令输出的说明,请参见 MySQL Router 状态 - InnoDB ClusterSet

  7. 如果要更改全局路由策略或单个 MySQL Router 实例的路由策略,请在连接到 InnoDB ClusterSet 部署中的任何成员服务器时,在 MySQL Shell 中发出 clusterSet.setRoutingOption()。一次只能设置一个路由选项。MySQL Router 实例需要几秒钟才能获取路由策略更改。

    例如,针对 InnoDB ClusterSet myclusterset 发出的此命令将 MySQL Router 实例的目标集群更改为集群 clustertwo

    mysql-js> myclusterset.setRoutingOption('mymachine::Rome1', 'target_cluster', 'clustertwo')
    Routing option 'target_cluster' successfully updated in router 'Rome1'.

    在此示例中,myclustersetClusterSet 对象的变量,Rome1 是 MySQL Router 实例的名称,而 clustertwo 是要定位的特定集群的名称。

    要将实例的路由策略设置回遵循主集群,请发出以下命令

    mysql-js> myclusterset.setRoutingOption('mymachine::Rome1', 'target_cluster', 'primary')
    Routing option 'target_cluster' successfully updated in router 'Rome1'.

    要清除实例的路由策略,请使用 clusterSet.setRoutingOption() 命令将相关策略设置为 null。例如

    mysql-js> myclusterset.setRoutingOption('mymachine::Rome1', 'target_cluster', null)
    Routing option 'target_cluster' successfully updated in router 'Rome1'.

    有关可用路由选项的更多信息,请参见 第 6.10.4 节“路由选项”

    要设置全局路由策略,请不要指定 MySQL Router 实例,只需指定策略名称和设置即可。有关更多信息以及可用路由选项的说明,请参见 MySQL Router 状态 - InnoDB ClusterSet

  8. 准备好开始接受连接后,请配置应用程序以使用 MySQL Router 侦听 InnoDB ClusterSet 部署流量的端口。然后,在安装 MySQL Router 的服务器上使用合适的 shell 或脚本启动 MySQL Router 实例。请参见 启动 MySQL Router