ProxySQL چیست
در دنیای پایگاه داده ، بسیار مهم است که پایگاه داده ها همیشه با عملکرد بالا در دسترس باشند. هنگامی که یک برنامه یا پایگاه داده جدیدی بالا می آید ،در ابتدا شرایط مناسب است ولی با افزایش میزان ترافیک ، کانکشن ها و داده ها ، زمان پاسخ افزایش می یابد. اکنون چالش برای هر DBA افزایش مقیاس یا scale دیتابیس است.
DBA ها دو برده (slave) اضافه کرده و ترافیک read را به slaves هدایت کرده و زمان پاسخ را کاهش میدهند. چالش بعدی مسیریابی ترافیک هنگام تأخیر در تکثیر یا خرابی سرور است؟ مسیریابی به صورت دستی هنوز هم می تواند تأثیر بدی بر زیرساخت داشته باشد. ProxySQL می تواند چنین چالش هایی را برطرف کند.
برای یادگیری maxsclae میتوانید از لینک زیر استفاده کنید
Load Balancer چیست؟
قبل از دانستن اطلاعات بیشتر در مورد ProxySQL ، بیایید یاد بگیریم LB (Load Balancer) چیست. برای ساده بودن ، Load balancer در شبکه ، ترافیک برنامه را بین سرورهای موجود توزیع می کند. این امر با افزایش کاربران همزمان و بهبود کارایی استفاده از سخت افزار ، به دستیابی به بازده ، قابلیت اطمینان ، در دسترس بودن و عملکرد بهتر برنامه ها کمک می کند.
دو نوع LB وجود دارد ، LB های سخت افزاری و نرم افزاری.LB سخت افزار دارای یک جز نرم افزاری است که بسته را پردازش می کند. LB نرم افزاری شامل یک کامپوننت سرور بر روی شبکه و با ترکیبی از یک یا چند الگوریتم زمان بندی است. LB نیز در صورت تغییر آدرس IP دیتابیس پیچیدگی را در سطح برنامه کاهش می دهد.
ProxySQL چیست؟
ProxySQL یکی از بالانس کننده بار نرم افزاری پیشرفته ای است . ProxySQL توانایی داخلی برای شناسایی خواندن ، نوشتن و مسیریابی ترافیک نوشتن برای تسلط بر خواندن ترافیک بین slave های موجود را دارد. در صورت بروز تأخیر در Replication یا خرابی سرور یا شکست در replication ، ترافیک خواندن به طور خودکار به سرورهای مختلف slave هدایت می شود.
ProxySQL ترافیک ورودی از یک برنامه را می پذیرد و آن را برای پشتیبان گیری از سرورهای MySQL / MariaDB / Percona به جلو هدایت می کند. در صورت بروز هرگونه خرابی در گره ها (سرورها) ، ProxySQL این مسئله را درک کرده و ترافیک را به یک گره دیگر که بسیار در دسترس است هدایت می کند. بنابراین ProxySQL اطمینان می دهد که هیچ نقطه ای از خرابی وجود ندارد. این برنامه از آنجا که ترافیک سرور خراب شده توسط ProxySQL به گره دیگری هدایت می شود ، به کار خود ادامه می دهد. با استفاده از یک الگوریتم مناسب تعادل بار ، به حفظ استفاده بهینه و کارآمد از منابع کمک می کند.
این برنامه برای پخش بار میان پایگاهدادهها استفاده میشود. قابلیت اصلی این پراکسی جدا کردن write و read است. هدف از این کار افزایش تعداد درخواستهای قابل پردازش است. برای این کار درخواستهای write فقط به یک پایگاهداده ارسال میشود و درخواستهای read بین پایگاهدادههای دیگر ارسال میشود. این پراکسی میتواند مقابل کلاسترهای master-slave و گلرا قرار بگیرد.
نصب ProxySql
فرض نصب روی سیستم عامل دبیان 10 می باشد
بدین منظور رپازیتوری را اضافه و پکیج proxysql را نصب میکنیم.
apt-get install -y lsb-release apt-transport-https wget -O - 'https://repo.proxysql.com/ProxySQL/repo_pub_key' | apt-key add - echo deb https://repo.proxysql.com/ProxySQL/proxysql-2.0.x/$(lsb_release -sc)/ ./ \ | tee /etc/apt/sources.list.d/proxysql.list apt-get update apt-get install proxysql
امکان نصب از طریق فایل .deb نیز وجود دارد. فایل باید از ریپو گیت دانلود شود.
برای ورود اولیه به این ابزار از این دستور استفاده میکنیم.
service proxysql start mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt='Admin> '
در صورتی که فایل کانفیگ را ایجاد کرده باشیم میتوانیم فرایند کانفیگ را از روی آن انجام دهیم:
service proxysql-initial start
پیکربندی ProxySql و Galera Cluster
از ورژن ۲ ProxySQL به بعد galera مستقیما پشتیبانی میشود.
پارامترهای مربوط به mysql_galera_hostgroups به شرح زیر میباشد:
-
writer_hostgroup: مشخص کردن id گروهی که وظیفه نوشتن را دارد.
-
backup_writer_hostgroup: اگر تعداد نویسندهها بیشتر از یکی باشد و تعداد آنها از max_writers بیشتر باشد سایر نودها در این دسته قرار میگیرند.
-
reader_hostgroup: گروهی که وظیفه پذیرش پرسوجوهای مربوط به خواندن را دارند. در این گروه read_only=1 است.
-
offline_hostgroup: اگر پراکسی متوجه شود نودی غیر فعال شده است آن را در این گروه قرار میدهد.
-
active: فقط ۲ مقدار ۰ و ۱ میگیرد. در صورت فعال شدن یک نود پراکسی آن را در گروه مربوط به آن قرار میدهد.
-
max_writers: تعداد نودهایی که حق نوشتن دارند را مشخص میکند. اگر تعداد نودهای نویسنده بیشتر از این مقدار باشد، آنها را در گروه نویسندگان بکاپ قرار میدهد.
-
writer_is_also_reader: فقط ۲ مقدار ۱و۰ میگیرد. میتوان بیان کرد که نودی که در گروه نویسندگان قرار دارد در گروه خوانندگان نیز باشد.
-
max_transactions_behind:مشخص میکند یک نود چقدر میتواند از سایر نودهای گلرا عقب باشد. در صورتی که یک نود تعداد زیادتری از این مقدار عقب باشد پرسوجوهای مربوط به خواندن به آن ارسال نمیشود. (برای هر نود به وسیله خواندن متغیر wsrep_local_recv_queue از گلرا بدست میآید)
پیکربندی مربوط به پراکسی sql
با فرض این که کلاستر گلرا به آدرسهای 192.168.207.35، 192.168.207.36 و 192.168.207.37 موجود است شروع به پیکربندی میکنیم.
ورود به پنل proxysql:
mysql -P6032 -uadmin -padmin -h 127.0.0.1
پس از ورود باید نودها را به پراکسی معرفی کنیم. نود با کمترین وزن به گروه نویسندگان بکاپ منتقل میشود:
add writer nodes > INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight) VALUES (2,'192.168.207.35',3360,100); INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight) VALUES (2,'192.168.207.36',3360,100); add reader nodes > INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight) VALUES (3,'192.168.207.35',3360,100); INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight) VALUES (3,'192.168.207.36',3360,100); INSERT INTO mysql_servers(hostgroup_id,hostname,port,weight) VALUES (3,'192.168.207.37',3360,100);
سپس باید گروهها را به دسته mysql_galera_hostgroups اضافه کنیم. همچنین باید رفتار کلاستر را در برابر پرس و جوها مشحص کنیم. max_writers=1 قرار میدهیم تا فقط یک نویسنده داشته باشیم. برای اینک نود نویسنده پرسوجوهای مربوط به خواندن را انجام ندهد writer_is_also_reader=1 قرار میدهیم:
writer_hostgroup=2, backup_writer_hostgroup=4, reader_hostgroup=3, max_writers=1, writer_is_also_reader=1
create mysql_galera_hostgroups > INSERT INTO mysql_galera_hostgroups (writer_hostgroup,backup_writer_hostgroup,reader_hostgroup,offline_hostgroup,active,max_writers,writer_is_also_reader,max_transactions_behind) VALUES (2,4,3,1,1,1,1,100);
پس از این ۲ مرحله برای ذخیره شدن تنظیمات باید دستورات زیر را وارد کنید:
save to runtime > LOAD MYSQL SERVERS TO RUNTIME; save to disk > SAVE MYSQL SERVERS TO DISK;
بررسی صحت تنظیمات وارد شده:
select * from mysql_servers; +--------------+----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | hostgroup_id | hostname | port | gtid_port | status | weight | compression | max_connections | max_replication_lag | use_ssl | max_latency_ms | comment | +--------------+----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ | 2 | 192.168.207.35 | 3360 | 0 | ONLINE | 100 | 0 | 1000 | 0 | 0 | 0 | | | 2 | 192.168.207.36 | 3360 | 0 | ONLINE | 100 | 0 | 1000 | 0 | 0 | 0 | | | 3 | 192.168.207.35 | 3360 | 0 | ONLINE | 100 | 0 | 1000 | 0 | 0 | 0 | | | 3 | 192.168.207.36 | 3360 | 0 | ONLINE | 100 | 0 | 1000 | 0 | 0 | 0 | | | 3 | 192.168.207.37 | 3360 | 0 | ONLINE | 100 | 0 | 1000 | 0 | 0 | 0 | | +--------------+----------------+------+-----------+--------+--------+-------------+-----------------+---------------------+---------+----------------+---------+ mysql> select * from mysql_galera_hostgroups; +------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+ | writer_hostgroup | backup_writer_hostgroup | reader_hostgroup | offline_hostgroup | active | max_writers | writer_is_also_reader | max_transactions_behind | comment | +------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+ | 2 | 4 | 3 | 1 | 1 | 1 | 1 | 100 | NULL | +------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+---------+
در مرحله بعد باید قوانین جداسازی پرسوجوها بر اساس نوشتن و خواندن را ایجاد کنیم:
add query rule for read/write split: > INSERT INTO mysql_query_rules (active, match_digest, destination_hostgroup, apply) VALUES (1, '^SELECT.*',3, 1); > INSERT INTO mysql_query_rules (active, match_digest, destination_hostgroup, apply) VALUES (1, '^SELECT.* FOR UPDATE',2, 1); > INSERT INTO mysql_query_rules (active, match_digest, destination_hostgroup, apply) VALUES (1, '.*',2, 1); > LOAD MYSQL QUERY RULES TO RUNTIME; > SAVE MYSQL QUERY RULES TO DISK;
تغییر پسورد admin:
change admin password > SET admin-admin_credentials = 'admin:newpass';
LOAD ADMIN VARIABLES TO RUNTIME;
SAVE ADMIN VARIABLES TO DISK;
تغییر interfaceهایی که برنامهها به آن متصل میشوند:
change port > set mysql-interfaces = "0.0.0.0:4006";
SAVE MYSQL VARIABLES TO DISK;
service proxysql restart
تغییر کاربر monitor:
change monitor user and password > set mysql-monitor_username = "monitoring";
> set mysql-monitor_password = "pass";
> LOAD MYSQL VARIABLES TO RUNTIME;
> SAVE MYSQL VARIABLES TO DISK;
این کاربر باید در پایگاهدادهها هم ایجاد شود تا وضعیت کلاستر را مورد بررسی قرار دهد:
CREATE USER 'monitoring'@'%' IDENTIFIED BY 'pass'; GRANT SELECT on sys.* to 'monitoring'@'%';
امکان دارد سطح دسترسیهایی که در بخش بالا درنظر گرفته شده باشد ناکافی باشد.(کمبود داک) برای حل این مشکل میتوان دسترسی بیشتری به آن داد.
هر کاربری ک بخواهد از proxysql استفاده کند باید غیر از پایگاه در خود proxysql هم ثبت شده باشد.
add zabbix user > INSERT INTO mysql_users(username,password) VALUES ('zabbix_user','PASSWORD'); > LOAD MYSQL USERS TO RUNTIME; > SAVE MYSQL USERS TO DISK;
تغییر در تنظیمات بدون قطعی
در proxysql برای تغییر در تنظیمات باید از دستورات sql برای تغییر در تنظیمات استفاده کرد.
show tables; +----------------------------------------------------+ | tables | +----------------------------------------------------+ | global_variables | | mysql_aws_aurora_hostgroups | | mysql_collations | | mysql_firewall_whitelist_rules | | mysql_firewall_whitelist_sqli_fingerprints | | mysql_firewall_whitelist_users | | mysql_galera_hostgroups | | mysql_group_replication_hostgroups | | mysql_query_rules | | mysql_query_rules_fast_routing | | mysql_replication_hostgroups | | mysql_servers | | mysql_users | | proxysql_servers | | restapi_routes | | runtime_checksums_values | | runtime_global_variables | | runtime_mysql_aws_aurora_hostgroups | | runtime_mysql_firewall_whitelist_rules | | runtime_mysql_firewall_whitelist_sqli_fingerprints | | runtime_mysql_firewall_whitelist_users | | runtime_mysql_galera_hostgroups | | runtime_mysql_group_replication_hostgroups | | runtime_mysql_query_rules | | runtime_mysql_query_rules_fast_routing | | runtime_mysql_replication_hostgroups | | runtime_mysql_servers | | runtime_mysql_users | | runtime_proxysql_servers | | runtime_restapi_routes | | runtime_scheduler | | scheduler | +----------------------------------------------------+
در جداول بالا تنظیمات را در جدولهایی که مربوط به runtime نیستند وارد میکنیم. سپس با دستور load و save به ترتیب تنظیمات را روی runtime و disk ذخیره میکنیم.
ساختار ذخیره سازی تنضیمات در proxysql به صورت زیر است:
پس از پایان تنظیمات میتوان وضعیت کلی سرورها از پراکسی جویا شد:
select * from mysql_server_galera_log order by time_start_us desc limit 3; +----------------+------+------------------+-----------------+-------------------+-----------+------------------------+-------------------+--------------+----------------------+---------------------------------+----------------+-------+ | hostname | port | time_start_us | success_time_us | primary_partition | read_only | wsrep_local_recv_queue | wsrep_local_state | wsrep_desync | wsrep_reject_queries | wsrep_sst_donor_rejects_queries | pxc_maint_mode | error | +----------------+------+------------------+-----------------+-------------------+-----------+------------------------+-------------------+--------------+----------------------+---------------------------------+----------------+-------+ | 192.168.207.37 | 3360 | 1596622329840835 | 3568 | YES | NO | 0 | 4 | NO | NO | NO | NO | NULL | | 192.168.207.36 | 3360 | 1596622329834547 | 3665 | YES | NO | 0 | 4 | NO | NO | NO | NO | NULL | | 192.168.207.35 | 3360 | 1596622329831493 | 9064 | YES | NO | 0 | 4 | NO | NO | NO | NO | NULL | +----------------+------+------------------+-----------------+-------------------+-----------+------------------------+-------------------+--------------+----------------------+---------------------------------+----------------+-------+
برای بررسی وضعیت پرسوجوهای ارسالی میتوان از دستورهای زیر استفاده کرد:
mysql> select hostgroup,srv_host,status,ConnUsed,MaxConnUsed,Queries,Latency_us from stats.stats_mysql_connection_pool order by srv_host;
+-----------+----------------+---------+----------+-------------+----------+------------+
| hostgroup | srv_host | status | ConnUsed | MaxConnUsed | Queries | Latency_us |
+-----------+----------------+---------+----------+-------------+----------+------------+
| 2 | 192.168.207.35 | SHUNNED | 0 | 85 | 31894 | 647 |
| 3 | 192.168.207.35 | ONLINE | 0 | 4 | 178634 | 647 |
| 4 | 192.168.207.35 | ONLINE | 0 | 0 | 0 | 647 |
| 2 | 192.168.207.36 | SHUNNED | 0 | 936 | 23387827 | 509 |
| 3 | 192.168.207.36 | ONLINE | 0 | 3 | 171814 | 509 |
| 4 | 192.168.207.36 | ONLINE | 0 | 0 | 0 | 509 |
| 2 | 192.168.207.37 | ONLINE | 0 | 16 | 122069 | 819 |
| 3 | 192.168.207.37 | ONLINE | 0 | 3 | 84405 | 819 |
+-----------+----------------+---------+----------+-------------+----------+------------+
مشاهده وضعیت کلی proxysql
select * from stats_mysql_connection_pool; +-----------+----------------+----------+---------+----------+----------+--------+---------+-------------+---------+-------------------+-----------------+-----------------+------------+ | hostgroup | srv_host | srv_port | status | ConnUsed | ConnFree | ConnOK | ConnERR | MaxConnUsed | Queries | Queries_GTID_sync | Bytes_data_sent | Bytes_data_recv | Latency_us | +-----------+----------------+----------+---------+----------+----------+--------+---------+-------------+---------+-------------------+-----------------+-----------------+------------+ | 2 | 192.168.207.37 | 3360 | ONLINE | 0 | 17 | 17 | 0 | 17 | 10675 | 0 | 1811061 | 15524 | 944 | | 2 | 192.168.207.36 | 3360 | SHUNNED | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 459 | | 2 | 192.168.207.35 | 3360 | SHUNNED | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 915 | | 3 | 192.168.207.37 | 3360 | ONLINE | 0 | 10 | 10 | 0 | 10 | 5619 | 0 | 1344154 | 40544106 | 944 | | 3 | 192.168.207.36 | 3360 | ONLINE | 0 | 6 | 6 | 0 | 6 | 5489 | 0 | 1327736 | 39501124 | 459 | | 3 | 192.168.207.35 | 3360 | ONLINE | 0 | 8 | 8 | 0 | 8 | 5769 | 0 | 1400080 | 40226115 | 915 | | 4 | 192.168.207.36 | 3360 | ONLINE | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 459 | | 4 | 192.168.207.35 | 3360 | ONLINE | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 915 | +-----------+----------------+----------+---------+----------+----------+--------+---------+-------------+---------+-------------------+-----------------+-----------------+------------+
کلاستر ProxySQL
با توجه به اینک تنظیمات باید در تمام نودها یکسان باشد و همانطور که گفته شد نحوه ذخیرهسازی تنظمیات در proxysql با سایر برنامهها متفاوت است، امکان استفاده از rsync و ریست برنامه نیست. برای حل این چالش روشی برای کلاستر کردن تنظیمات ارايه شده است. در این روش نودها در جدول proxysql_servers اضافه میشوند. پس از لود کردن تنظیمات در حافظه نودی که در آن تغییرات قرار داده شده است به سایر نودها خبر میدهد که تنظیمات دچار تغییر شدهاند سپس سایر نودها تنظیمات را از نودی که تغییر در آن ایجاد شده میگیرند.
باید اول کلاستر ایجاد شود سپس سایر تنظیمات وارد شوند.
در کلاستر مستر و اسلیو وجود ندارد و هر نودی که دستور load را بزند میتواند تنظیمات را تغییر دهد.
در هنگام اضافه کردن نود جدید به کلاستر فعلی نباید تنظیماتی غیر از تنظیمات کلاستر باشد به این صورت نود خود را با سایر نودها sync میکند.
نمونه تنظیمات فایل proxysql.conf در زیر آمده است:
datadir="/var/lib/proxysql"
admin_variables =
{
admin_credentials="admin:pass;cluster:pass;admin:admin"
mysql_ifaces="0.0.0.0:6032"
cluster_username="cluster"
cluster_password="pass"
cluster_check_interval_ms=200
cluster_check_status_frequency=100
cluster_mysql_query_rules_save_to_disk=true
cluster_mysql_servers_save_to_disk=true
cluster_mysql_users_save_to_disk=true
cluster_proxysql_servers_save_to_disk=true
cluster_mysql_query_rules_diffs_before_sync=3
cluster_mysql_servers_diffs_before_sync=3
cluster_mysql_users_diffs_before_sync=3
cluster_proxysql_servers_diffs_before_sync=3
}
proxysql_servers =
(
{
hostname="SERVER1"
port=6032
comment="proxysql1"
},
{
hostname="SERVER2"
port=6032
comment="proxysql2"
}
)
تنظیمات میتوانند خارج از خط فرمان باشند
set admin-cluster_username > set admin-cluster_username = "myCluster1"; set admin-cluster_password > set admin-cluster_password = "yumyumCluster"; updating admin_credentials > SET admin-admin_credentials = 'admin:admin;myCluster1:yumyumCluster'; save changes > LOAD ADMIN VARIABLES TO RUNTIME; SAVE ADMIN VARIABLES TO DISK;
در صورتی که بخواهیم نودی به کلاستر اضافه کنیم در نودهای موجود به صورت زیر اقدام میکنیم:
INSERT INTO proxysql_servers (hostname,port) VALUES ('192.168.207.110','6032'); LOAD PROXYSQL SERVERS TO RUNTIME; SAVE PROXYSQL SERVERS TO DISK;
معمولا در تمام دستورات load دادهها سینک میشوند. این نکته در تمام موارد صادق نیست. در مورد ADMIN VARIABLES و MYSQL VARIABLES درست نیست به همین دلیل این موارد بصورت دستی و یا در فایل تنظیمات قرار میگیرند.
LOAD MYSQL QUERY RULES TO RUNTIME: generates a new checksum if admin-checksum_mysql_query_rules is true LOAD MYSQL SERVERS TO RUNTIME: generates a new checksum if admin-checksum_mysql_servers is true LOAD MYSQL USERS TO RUNTIME: generates a new checksum if admin-checksum_mysql_users is true LOAD PROXYSQL SERVERS TO RUNTIME: generates a new checksum, always LOAD ADMIN VARIABLES TO RUNTIME: does NOT generate a checksum yet LOAD MYSQL VARIABLES TO RUNTIME: does NOT generate a checksum yet
ProxySQL Caching
برای بهبود کارایی proxysql میتوان کوئریها را کش کرد. برای اینکار باید اول از جدول stats_mysql_query_digest کوئریهایی که برای کش کردن مناسب هستند پیدا کنیم. برای اینکار میتوانیم کوئریها را بر اساس تعداد بار اجرا یا مجموع زمان اجرا مرتب کنیم.
select * from stats_mysql_query_digest order by count_star DESC limit 5\G SELECT * FROM stats_mysql_query_digest ORDER BY sum_time DESC\G
سپس باید فیلد مربوط به ستون digest را استخراج کنیم و آن را در جدول mysql_query_rules اضافه کنیم.
INSERT INTO mysql_query_rules(active, digest, cache_ttl, apply) VALUES(1,'0x2F6029D9E19D4643',2000,1); LOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;
نمایش تعداد اجرای هر رول
select * from stats_mysql_query_rules;
برای یادگیری maxsclae میتوانید از لینک زیر استفاده کنید
امیدوارم مفید بوده باشه
یا حق