MySQL マスタースレーブレプリケーション 読み書き分離の設定方法の詳細説明

MySQL マスタースレーブレプリケーション 読み書き分離の設定方法の詳細説明

1. 説明

前回は、MySQL のインストールと構成、MySQL ステートメントの使用、MySQL データのバックアップとリカバリについて説明しました。今回は、MySQL のマスター/スレーブ レプリケーション、読み取り/書き込み分離、高可用性 MHA について紹介します。

環境は以下のとおりです。

マスター:CentOS7_x64 mysql5.721 172.16.3.175 db1
スレーブ1:CentOS7_x64 mysql5.7.21 172.16.3.235 db2
スレーブ2:CentOS7_x64 mysql5.7.21 172.16.3.235 db3
プロキシSQL/MHA:CentOS7_x64 mysql5.7.21 172.16.3.235 プロキシSQL

アーキテクチャ図:

例:

テストを構成する際、利便性のためファイアウォール ヘッダーと selinux セキュリティ ポリシーはオフにされました。
実際には、ファイアウォール ポリシーを開いてください。ワンクリックで myslqdb をインストールして構成するスクリプトがすでにあります。ここでは構成を繰り返すつもりはありません。対応するロールの対応する構成を投稿するか、関連ソフトウェアをインストールするだけです。

2. マスタースレーブレプリケーション構成

マスター データベース 1 つ、スレーブ ノード N 個。スレーブ ノードで 2 つのスレッドが開始され、Slave_IO_Running スレッドとマスター ノードの権限を持つアカウントを介して、バイナリ ログがマスター データベース ノードからローカルにコピーされ、Slave_SQL_Running スレッドを介してバイナリ ログがローカルで実行され、マスター スレーブ ノードのコンテンツ同期が実現されます。

マスター構成:

egrep -v '(^$|^#)' /usr/local/mysql/etc/my.cnf

[mysqld]
データディレクトリ=/data1/mysqldb
ソケット=/tmp/mysql.sock
キーバッファサイズ = 16M
最大許容パケット = 16M
スレッドスタック = 192K
スレッドキャッシュサイズ = 8
クエリキャッシュ制限 = 1M
クエリキャッシュサイズ = 64M
クエリキャッシュタイプ = 1
シンボリックリンク=0
innodb_file_per_table=オン
スキップ名解決=オン

サーバーID = 1
log_bin = /data1/mysqldb/mysql-bin.log
[mysqld_safe]
ログエラー=/usr/local/mysql/logs/error.log
pidファイル=/data1/mysqldb/mysql.pid
!includedir /usr/local/mysql/etc/my.cnf.d

スレーブ ノード同期アカウントを作成します。

mysql > 'replpass' で識別される 'repluser'@'172.16.3.%' に、*.* 上のレプリケーション クライアント、レプリケーション スレーブを許可します。
mysql > 権限をフラッシュします。
mysql >マスターログを表示;
+------------------+-----------+
| ログ名 | ファイルサイズ |
+------------------+-----------+
|mysql-bin.000001 | 622 |

主節點上的binlog日志文件及位置;請記下;從節點第一次同步時需要用;

スレーブノード:

egrep -v '(^$|^#)' /usr/local/mysql/etc/my.cnf

[mysqld]
データディレクトリ=/data1/mysqldb
ソケット=/data1/mysqldb/mysql.sock
キーバッファサイズ = 16M
最大許容パケット = 16M
スレッドスタック = 192K
スレッドキャッシュサイズ = 8
クエリキャッシュ制限 = 1M
クエリキャッシュサイズ = 64M
クエリキャッシュタイプ = 1
シンボリックリンク=0

innodb_file_per_table=オン
スキップ名解決=オン

server-id = 11 #スレーブノードID。各スレーブノードには異なるrelay_log = relay-logがあります
読み取り専用=オン

[mysqld_safe]
ログエラー=/usr/local/mysql/log/error.log
pidファイル=/var/run/mysql/mysql.pid
!includedir /usr/local/mysql/etc/my.cnf.d

MySQLデータベースを起動する

注: 2 つのスレーブ ノードの server-id 値は異なりますが、それ以外はすべて同じです。そのため、スレーブ ノードには 1 つの構成ファイルのみが表示されます。
データベースにログインし、データを同期してスレーブを起動します

両方のスレーブを同期して起動する必要があります

mysql > マスターを MASTER_HOST="172.16.3.175",MASTER_USER="repluser",MASTER_PASSWORD="replpass",MASTER_PORT=3306,MASTER_LOG_FILE="mysql-bin.000001",MASTER_LOG_POS=622 に変更します。
mysql > start slave; #スレーブノードを起動します ()

#スレーブノードのステータスを表示しますmysql > SHOW SLAVE STATUS;
************************** 1. 行 ****************************
    Slave_IO_State: マスターがイベントを送信するのを待機中
     Master_Host: 172.16.3.175 #マスターノードMaster_User: repluser #同期アカウントMaster_Port: 3306
    接続再試行: 60
    マスターログファイル:mysql-bin.000001
   読み取りマスターログ位置: 622
    リレーログファイル: リレーログ.000001
    リレーログ位置: 582
  リレーマスターログファイル: mysql-bin.000001
    Slave_IO_Running: はい #同期スレッドは正常です Slave_SQL_Running: はい #ローカル書き込みスレッドは正常です Replicate_Do_DB: #同期フィルターは空です (1 つまたは複数のライブラリのみを同期できます)
   Replicate_Ignore_DB: #同期されていないデータベース Replicate_Do_Table:      
  無視テーブルを複製: 
  Replicate_Wild_Do_Table: 
 Replicate_Wild_Ignore_Table: 
     Last_Errno: 0 #最後の同期エラー 0 は正常な同期を示します Last_Error: 
     スキップカウンタ: 0
   実行マスターログポジション: 622
    リレーログスペース: 615
    Until_Condition: なし
    ログファイルまで: 
    ログ位置まで: 0
   マスターSSL許可: いいえ
   マスターSSLCAファイル: 
   マスターSSLCAパス: 
    マスターSSL証明書: 
   マスターSSL暗号: 
    マスターSSLキー: 
  マスターより遅れている秒数: 0
Master_SSL_Verify_Server_Cert: いいえ
    最終IOエラー番号: 0
    最後のIOエラー: 
    最終SQLエラー番号: 0
    最後のSQLエラー: 
 Replicate_Ignore_Server_Ids: 
    マスターサーバーID: 1
     マスター_UUID: 57017c43-36e3-11e8-ac76-080027393fc7
    マスター情報ファイル: /data1/mysqldb/master.info
     SQL_遅延: 0
   SQL_残り遅延: NULL
  Slave_SQL_Running_State: スレーブはすべてのリレーログを読み取りました。さらに更新を待機しています。
   マスター再試行回数: 86400
     マスターバインド: 
  最終IOエラータイムスタンプ: 
  最終SQLエラータイムスタンプ: 
    マスターSSL証明書: 
   マスターSSLCrlパス: 
   取得済み_Gtid_Set: 
   実行されたGtidセット: 
    自動位置: 0
   Replicate_Rewrite_DB: 
     チャンネル名: 
   マスター TLS バージョン: 
セット内の 1 行 (0.00 秒)
エラー: 
クエリが指定されていません

マスタースレーブ同期をテストする

マスターにテスト データをインポートし、データを変更してスレーブのデータが一貫しているかどうかを確認します。

[root@db1 ~]# mysql < Testdb.sql
データベースにログインします [root@db1 ~]# mysql -uroot -p
mysql> データベースを表示します。
+--------------------+
| データベース |
+--------------------+
 勉強 |
+--------------------+
セット内の行数は 5 です (0.00 秒)
### study テストデータベースが正常にインポートされましたmysql> use study;
データベースが変更されました
mysql> テーブルを表示します。
+-----------------+
| 研究中の表 |
+-----------------+
| クラス |
| コース |
| パート |
| スコア |
| 学生 |
|tb31|
|tb32|
| 先生 |
| テスト1 |
| テスト2 |
| ユーザー情報 |
+-----------------+
セット内の行数は 11 です (0.00 秒)
#test1 test2テーブルを削除する

ノードからのスレーブビュー

mysql> テーブルを表示します。
+-----------------+
| 研究中の表 |
+-----------------+
| クラス |
| コース |
| パート |
| スコア |
| 学生 |
|tb31|
|tb32|
| 先生 |
| ユーザー情報 |
+-----------------+
セット内の行数は 9 です (0.00 秒)

データは正常に同期できます。マスタースレーブ同期は、最初に手動で開始する必要があることに注意してください。その後は、MySQL サービスで自動的に開始されます。マスタースレーブ同期アーキテクチャは、データ同期のみを容易にします。サードパーティのツールが関与していない場合は、プログラム内で読み取りと書き込みの分離を実現する必要がありますが、これは避けられません。エラーが発生した場合は、データを手動で同期する必要があります。ここでは、proxysql を使用して読み取りと書き込みの分離を行います。

3. ProxySQLの読み取りと書き込みの分離

以上でマスタースレーブレプリケーション構成が完了しましたが、これは基本的な構成に過ぎず、proxysql を追加することで MySQL の読み書き分離を実現しています。proxysql は haproxy の 7 層プロキシルーティング機能に似ており、MySQL プロトコルのデータベースプロキシをサポートしています。これは DBA によって DBA のために開発されており、ユーザー要求は proxysql に送信され、書き込み要求の場合はマスターノードに送信され、読み取り要求はスレーブノードグループに送信されます。このようにして、読み書き分離が実現され、マスターデータベースの IO プレッシャーがある程度軽減されます。
ProxySQLをダウンロードしてインストールする
最新バージョンは1.4.7-1です(最新バージョンに問題があるため)
ここでは、1.3.6-1を使用してCentOS7ベースのrpmパッケージをダウンロードします。ローカルにダウンロードし、yumでインストールします。

[root@proxysql ~]# yum install proxysql-1.3.6-1-centos7.x86_64.rpm -y
[root@proxysql ~]# rpm -ql proxysql
プロキシSQL
/etc/proxysql.cnf #メイン設定ファイル /usr/bin/proxysql
プロキシSQLツール
プロキシSQLツール

構成は次のとおりです。

ProxySQL を構成する前に、ProxySQL がマスター ノードとスレーブ ノードで動作できるように、マスター ノードで承認済みアカウントを構成する必要があります。また、ProxySQL 上の MySQL クライアント ツールは、マスター ノードとスレーブ ノード上のものと一致している必要があります。
マスターノードのログインアカウントを承認します。

 mysql > GRANT ALL ON *.* TO 'myadmin'@'172.16.3.%' identified by 'mypass';

proxysql.cnf の設定

[root@proxysql ~]# egrep -v '(^$|^#)' /etc/proxysql.cnf

データディレクトリ="/var/lib/proxysql"
管理者変数=
{ 
 admin_credentials="admin:admin" #proxysql 独自の管理者ユーザー名とパスワード mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock"
}
mysql_variables=
{
 threads=4 #スレッド数。CPUコア数と一致させることを推奨 max_connections=2048 #最大接続 default_query_delay=0
 デフォルトクエリタイムアウト=36000000
 圧縮あり=true
 ポーリングタイムアウト=2000
 インターフェース="0.0.0.0:3306;/tmp/proxysql.sock" #外部インターフェース default_schema="information_schema"
 スタックサイズ=1048576
 サーバーバージョン="5.5.30"
 接続タイムアウトサーバー=3000
 monitor_username="モニター"
 monitor_password="モニター"
 モニター履歴=600000
 モニター接続間隔=60000
 モニターのping間隔=10000
 モニター読み取り専用間隔=1500
 モニター読み取り専用タイムアウト=500
 ping_interval_server_msec=120000
 ping_timeout_server=500
 コマンド統計=true
 セッションソート=true
 失敗時の接続再試行=10
}

#####マスターノードとスレーブノードの構成mysql_servers =      
(
 {
  address = "172.16.3.175" # デフォルトなし、必須。ポートが 0 の場合、アドレスは Unix ソケットドメインとして解釈されます
  port = 3306 # デフォルトなし、必須。ポートが0の場合、アドレスはUnixソケットドメインとして解釈されます
  hostgroup = 1 # グループ番号を設定します status = "ONLINE" # デフォルト: ONLINE
  重み = 1 # デフォルト: 1
  圧縮 = 0 # デフォルト: 0
  max_connections = 200 ###最大接続数を定義する},
 {
  address = "172.16.3.235" # デフォルトなし、必須。ポートが 0 の場合、アドレスは Unix ソケットドメインとして解釈されます
  port = 3306 # デフォルトなし、必須。ポートが0の場合、アドレスはUnixソケットドメインとして解釈されます
  hostgroup = 2 # デフォルトなし、必須
  status = "ONLINE" # デフォルト: ONLINE
  重み = 1 # デフォルト: 1
  圧縮 = 0 # デフォルト: 0
  最大接続数=1000
 },
 {
  address = "172.16.3.241" # デフォルトなし、必須。ポートが 0 の場合、アドレスは Unix ソケットドメインとして解釈されます
  port = 3306 # デフォルトなし、必須。ポートが0の場合、アドレスはUnixソケットドメインとして解釈されます
  hostgroup = 2 # デフォルトなし、必須
  status = "ONLINE" # デフォルト: ONLINE
  重み = 1 # デフォルト: 1
  圧縮 = 0 # デフォルト: 0
  最大接続数=1000
 }
)
mysql_users:
(
 {
  username = "myadmin" # デフォルトなし、必須
  password = "mypass" # デフォルト: ''
  default_hostgroup = 1 # デフォルト: 0
  最大接続数=1000
  default_schema="テスト"
  active = 1 #アクティブ化するかどうか}
)
mysql_クエリルール:
(
)
スケジューラ=
(
)
mysql_replication_hostgroups=
(
  {
    writer_hostgroup=1 #書き込みグループ番号1を定義
    reader_hostgroup=2 #読み取りグループ番号2を定義
    comment="テスト repl 1" #コメント内容}
)

proxysqlサービスを開始する


[root@proxysql ~]# service proxysql start

ProxySQL のテスト

proxysql を介してデータベースの使用をシミュレートします [root@proxysql ]# mysql -h172.16.3.175 -umyadmin -pmypass
mysql: [警告] コマンドライン インターフェイスでパスワードを使用すると安全でない可能性があります。
MySQL モニターへようこそ。コマンドは ; または \g で終わります。
MySQL接続IDは17406です
サーバーバージョン: 5.7.21-log MySQL コミュニティサーバー (GPL)
Copyright (c) 2000, 2018, Oracle およびその関連会社。無断複写・転載を禁じます。
OracleはOracle Corporationおよびその関連会社の登録商標です。
その他の名称は各社の商標である場合があります。
所有者。
ヘルプを表示するには、「help;」または「\h」と入力します。現在の入力ステートメントをクリアするには、「\c」と入力します。
マイSQL> 

mysql > データベースを表示;
mysql> データベースを表示します。
+--------------------+
| データベース |
+--------------------+
| 情報スキーマ |
|mysql |
| パフォーマンススキーマ |
| 勉強 |
|システム|
+--------------------+
セット内の行数は 5 です (0.00 秒)
### 研究データベース user_info の 6 から 12 の間のデータを削除します。削除前:
mysql> user_info から * を選択します。
+-----+-------+-------+--------+----------+
| nid | 名前 | 年齢 | 性別 | part_nid |
+-----+-------+-------+--------+----------+
| 1 | さん | 20 | 男性 | 1 |
| 2 | ドン | 29 | 男性 | 2 |
| 4 | リン | 28 | 男性 | 4 |
| 5 | 歳 | 28 | 男性 | 3 |
| 6 | ドン | 30 | 男性 | 1 |
| 7 | b | 11 | 女性 | 1 |
| 8 | c | 12 | 女性 | 1 |
| 9 | d | 18 | 女性 | 4 |
| 10 | e | 22 | 男性 | 3 |
| 11 | 女性 | 23 | 男性 | 2 |
| 12 | ドンギー | 22 | 男性 | 1 |
+-----+-------+-------+--------+----------+
セット内の行数は 11 です (0.00 秒)
削除後:
mysql> nid >6 かつ nid <12 の場合、user_info から削除します。
クエリは正常、5 行が影響を受けました (0.03 秒)

mysql> user_info から * を選択します。
+-----+-------+-------+--------+----------+
| nid | 名前 | 年齢 | 性別 | part_nid |
+-----+-------+-------+--------+----------+
| 1 | さん | 20 | 男性 | 1 |
| 2 | ドン | 29 | 男性 | 2 |
| 4 | リン | 28 | 男性 | 4 |
| 5 | 歳 | 28 | 男性 | 3 |
| 6 | ドン | 30 | 男性 | 1 |
| 12 | ドンギー | 22 | 男性 | 1 |
+-----+-------+-------+--------+----------+
セット内の 6 行 (0.00 秒)

マスター ノードとスレーブ ノードを確認すると、上記のクエリと変更データが proxysql によって処理するためにバックエンドに正しくプロキシされていることがわかります。
上記は直感的ではありません。proxysqlと各マスターノードおよびスレーブノード間の通信を表示するには、マスターノードとスレーブノードにtcpdumpをインストールし、パケットをフィルタリングします。

マスターノード:
次のようなもの:
[root@db1 ~]# tcpdump -i enp0s3 -nn tcp ポート 3306
tcpdump: 詳細な出力は抑制されています。完全なプロトコル デコードには -v または -vv を使用してください。
enp0s3 でリッスン、リンク タイプ EN10MB (イーサネット)、キャプチャ サイズ 262144 バイト
18:04:34.678861 IP 172.16.3.254.42191 > 172.16.3.175.3306: フラグ [S]、シーケンス 3385407732、win 29200、オプション [mss 1460、sackOK、TS 値 17576713 ecr 0、nop、wscale 7]、長さ 0
18:04:34.678908 IP 172.16.3.175.3306 > 172.16.3.254.42191: フラグ [S.]、シーケンス 1579426335、ack 3385407733、win 28960、オプション [mss 1460、sackOK、TS 値 29413673 ecr 17576713、nop、wscale 7]、長さ 0
18:04:34.680902 IP 172.16.3.254.42191 > 172.16.3.175.3306: フラグ [.]、ack 1、win 229、オプション [nop、nop、TS val 17576715 ecr 29413673]、長さ 0
18:04:34.681264 IP 172.16.3.175.3306 > 172.16.3.254.42191: フラグ [P.]、シーケンス 1:83、ack 1、win 227、オプション [nop、nop、TS 値 29413675 ​​ecr 17576715]、長さ 82
....
ノードから:
次のようなもの:
[root@db2 data1]# tcpdump -i enp0s3 -nn tcp ポート 3306
tcpdump: 詳細な出力は抑制されています。完全なプロトコル デコードには -v または -vv を使用してください。
enp0s3 でリッスン、リンク タイプ EN10MB (イーサネット)、キャプチャ サイズ 262144 バイト
18:02:57.932043 IP 172.16.3.254.42733 > 172.16.3.235.3306: フラグ [S]、シーケンス 76520456、win 29200、オプション [mss 1460、sackOK、TS 値 17479189 ecr 0、nop、wscale 7]、長さ 0
...........

ProxySQL コマンドライン管理インターフェース: 実行時の変更をサポート

 [root@proxysql]# mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='Admin> '
管理者> データベースを表示;
+-----+---------+-------------------------------+
| シーケンス | 名前 | ファイル |
+-----+---------+-------------------------------+
| 0 | メイン | |
| 2 | ディスク | /var/lib/proxysql/proxysql.db |
| 3 | 統計 | |
| 4 | モニター | |
+-----+---------+-------------------------------+
セット内の 4 行 (0.00 秒)

上記の統計、モニター、メインはすべて構成ファイル データベースから取得され、再起動せずに MySQL ランタイムと同様の方法で変更できます。

これまでに、proxysql マスター スレーブ レプリケーションに基づく読み取り/書き込み分離アーキテクチャが完成しました。
デュアルマスターまたはマルチマスターモデルでは、読み取りと書き込みの分離を実装する必要はなく、haproxy、nginx、lvs などの負荷分散のみが必要です。
マスター データがマシン上に残っている場合、ProxySQL では問題は解決されません。この場合、後で紹介する MHA を使用して解決する必要があります。

以下もご興味があるかもしれません:
  • MySQL データベースのマスター スレーブ分離のサンプル コード
  • MySQL マスタースレーブ同期、読み取り書き込み分離構成手順
  • MySQL マスタースレーブレプリケーション、読み取り/書き込み分離、バックアップとリカバリの詳細な説明
  • MySQL マスタースレーブレプリケーションの読み書き分離構造の詳細な説明
  • Linux システムで MySQL マスター/スレーブ分離を構成する手順

<<:  protobuf の簡単な紹介と Ubuntu 16.04 環境でのインストールチュートリアル

>>:  Vue での weixin-js-sdk の一般的な使用方法の詳細な説明

推薦する

HTML で 2 列レイアウトを実装する方法の例 (左側は固定幅、右側は適応幅)

HTMLは2列レイアウトを実装し、左側は固定幅、右側は適応幅です。実装1: <スタイル>...

バックエンドから返される 100,000 個のデータをフロントエンドでより適切に表示するにはどうすればよいですか?

目次予備作業バックエンド構築フロントエンドページダイレクトレンダリングsetTimeout ページン...

Centos7 FFmpeg オーディオ/ビデオ ツールのインストールに関する簡単なドキュメント

ffmpeg は非常に強力なオーディオおよびビデオ処理ツールです。公式 Web サイトは http:...

Facebook によるインターネット サービスのほぼ完璧な再設計

<br />出典: http://www.a-xuan.cn/?p=197 先ほどFac...

MySQL の NULL と空の文字列

最近、MySQL に触れました。昨日、テーブル構造情報を格納するための新しいテーブルを作成しました。...

Vue の基本的な手順の例のグラフィック説明

目次1. v-on指令1. 基本的な使い方2. 糖衣構文3. イベントパラメータ4. イベント修飾子...

Linux の圧縮および解凍コマンドの紹介

目次一般的な圧縮形式: gz .bz2 .xz .zip一般的に使用されるアーカイブは圧縮を必要とす...

MySQL binlog の解析

目次1. binlogの紹介2. Binlog関連のパラメータ3. バイナリログの内容を分析するIV...

MySQL 8.0.15 のダウンロードとインストールの詳細なチュートリアルは初心者にとって必須です。

この記事では、MySQL 8.0.15をダウンロードしてインストールするための具体的な手順を参考まで...

LinuxはRsync+Inotifyを使用してローカルとリモートのデータのリアルタイム同期を実現します。

0x0 テスト環境本社本番サーバーと支社バックアップサーバーはリモートデータバックアップが必要です...

MySQL を使用して Excel でデータ生成を完了する方法

Excel は、データ分析に最もよく使用されるツールです。この記事では、MySQL と Excel ...

MySQL のマスタースレーブレプリケーションと読み取り書き込み分離の原理と使用法の詳細な説明

この記事では、例を使用して、MySQL マスター/スレーブ レプリケーションと読み取り/書き込み分離...

JavaScript 配列メソッド - 体系的な概要と詳細な説明

目次一般的な配列メソッド配列要素の追加と削除配列ヘッダーの操作配列の末尾を操作する任意の場所に追加ま...

ドラッグアンドドロップによる並べ替えの詳細を実現する js

目次1. はじめに2. 実装3. HTML ドラッグ アンド ドロップ API を使用しないのはなぜ...

Apache Bench ストレステストツールの実装原理と使用状況分析

1: スループット(1秒あたりのリクエスト数)サーバーの同時処理能力を定量的に表したもので、reqs...