ProxySQL - أداة لإزالة تعدد الإرسال للاتصالات

مرحبًا ، اسمي ألكسندر ياكوفليف ، أعمل لدى Citimobil وأعمل. اليوم سوف أخبركم عن منتج ProxySQL المثير للاهتمام للغاية - إنه وكيل MySQL عالي الأداء يمكنه القيام بالكثير من الأشياء - التقاط الطلبات وإنقاصها عن طريق القناع ، حيث يمكنك البحث عن حقن sql ، وتكرار الحمل وأكثر من ذلك بكثير. سأتحدث عن تجربتنا معه.
عاجلاً أم آجلاً ، سيواجه أي مشروع كبير لتكنولوجيا المعلومات ، بدأ تطويره باستخدام زوج من الخوادم ، الحالة الموضحة أدناه. تخيل أن المشروع كان يحتوي في البداية على قاعدة بيانات واحدة فقط - الخادم الرئيسي. تدريجيا ، تم إضافة حفنة من العبيد إليها. ثم أدخلوا التقسيم.

ويوم واحد جيد ، يزداد الحمل فجأة 10 مرات. على سبيل المثال ، لأن منافسك الرئيسي سقط ، وهرع العملاء إليك. في هذه المرحلة ، يبدو لك أنه يمكنك ببساطة زيادة الحمل بإضافة خوادم الويب. ولكن بعد القيام بذلك ، تنشأ حالة غير سارة.

خذ بعين الاعتبار مثال معالج واحد. لنفترض أن لديك 50 خادم ويب وفي كل 200 عملية php-fpm. ثم ستصل 50 * 200 وصلة إلى السيد ، وعندها سيصل 50 * 200 / عدد العبيد إلى كل عبد (إذا ، بالطبع ، تم تكوين Roundrobin في haproxy) - انظر الصورة أدناه. بالطبع ، هناك 10 آلاف اتصال بالسيد كثيرًا ، لكنها لا تزال محتملة ، وإذا كان هناك 200 موقع ويب ، فسيكون عدد الاتصالات أكثر ، واتصال واحد = خيط واحد.
لقد واجهنا هذا الاختناق.

صورة

ثم بدأنا في المجادلة: يتم تثبيت الاتصال بالمعالج دائمًا في التعليمات البرمجية ، ولكن هل هو ضروري لجميع عمليات fpm؟ على الاغلب لا. لاحظنا أن عددًا كبيرًا من الاتصالات المستمرة بالسيد يتعطل ببساطة في الزلات. وقرروا أننا بحاجة إلى إزالة التعددية.

صورة

للقيام بذلك ، لفتنا الانتباه إلى منتج يسمى ProxySQL. يعمل مثل الوكيل العكسي العادي: يتم إنشاء الاتصالات إليه ، ويعيد توزيع حركة المرور وفقًا لقواعد معينة محددة في التكوين.

لقد قمنا بتثبيت ProxySQL على جميع خوادم الويب لدينا ، وفي تكوين التطبيق ، حددنا أن الاستدعاء لقاعدة البيانات الرئيسية يتم إجراؤه على العنوان 127.0.0.1. إذا كان ما قبل 200 عاملاً من موظفي FPM على كل خادم ويب يعني 200 اتصال بالقاعدة الرئيسية من هذا الجهاز ، فقد تغير الوضع الآن. تأتي هذه الاتصالات الـ 200 في ProxySQL ، ويخرج 50-70 في أوقات مختلفة. أي أنه يمكن لـ ProxySQL إعادة استخدام الاتصالات الموجودة.

بفضل demultiplexing ، قللنا عدد الاتصالات بمقدار 3-10 مرات على جميع الأساتذة ، انظر الرسم البياني الحالي للاتصالات لأحد الأساتذة أدناه.

صورة

بفضل ProxySQL ، تخلصنا من عنق الزجاجة أعلاه. لكن هذا ليس سير العمل الوحيد الذي قمنا بتحسينه باستخدام هذه الأداة.
لم نكمل العملية الثانية بعد ، ولكننا على وشك الانتهاء. باستخدام ProxySQL ، نخطط لتكرار الحمل الحقيقي في بيئة الاختبار. هذا ضروري للتحقق من الميزات الجديدة مع حركة المرور القتالية.

كيف سيتم تنفيذ ذلك؟ ينتقل التطبيق إلى ProxySQL ، ويرسل حركة المرور على مسارين: إلى قواعد بيانات المعارك لكي يعمل التطبيق ، وإلى بيئة الاختبار للتحقق من الميزات الجديدة تحت التحميل.

ميزة ProxySQL هي أن هناك تكوينها ، والذي في حالتنا يتم طرحه من خلال دمية (بالنسبة للعرائس هناك وحدة ProxySQL) ، ولكن هناك أيضًا مفهوم منطقة وقت التشغيل ، من أجل إجراء تغيير (إضافة خادم ، إضافة مستخدم ، حذف الخادم والمستخدم ) ، لست بحاجة إلى إعادة التشغيل / إعادة التحميل المعتادة. ، يتم كل شيء من خلال وحدة تحكم ProxySQL ، على سبيل المثال مثل هذا.

mysql -ulogin -ppassword -h 127.0.0.1 -P6032 -e "INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('sm_username','pass',1);;LOAD MYSQL USERS TO RUNTIME;SAVE MYSQL USERS TO DISK;"

بمزيد من التفصيل ، بالطبع ، في الوثائق الرسمية بالبروكسي الوكيل / التوثيق

شكرا لكم على اهتمامكم.

التكوين الخاص بنا ، الذي قمنا بحل المشكلة الموصوفة أعلاه ، انظر أدناه.

التكوين لدينا

datadir="/var/lib/proxysql"

admin_variables=
{
    admin_credentials="user:pass"
    mysql_ifaces="0.0.0.0:6032"
    refresh_interval=2000
    web_enabled=true
    web_port=6080
    stats_credentials="stats:admin"
}

mysql_variables =
{
    threads = 1000
    max_connections = 2000
    default_query_delay= 0
    default_query_timeout=1
    have_compress=true
    poll_timeout=2000
    interfaces="0.0.0.0:6033;/tmp/proxysql.sock"
    default_schema="information_schema"
    stacksize=1048576
    server_version="5.7.22"
    connect_timeout_server=10000
    monitor_history=60000
    monitor_connect_interval=200000
    monitor_ping_interval=200000
    ping_interval_server_msec=5000
    ping_timeout_server=200
    commands_stats=true
    sessions_sort=true
    monitor_username="root"
    monitor_password="password"
    monitor_galera_healthcheck_interval=200
    monitor_galera_healthcheck_timeout=80
}

mysql_servers =
(
  {
    address = "ip_real_mysql_server",
    port = 3306,
    max_connections = 10000,
    host_group = 1,
  })
mysql_users =
(
  {
    username = "user",
    password = "pass",
    default_hostgroup = 1,
    transaction_persistent = 0,
    active = 1,
  })

All Articles