การใช้งาน PHP อย่างแท้จริงของโปรโตคอลการจำลองแบบ MySQL ซึ่งจะทำให้คุณได้รับเหตุการณ์ต่างๆ เช่น แทรก อัปเดต ลบ พร้อมด้วยข้อมูลและการสืบค้น SQL แบบ Raw
ขึ้นอยู่กับผลงานที่ยอดเยี่ยมของผู้สร้าง: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 เพื่อสร้างการกำหนดค่า ตัวเลือกที่มี:
'ผู้ใช้' - ผู้ใช้ mysql ของคุณ (จำเป็น)
'ip' หรือ 'host' - โฮสต์ mysql/ip ของคุณ (จำเป็น)
'รหัสผ่าน' - รหัสผ่าน mysql ของคุณ (จำเป็น)
'พอร์ต' - พอร์ตโฮสต์ mysql ของคุณ (ค่าเริ่มต้น 3306)
'ชุดอักขระ' - ชุดอักขระการเชื่อมต่อ db (ค่าเริ่มต้น utf8)
'gtid' - เครื่องหมาย GTID ที่จะเริ่มต้น (รูปแบบ 9b1c8d18-2a76-11e5-a26b-000c2976f3f3:1-177592)
'mariaDbGtid' - เครื่องหมาย MariaDB GTID เพื่อเริ่มต้น (รูปแบบ 1-1-3,0-1-88)
'slaveId' - รหัสทาสของสคริปต์เพื่อระบุตัวตน (ค่าเริ่มต้น: 666) (SHOW SLAVE HOSTS)
'binLogFileName' - ชื่อไฟล์บันทึก bin ที่จะเริ่มต้น
'binLogPosition' - ตำแหน่งบันทึกของถังขยะที่จะเริ่มต้น
'eventsOnly' - อาร์เรย์เพื่อฟังเหตุการณ์ (รายการทั้งหมดในไฟล์ ConstEventType.php)
'eventsIgnore' - อาร์เรย์ที่จะละเว้นเหตุการณ์ (รายการทั้งหมดในไฟล์ ConstEventType.php)
'tablesOnly' - อาร์เรย์เพื่อฟังเฉพาะตารางที่กำหนดเท่านั้น (ค่าเริ่มต้นของตารางทั้งหมด)
'databasesOnly' - อาร์เรย์เพื่อฟังเฉพาะฐานข้อมูลที่กำหนด (ค่าเริ่มต้นของฐานข้อมูลทั้งหมด)
'tableCacheSize' - ข้อมูลบางส่วนถูกรวบรวมจากสคีมาข้อมูล ข้อมูลนี้ถูกแคช
'กำหนดเอง' - หากต้องตั้งค่าพารามิเตอร์บางตัวในคลาสที่ขยาย/นำไปใช้เอง
'heartbeatPeriod' - ตั้งค่าช่วงเวลาเป็นวินาทีระหว่างการเต้นของหัวใจการจำลอง เมื่อใดก็ตามที่บันทึกไบนารี่ของต้นแบบได้รับการอัปเดตด้วยเหตุการณ์ ระยะเวลารอสำหรับฮาร์ทบีทครั้งถัดไปจะถูกรีเซ็ต Interval คือค่าทศนิยมที่มีช่วง 0 ถึง 4294967 วินาทีและมีความละเอียดเป็นมิลลิวินาที ค่าที่ไม่ใช่ศูนย์ที่น้อยที่สุดคือ 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 จะไม่ให้คุณโทรแบบอะซิงก์ โดยปกติคุณจะต้องตั้งโปรแกรมสิ่งนี้ในแอปพลิเคชันของคุณ (โดยการส่งเหตุการณ์และเพิ่มไปยังระบบคิวบางระบบ และหากฐานข้อมูลของคุณมีจุดเข้าหลายจุดเช่นเว็บ แบ็กเอนด์ไมโครเซอร์วิสอื่น ๆ การเพิ่มการประมวลผลให้กับไมโครเซอร์วิสอื่น ๆ นั้นไม่ถูกเสมอไป แต่การใช้การจำลองแบบ mysql โปรโตคอลที่คุณสามารถฟังเหตุการณ์การเขียนและประมวลผลแบบอะซิงโครนัส (คำสั่งผสมที่ดีที่สุดคือการเพิ่มรายการลงในระบบคิวบางอย่างเช่น rabbitmq, redis หรือ kafka) นอกจากนี้ในแคชที่ไม่ถูกต้อง การจำลองแบบเครื่องมือค้นหา การวิเคราะห์แบบเรียลไทม์ และการตรวจสอบ
ก่อนอื่น คุณต้องรู้ว่าอาจมีเหตุการณ์มากมายเกิดขึ้น เช่น หากคุณอัปเดต 1,000,000 ระเบียนในตาราง "bar" และคุณต้องการส่วนแทรกนี้จากตาราง "foo" ของคุณ จากนั้นทั้งหมดจะต้องได้รับการประมวลผลด้วยสคริปต์ และคุณต้องรอข้อมูลของคุณ นี่เป็นเรื่องปกติและวิธีการทำงานเช่นนี้ คุณสามารถเพิ่มความเร็วได้โดยใช้ตัวเลือกการกำหนดค่า นอกจากนี้ หากสคริปต์ขัดข้อง คุณจะต้องบันทึกตำแหน่งแบบฟอร์ม 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 เริ่มต้นจะสร้างสตรีมขนาดใหญ่หนึ่งหยดซึ่งต้องใช้ 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] เพื่อแบ่งออกเป็นชิ้นเล็กๆ