ホームページ  >  記事  >  データベース  >  mysqlルーターとは何ですか

mysqlルーターとは何ですか

青灯夜游
青灯夜游オリジナル
2023-04-13 15:15:254151ブラウズ

MySQL Router は MySQL によって正式に提供される軽量ミドルウェアであり、InnoDB Cluster の一部です。アプリケーションとバックエンド MySQL サーバー間の透過的なルーティングを提供できます。主に MySQL のマスター/スレーブの問題を解決するために使用されます。データベース:高可用性、負荷分散、容易な拡張、およびクラスターのその他の問題。 MySQL Router は、アプリケーションの単一接続ポイントとしてデータベース クラスターの仮想 IP を提供し、この単一接続ポイントを通じて、ロード バランシング、読み取り/書き込み分離、フェイルオーバー、およびその他のデータベース高可用性ソリューションを実現できます。

mysqlルーターとは何ですか

このチュートリアルの動作環境: Windows7 システム、mysql8 バージョン、Dell G3 コンピューター。

1. はじめに

1.1 MySQL Router の概要

MySQL Router は、MySQL によって公式に提供される軽量ミドルウェアです。 InnoDB Cluster の機能は、アプリケーションとバックエンド MySQL サーバー間の透過的なルーティングを提供します。これは主に、高可用性、負荷分散、および MySQL マスター/スレーブ データベース クラスターの簡単な拡張の問題を解決するために使用されます。ルーターは、アプリケーションと MySQL サーバーの間に位置するトラフィック転送層として機能し、その機能は LVS に似ています。

1.2 MySQL Router を使用する理由?

グループ レプリケーション (MGR) メカニズムに基づいて、マスター ノードがダウンしてクラスターから離れると、残りのノードが paxos プロトコルに基づいて新しいマスター ノードを選択します。ここに問題があります。アプリケーションがマスター ノードに接続されているときに、マスター ノードがクラッシュしてクラスターから離脱すると、使用可能なデータベース IP アドレスが変更されます。このとき、クライアント アプリケーションは引き続き障害が発生したノードへの接続を試行します。クライアントは変更できますが、エンドアプリケーションの接続構成は変更できますが、この状況は基本的に非現実的です。

#1.3MySQL Router 関係図

MySQL グループ レプリケーションと MySQL Shel の組み合わせは次のとおりです:

上の図は、InnoDB クラスターにおける MySQL Router の役割を完全に示しています。その主な機能は、アプリケーションの単一の接続ポイントとしてデータベース クラスターに仮想 IP を提供することです。この単一の接続ポイントを通じて、負荷分散と読み取り/書き込み分離が実現され、フェイルオーバーおよびその他のデータベース高可用性ソリューションが実現されます。

MySQL Router は、次の理由から、アプリケーションが配置されているマシンにインストールすることをお勧めします:

    TCP/IP ではなくローカル Unix ソケット経由で接続すると、パフォーマンスが向上します
  • ネットワーク遅延の削減
  • MySQL インスタンスには追加のアカウントは必要ありません。myapp@%
  • の代わりに、router@198.51.100.45 を 1 つだけ使用するだけです。アプリケーション サーバーのスケーラビリティが向上します

1.4 MySQL Cluster の概要

Cluster は、この高可用性ソリューションの仮想ノードであり、すべてのメンバー上に仮想ノードを作成します。 MySQL_innodb_cluster_metadata という名前のデータベースには、クラスター情報、クラスター メンバー、グループ レプリケーション情報、接続されている MySQL Router および MySQL Router クエリを提供するその他の情報を含むクラスターのメタデータ情報が保存されます。これは、クラスター モードで表示される、グループ レプリケーション上のメンバーの論理カプセル化のレイヤーに相当します。各ノードのステータスは、グループ レプリケーション内の対応するインスタンス メンバーのステータスとリアルタイムで同期されますが、クラスター ノードとグループはレプリケーション グループのメンバーは、クラスターの作成時にのみ同期されます。後のグループ レプリケーションでのメンバーの変更は、クラスターに自動的に同期されません。クラスター内のノードは手動で追加または削除できます。これにより、アプリケーション指向の特定のインスタンスが作成されます。より制御可能で柔軟です。

2. 環境の準備

ホスト名IPアドレスロール#oratest51oratest52#test61172.16.9.61秒 #node4172.16.8.68MySQL ルーター

オペレーティング システム: CentOS Linux リリース 7.2.1511
MySQL バージョン: mysql-5.7.26-linux-glibc2.12-x86_64
MySQL ルーター バージョン: mysql-router-8.0.17-linux-glibc2。 12-x86_64
MySQL シェル バージョン: mysql-shell-8.0.17-linux-glibc2.12-x86-64bit

3. MySQL Router のインストールと構成

MySQL Router には 2 つのデプロイメント モードがあります:

  • ブートストラップ モード: フェイルオーバーをサポートし、InnoDB Cluster と組み合わせて使用​​する必要があり、--directory で指定されたパスの下にインストール ディレクトリを自動的に生成します。 . 構成ファイル内のポートは 6446 と 6447 です。
  • シンプル モード: フェイルオーバーはサポートされておらず、InnoDB クラスターで使用する必要はありません。通常、マスター/スレーブ レプリケーション モードまたはマスター/マスター レプリケーション モードで使用されます。/usr/local/mysqlrouter を使用します。 /share/doc/mysqlrouter/sample_mysqlrouter.confこの設定ファイルがデプロイされます。

3.1 ブートストラップ モードでの MySQL Router のインストール

注: MySQL Router をブートストラップ モードでインストールするための前提条件は、MGR がインストールされていることです。インストールされている、MySQL シェルがインストールされている、InnoDB クラスターが構成されている

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:
- Configuration file: /etc/mysqlrouter/mysqlrouter.conf
- # を介していくつかのデフォルト パスを確認できます。 ##プラグイン パス: /usr/lib64/mysqlrouter-
ログ パス: /var/log/mysqlrouter-
永続データ パス: / var/lib/mysqlrouter-
実行時ステータス パス: /run/mysqlroutermysqlrouter コマンド ラインで --config または -c オプションを使用してユーザー定義の設定を渡す場合ファイル、デフォルトの構成ファイルはロードされません。

3.1.3 MySQL Router を初期化し、プライマリ
[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 のアドレスを入力します。MySQL InnoDB クラスターで実行するように Router を起動して構成します。

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 ルーターは、デフォルトでインストール ディレクトリで「mysqlrouter.conf」を検索し、ホーム ディレクトリで「.mysqlrouter.conf」を検索します。バイナリ プログラムの mysqlrouter コマンドで「-c」または「--config」を使用して、構成ファイルを手動で指定することもできます。

MySQL Router の設定ファイルは断片化されています。一般的に使用される 3 つのフラグメントがあります: [DEFAULT]、[logger]、[routing:NAME]。フラグメント名は大文字と小文字が区別され、単一行の "#" のみがサポートされます。 ". または ";" コメント。

bind_address: MySQL Router が配置されているマシンの IP を追加します。
  • destinations: バックエンド mysql サーバーの IP ポート
  • mode: 2 つのモードを提供します。 、読み取り専用および読み取り / 書き込み。読み取り / 書き込みのスケジューリング モードが最初に使用可能になり、読み取り専用のスケジューリング モードはラウンドロビンです。
  • connect_timeout: 接続タイムアウト時間
  • routing_strategy: ラウンドロビンおよび最初に利用可能なポリシーを使用したルーティング戦略
  • マルチマスター モードの場合、設定ファイルは次のとおりです
[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

# でプロセスを強制終了する必要があります。 ##4. 機能テスト

次のテストはすべてクラスター下の InnoDB で行われ、MySQL Router のインストール モードはブートストラップです

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&#39;t connect to MySQL server on &#39;172.16.9.51&#39; (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视频教程

172.16.9.51 プライマリ
172.16.9.52

以上がmysqlルーターとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。