Implementasi PHP Murni dari protokol replikasi MySQL. Ini memungkinkan Anda menerima acara seperti menyisipkan, memperbarui, menghapus dengan datanya dan kueri SQL mentah.
Berdasarkan karya hebat pencipta:https://github.com/noplay/python-mysql-replication dan https://github.com/fengxiangyun/mysql-replication
Dalam proyek Anda
composer require krowinski/php-mysql-replication
atau mandiri
git clone https://github.com/krowinski/php-mysql-replication.git
composer install -o
PHP
MYSQL
Di file konfigurasi server MySQL Anda, Anda perlu mengaktifkan replikasi:
[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
Peristiwa replikasi Mysql dijelaskan https://dev.mysql.com/doc/internals/en/event-meanings.html
Hak istimewa pengguna MySQL:
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'user'@'host';
GRANT SELECT ON `dbName`.* TO 'user'@'host';
Gunakan ConfigBuilder atau ConfigFactory untuk membuat konfigurasi. Opsi yang tersedia:
'pengguna' - pengguna mysql Anda (wajib)
'ip' atau 'host' - host/ip mysql Anda (wajib)
'kata sandi' - kata sandi mysql Anda (wajib)
'port' - port host mysql Anda (default 3306)
'charset' - rangkaian karakter koneksi db (utf8 default)
'gtid' - Penanda GTID untuk memulai (format 9b1c8d18-2a76-11e5-a26b-000c2976f3f3:1-177592)
'mariaDbGtid' - Penanda MariaDB GTID untuk memulai (format 1-1-3,0-1-88)
'slaveId' - id budak skrip untuk identifikasi (default: 666) (TAMPILKAN HOST BUDAK)
'binLogFileName' - nama file bin log untuk memulai
'binLogPosition' - posisi bin log untuk memulai
'eventsOnly' - array untuk mendengarkan acara (daftar lengkap di file ConstEventType.php)
'eventsIgnore' - array untuk mengabaikan acara (daftar lengkap di file ConstEventType.php)
'tablesOnly' - array untuk hanya mendengarkan pada tabel tertentu (default semua tabel)
'databasesOnly' - array untuk hanya mendengarkan database tertentu (default semua database)
'tableCacheSize' - beberapa data dikumpulkan dari skema informasi, data ini di-cache.
'custom' - jika beberapa parameter harus disetel di kelas yang diperluas/diimplementasikan sendiri
'heartbeatPeriod' - mengatur interval dalam hitungan detik antara detak jantung replikasi. Setiap kali log biner master diperbarui dengan suatu peristiwa, masa tunggu untuk detak jantung berikutnya diatur ulang. interval adalah nilai desimal yang memiliki rentang 0 hingga 4294967 detik dan resolusi dalam milidetik; nilai bukan nol terkecil adalah 0,001. Detak jantung dikirim oleh master hanya jika tidak ada peristiwa yang belum terkirim dalam file log biner untuk jangka waktu lebih lama dari interval.
'saveUuid' - menetapkan uuid budak untuk identifikasi (default: 0015d2b6-8a06-4e5e-8c07-206ef3fbd274)
Rubi: https://github.com/y310/kodama
Jawa: https://github.com/shyiko/mysql-binlog-connector-java
PERGI: https://github.com/siddontang/go-mysql
Python: https://github.com/noplay/python-mysql-replication
.NET: https://github.com/rusuly/MySqlCdc
Semua contoh tersedia di direktori contoh
Contoh ini akan membuang semua kejadian replikasi ke konsol:
Ingatlah untuk mengubah konfigurasi untuk pengguna, host, dan kata sandi Anda.
Pengguna harus memiliki hak replikasi [KLIEN REPLIKASI, PILIH]
php example/dump_events.php
Untuk acara pengujian 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 ;
Outputnya akan serupa dengan ini (tergantung konfigurasi misalnya GTID mati/hidup):
=== 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
Diuji pada 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)
Pertama-tama MYSQL tidak memberi Anda panggilan async. Anda biasanya perlu memprogram ini dalam aplikasi Anda (dengan mengirimkan acara dan menambahkan ke beberapa sistem antrian dan jika db Anda memiliki banyak titik masuk seperti web, backend layanan mikro lainnya tidak selalu murah untuk menambahkan pemrosesan ke semuanya. Tetapi menggunakan replikasi mysql protokol Anda dapat mendengarkan acara tulis dan memprosesnya secara asinkron (kombinasi terbaik adalah menambahkan item ke beberapa sistem antrian seperti kelincimq, redis atau kafka). Juga dalam cache yang tidak valid, replikasi mesin pencari, analisis dan audit waktu nyata.
Pertama-tama Anda perlu tahu bahwa banyak peristiwa yang mungkin terjadi, seperti jika Anda memperbarui 1.000.000 catatan di tabel "bar" dan Anda memerlukan sisipan ini dari tabel "foo" Anda, maka semua harus diproses dengan skrip, dan Anda harus menunggu data Anda. Ini normal dan beginilah cara kerjanya. Anda dapat mempercepat menggunakan opsi konfigurasi. Selain itu, jika skrip mogok, Anda perlu menyimpan posisi dari binlog (atau gtid) dari waktu ke waktu untuk memulai dari posisi ini ketika Anda menjalankan skrip ini lagi untuk menghindari duplikat.
Seperti yang saya sebutkan dalam 1 poin, gunakan sistem antrian seperti Rabbitmq, Redis atau Kafka, mereka akan memberi Anda kemampuan untuk memproses data dalam banyak skrip.
Buat masalah, saya akan mencoba mengatasinya di waktu luang saya :)
Ini berfungsi seperti MYSQL lainnya dalam mode budak dan memberikan overhead yang sama.
Untuk mengatasinya yang terbaik adalah dengan meningkatkan konfigurasi db net_read_timeout
dan net_write_timeout
menjadi 3600. (tx Bijimon)
Atur di my.conf binlog_row_image=full
untuk memperbaiki hanya menerima pembaruan sebagian.
Atur di my.conf log_slave_updates=on
untuk memperbaikinya (#71)(#66)
Pengaturan default MYSQL menghasilkan satu gumpalan aliran besar yang memerlukan lebih banyak RAM/CPU. Anda dapat mengubahnya untuk aliran yang lebih kecil menggunakan variabel 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] untuk dipecah menjadi beberapa bagian yang lebih kecil