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' - DB 연결 문자 세트(기본값 utf8)
'gtid' - 시작할 GTID 마커(형식 9b1c8d18-2a76-11e5-a26b-000c2976f3f3:1-177592)
'mariaDbGtid' - 시작할 MariaDB GTID 마커(형식 1-1-3,0-1-88)
'slaveId' - 식별을 위한 스크립트 슬레이브 ID(기본값: 666) (슬레이브 호스트 표시)
'binLogFileName' - 시작할 bin 로그 파일 이름
'binLogPosition' - 시작할 bin 로그 위치
'eventsOnly' - 이벤트를 수신할 배열(ConstEventType.php 파일의 전체 목록)
'eventsIgnore' - 이벤트를 무시하는 배열(ConstEventType.php 파일의 전체 목록)
'tablesOnly' - 지정된 테이블만 수신하는 배열(기본값은 모든 테이블)
'databasesOnly' - 지정된 데이터베이스만 수신하는 배열(기본값은 모든 데이터베이스)
'tableCacheSize' - 일부 데이터는 정보 스키마에서 수집되며 이 데이터는 캐시됩니다.
'custom' - 확장/구현된 자체 클래스에서 일부 매개변수를 설정해야 하는 경우
'heartbeatPeriod' - 복제 하트비트 사이의 간격을 초 단위로 설정합니다. 마스터의 바이너리 로그가 이벤트로 업데이트될 때마다 다음 하트비트에 대한 대기 기간이 재설정됩니다. 간격은 0~4294967초 범위와 밀리초 단위의 분해능을 갖는 10진수 값입니다. 0이 아닌 가장 작은 값은 0.001입니다. 간격보다 긴 기간 동안 바이너리 로그 파일에 전송되지 않은 이벤트가 없는 경우에만 마스터가 하트비트를 전송합니다.
'saveUuid' - 식별을 위해 슬레이브 UUID를 설정합니다(기본값: 0015d2b6-8a06-4e5e-8c07-206ef3fbd274)
루비: https://github.com/y310/kodama
자바: https://github.com/shyiko/mysql-binlog-connector-java
바로가기: https://github.com/siddontang/go-mysql
파이썬: https://github.com/noplay/python-mysql-replication
.NET: https://github.com/rusuly/MySqlCdc
모든 예제는 예제 디렉터리에서 사용할 수 있습니다.
이 예에서는 모든 복제 이벤트를 콘솔에 덤프합니다.
사용자, 호스트 및 비밀번호에 대한 구성을 변경하는 것을 잊지 마십시오.
사용자에게는 복제 권한이 있어야 합니다. [ 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에 웹과 같은 많은 진입 지점이 있는 경우 백엔드 다른 마이크로서비스가 모든 것에 처리를 추가하는 것이 항상 저렴하지는 않습니다. 그러나 mysql 복제를 사용하면 쓰기 이벤트를 수신하고 비동기식으로 처리할 수 있는 프로토콜입니다(rabbitmq, redis 또는 kafka와 같은 일부 대기열 시스템에 항목을 추가하는 것이 가장 좋습니다). 또한 캐시 무효화, 검색 엔진 복제, 실시간 분석 및 감사에도 사용됩니다.
우선, "bar" 테이블에서 1,000,000개의 레코드를 업데이트하고 "foo" 테이블에서 이 하나의 삽입이 필요한 경우와 같이 많은 이벤트가 발생할 수 있다는 점을 알아야 합니다. 그러면 모두 스크립트로 처리되어야 합니다. 그리고 데이터를 기다려야 합니다. 이는 정상이며 작동 방식입니다. 구성 옵션을 사용하여 속도를 높일 수 있습니다. 또한 스크립트가 충돌하는 경우 중복을 피하기 위해 이 스크립트를 다시 실행할 때 이 위치에서 시작하려면 때때로 위치 형식 binlog(또는 gtid)를 저장해야 합니다.
Rabbitmq, redis 또는 kafka와 같은 1포인트 사용 대기열 시스템에서 언급한 것처럼 여러 스크립트에서 데이터를 처리할 수 있는 기능을 제공합니다.
쉬는 시간에 문제를 풀어보도록 하겠습니다 :)
슬레이브 모드의 다른 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 설정은 하나의 큰 스트림 덩어리를 생성하므로 더 많은 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] 더 작은 청크로 분할