تنفيذ PHP خالص لبروتوكول النسخ المتماثل MySQL. يتيح لك ذلك تلقي أحداث مثل الإدراج والتحديث والحذف باستخدام البيانات واستعلامات 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 الخاص بك، تحتاج إلى تمكين النسخ المتماثل:
[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" - مضيف/ip mysql الخاص بك (إلزامي)
"كلمة المرور" - كلمة مرور 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) (إظهار مضيفي الرقيق)
"binLogFileName" - اسم ملف سجل الحاوية للبدء منه
'binLogPosition' - موضع سجل الحاوية للبدء منه
'eventsOnly' - مصفوفة للاستماع إلى الأحداث (القائمة الكاملة في ملف ConstEventType.php)
'eventsIgnore' - مصفوفة لتجاهل الأحداث (القائمة الكاملة في ملف ConstEventType.php)
'tablesOnly' - مصفوفة للاستماع فقط إلى جداول محددة (جميع الجداول افتراضيًا)
'databasesOnly' - مصفوفة للاستماع فقط إلى قواعد بيانات معينة (جميع قواعد البيانات افتراضيًا)
'tableCacheSize' - يتم جمع بعض البيانات من مخطط المعلومات، ويتم تخزين هذه البيانات مؤقتًا.
"مخصص" - إذا كان يجب تعيين بعض المعلمات في فئات خاصة موسعة/منفذة
'heartbeatPeriod' - يضبط الفاصل الزمني بالثواني بين نبضات النسخ المتماثل. عندما يتم تحديث السجل الثنائي للسيد بحدث ما، تتم إعادة تعيين فترة الانتظار لنبضة القلب التالية. الفاصل الزمني هو قيمة عشرية يتراوح نطاقها بين 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
صافي: 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 أيضًا في إبطال ذاكرة التخزين المؤقت أو النسخ المتماثل لمحرك البحث في الوقت الفعلي). التحليلات والتدقيقات.
حسنًا، أولاً وقبل كل شيء، عليك أن تعرف أنه قد تحدث الكثير من الأحداث، مثل إذا قمت بتحديث 1000000 سجل في الجدول "bar" وتحتاج إلى هذا الإدخال من الجدول "foo" الخاص بك، فيجب معالجة كل شيء عن طريق البرنامج النصي، وتحتاج إلى انتظار البيانات الخاصة بك. هذا أمر طبيعي وهذه هي الطريقة التي يعمل بها. يمكنك تسريع استخدام خيارات التكوين. أيضًا، إذا تعطل البرنامج النصي، فأنت بحاجة إلى حفظ نموذج الموضع من وقت لآخر binlog (أو gtid) للبدء من هذا الموضع عند تشغيل هذا البرنامج النصي مرة أخرى لتجنب التكرارات.
كما ذكرت في نقطة واحدة، استخدم نظام قائمة الانتظار مثل 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 الافتراضي نقطة كبيرة واحدة من الدفق، وهذا يتطلب المزيد من ذاكرة الوصول العشوائي/وحدة المعالجة المركزية (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] للتقسيم إلى أجزاء أصغر