MySQL レプリケーション プロトコルの純粋な PHP 実装。これにより、挿入、更新、削除などのイベントとそのデータおよび生の SQL クエリを受信できるようになります。
クリエイターの素晴らしい作品に基づいています:https://github.com/noplay/python-mysql-replication および https://github.com/fengxiangyun/mysql-replication
あなたのプロジェクトでは
composer require krowinski/php-mysql-replication
またはスタンドアロン
git clone https://github.com/krowinski/php-mysql-replication.git
composer install -o
PHP
MYSQL
MySQL サーバー構成ファイルでレプリケーションを有効にする必要があります。
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
binlog-format = row #Very important if you want to receive write, update and delete row events
MySQL レプリケーション イベントの説明 https://dev.mysql.com/doc/internals/en/event-meanings.html
MySQL ユーザー権限:
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'user'@'host';
GRANT SELECT ON `dbName`.* TO 'user'@'host';
ConfigBuilder または ConfigFactory を使用して構成を作成します。利用可能なオプション:
'user' - mysql ユーザー (必須)
「ip」または「host」 - mysql のホスト/IP (必須)
'password' - mysql パスワード (必須)
'port' - mysql ホスト ポート (デフォルトは 3306)
'charset' - データベース接続の文字セット (デフォルトは utf8)
'gtid' - 開始する GTID マーカー (形式 9b1c8d18-2a76-11e5-a26b-000c2976f3f3:1-177592)
'mariaDbGtid' - 開始する MariaDB GTID マーカー (形式 1-1-3、0-1-88)
'slaveId' - 識別用のスクリプト スレーブ ID (デフォルト: 666) (SHOW SLAVE HOSTS)
'binLogFileName' - 開始する bin ログ ファイル名
'binLogPosition' - 開始する bin ログの位置
'eventsOnly' - イベントをリッスンする配列 (ConstEventType.php ファイル内の完全なリスト)
'eventsIgnore' - イベントを無視する配列 (ConstEventType.php ファイル内の完全なリスト)
'tablesOnly' - 指定されたテーブルのみをリッスンする配列 (デフォルトはすべてのテーブル)
'databasesOnly' - 指定されたデータベースのみをリッスンする配列 (デフォルトはすべてのデータベース)
'tableCacheSize' - 一部のデータは情報スキーマから収集され、このデータはキャッシュされます。
'custom' - 拡張/実装された独自のクラスで一部のパラメータを設定する必要がある場合
'heartbeatPeriod' - レプリケーションのハートビート間の間隔を秒単位で設定します。マスターのバイナリ ログがイベントで更新されるたびに、次のハートビートの待機期間がリセットされます。間隔は、0 ~ 4294967 秒の範囲とミリ秒単位の分解能を持つ 10 進数値です。ゼロ以外の最小値は 0.001 です。ハートビートは、バイナリ ログ ファイルに間隔より長い期間未送信のイベントがない場合にのみ、マスターによって送信されます。
'saveUuid' - 識別用にスレーブ UUID を設定します (デフォルト: 0015d2b6-8a06-4e5e-8c07-206ef3fbd274)
Ruby: https://github.com/y310/kodama
Java: https://github.com/shyiko/mysql-binlog-connector-java
行く: https://github.com/siddontang/go-mysql
Python: https://github.com/noplay/python-mysql-replication
.NET: https://github.com/rusuly/MySqlCdc
すべての例は、example ディレクトリで入手できます。
この例では、すべてのレプリケーション イベントをコンソールにダンプします。
ユーザー、ホスト、パスワードの設定を忘れずに変更してください。
ユーザーはレプリケーション権限を持っている必要があります [ REPLICATION CLIENT、SELECT]
php example/dump_events.php
テスト SQL イベントの場合:
CREATE DATABASE php_mysql_replication ;
use php_mysql_replication;
CREATE TABLE test4 (id int NOT NULL AUTO_INCREMENT, data VARCHAR ( 255 ), data2 VARCHAR ( 255 ), PRIMARY KEY (id));
INSERT INTO test4 (data,data2) VALUES ( " Hello " , " World " );
UPDATE test4 SET data = " World " , data2 = " Hello " WHERE id = 1 ;
DELETE FROM test4 WHERE id = 1 ;
出力は次のようになります (GTID のオフ/オンなどの設定に応じて異なります)。
=== Event format description ===
Date: 2017-07-06T13:31:11+00:00
Log position: 0
Event size: 116
Memory usage 2.4 MB
=== Event gtid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803092
Event size: 48
Commit: true
GTID NEXT: 3403c535-624f-11e7-9940-0800275713ee:13675
Memory usage 2.42 MB
=== Event query ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803237
Event size: 145
Database: php_mysql_replication
Execution time: 0
Query: CREATE DATABASE php_mysql_replication
Memory usage 2.45 MB
=== Event gtid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803285
Event size: 48
Commit: true
GTID NEXT: 3403c535-624f-11e7-9940-0800275713ee:13676
Memory usage 2.45 MB
=== Event query ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803500
Event size: 215
Database: php_mysql_replication
Execution time: 0
Query: CREATE TABLE test4 (id int NOT NULL AUTO_INCREMENT, data VARCHAR(255), data2 VARCHAR(255), PRIMARY KEY(id))
Memory usage 2.45 MB
=== Event gtid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803548
Event size: 48
Commit: true
GTID NEXT: 3403c535-624f-11e7-9940-0800275713ee:13677
Memory usage 2.45 MB
=== Event query ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803637
Event size: 89
Database: php_mysql_replication
Execution time: 0
Query: BEGIN
Memory usage 2.45 MB
=== Event tableMap ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803708
Event size: 71
Table: test4
Database: php_mysql_replication
Table Id: 866
Columns amount: 3
Memory usage 2.71 MB
=== Event write ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803762
Event size: 54
Table: test4
Affected columns: 3
Changed rows: 1
Values: Array
(
[0] => Array
(
[id] => 1
[data] => Hello
[data2] => World
)
)
Memory usage 2.74 MB
=== Event xid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803793
Event size: 31
Transaction ID: 662802
Memory usage 2.75 MB
=== Event gtid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803841
Event size: 48
Commit: true
GTID NEXT: 3403c535-624f-11e7-9940-0800275713ee:13678
Memory usage 2.75 MB
=== Event query ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57803930
Event size: 89
Database: php_mysql_replication
Execution time: 0
Query: BEGIN
Memory usage 2.76 MB
=== Event tableMap ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804001
Event size: 71
Table: test4
Database: php_mysql_replication
Table Id: 866
Columns amount: 3
Memory usage 2.75 MB
=== Event update ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804075
Event size: 74
Table: test4
Affected columns: 3
Changed rows: 1
Values: Array
(
[0] => Array
(
[before] => Array
(
[id] => 1
[data] => Hello
[data2] => World
)
[after] => Array
(
[id] => 1
[data] => World
[data2] => Hello
)
)
)
Memory usage 2.76 MB
=== Event xid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804106
Event size: 31
Transaction ID: 662803
Memory usage 2.76 MB
=== Event gtid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804154
Event size: 48
Commit: true
GTID NEXT: 3403c535-624f-11e7-9940-0800275713ee:13679
Memory usage 2.76 MB
=== Event query ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804243
Event size: 89
Database: php_mysql_replication
Execution time: 0
Query: BEGIN
Memory usage 2.76 MB
=== Event tableMap ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804314
Event size: 71
Table: test4
Database: php_mysql_replication
Table Id: 866
Columns amount: 3
Memory usage 2.76 MB
=== Event delete ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804368
Event size: 54
Table: test4
Affected columns: 3
Changed rows: 1
Values: Array
(
[0] => Array
(
[id] => 1
[data] => World
[data2] => Hello
)
)
Memory usage 2.77 MB
=== Event xid ===
Date: 2017-07-06T15:23:44+00:00
Log position: 57804399
Event size: 31
Transaction ID: 662804
Memory usage 2.77 MB
VM でテスト済み
Debian 8.7
PHP 5.6.30
Percona 5.6.35
inxi
CPU(s)~4 Single core Intel Core i5-2500Ks (-SMP-) clocked at 5901 Mhz Kernel~3.16.0-4-amd64 x86_64 Up~1 day Mem~1340.3/1996.9MB HDD~41.9GB(27.7% used) Procs~122 Client~Shell inxi~2.1.28
php example/benchmark.php
Start insert data
7442 event by seconds (1000 total)
7679 event by seconds (2000 total)
7914 event by seconds (3000 total)
7904 event by seconds (4000 total)
7965 event by seconds (5000 total)
8006 event by seconds (6000 total)
8048 event by seconds (7000 total)
8038 event by seconds (8000 total)
8040 event by seconds (9000 total)
8055 event by seconds (10000 total)
8058 event by seconds (11000 total)
8071 event by seconds (12000 total)
まず第一に、MYSQL は非同期呼び出しを提供しません。通常、これをアプリケーションでプログラムする必要があります (イベントのディスパッチとキュー システムへの追加によって、DB に Web やバックエンドの他のマイクロサービスなどの多くのエントリ ポイントがある場合、それらすべてに処理を追加するのは必ずしも安価ではありません。ただし、mysql レプリケーションを使用する)書き込みイベントをリッスンして非同期に処理できるプロトコル (最適な組み合わせは、rabbitmq、redis、kafka などのキュー システムにアイテムを追加することです)。キャッシュ、検索エンジンのレプリケーション、リアルタイムでも無効化します。分析と監査。
まず第一に、テーブル "bar" 内の 1 000 000 レコードを更新し、テーブル "foo" からこのレコードを 1 つ挿入する必要がある場合など、多くのイベントが発生する可能性があることを知っておく必要があります。その後、すべてをスクリプトで処理する必要があります。データが届くまで待つ必要があります。これが正常であり、これが仕事のやり方です。設定オプションを使用すると高速化できます。また、スクリプトがクラッシュした場合は、重複を避けるために、このスクリプトを再度実行するときにこの位置から開始できるように、binlog (または gtid) 形式の位置を時々保存する必要があります。
1 ポイントで述べたように、rabbitmq、redis、kafka などのキュー システムを使用すると、複数のスクリプトでデータを処理できるようになります。
問題を作成して、空いた時間に取り組んでみます:)
スレーブ モードでは他の MYSQL と同様に動作し、同じオーバーヘッドが発生します。
これを修正するには、db 設定のnet_read_timeout
とnet_write_timeout
3600 に増やすのが最善です。 (tx Bijimon)
my.conf binlog_row_image=full
に設定して、部分的な更新のみを受信する問題を修正します。
これを修正するには my.conf log_slave_updates=on
を設定します (#71)(#66)
デフォルトの MYSQL 設定では、ストリームの 1 つの大きな blob が生成されます。これには、より多くの RAM/CPU が必要です。変数binlog_row_event_max_size
[https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-] を使用して、より小さなストリーム用にこれを変更できます。 log.html#sysvar_binlog_row_event_max_size] をより小さなチャンクに分割します