डेटाबेस पर जाने वाले ट्रैफ़िक को आकार देने की क्षमता सबसे महत्वपूर्ण में से एक है। पिछले दिनों में आपका उस पर इतना नियंत्रण नहीं था - एप्लिकेशन ने डेटाबेस को ट्रैफ़िक भेजा और वह इसके बारे में है। HAProxy, जिसका आमतौर पर उपयोग किया जाता था, में भी यातायात पर बारीक नियंत्रण का विकल्प नहीं होता है। SQL-जागरूक प्रॉक्सी, जैसे ProxySQL की शुरूआत के साथ, डेटाबेस व्यवस्थापकों के लिए अधिक संभावनाएं उपलब्ध हो गईं। आइए ProxySQL में कनेक्शन हैंडलिंग और थ्रॉटलिंग संभावनाओं पर एक नज़र डालें।
ProxySQL में कनेक्शन हैंडलिंग
जैसा कि आप जानते हैं, प्रॉक्सीएसक्यूएल जिस तरह से काम करता है वह क्वेरी नियमों के माध्यम से होता है। यह नियमों की एक सूची है जिसके खिलाफ प्रत्येक क्वेरी का परीक्षण किया जाता है और यह नियंत्रित करता है कि प्रॉक्सीएसक्यूएल क्वेरी को कैसे संभालेगा। शुरुआत से, एप्लिकेशन ProxySQL से जुड़ता है। यह ProxySQL के खिलाफ प्रमाणित करेगा (यही कारण है कि ProxySQL को सभी उपयोगकर्ताओं और पासवर्ड हैश को संग्रहीत करना है) और फिर ProxySQL इसे क्वेरी नियमों के माध्यम से चलाएगा ताकि यह निर्धारित किया जा सके कि क्वेरी किस होस्टग्रुप को भेजी जानी चाहिए।
ProxySQL बैकएंड सर्वर से कनेक्शन का एक पूल खोलता है। यह 1-टू-1 मैपिंग नहीं है, डिफ़ॉल्ट रूप से यह एक बैकएंड कनेक्शन को यथासंभव अधिक से अधिक फ्रंटएंड कनेक्शन के लिए पुन:उपयोग करने का प्रयास करता है। इसे कनेक्शन मल्टीप्लेक्सिंग कहा जाता है। विवरण उस सटीक ट्रैफ़िक पर निर्भर करता है जिसे उसे संभालना है। प्रत्येक खुले लेनदेन को उसी कनेक्शन के भीतर संभाला जाना चाहिए। यदि किसी प्रकार का स्थानीय चर परिभाषित है, तो इस कनेक्शन का पुन:उपयोग नहीं किया जा सकता है। एकाधिक फ्रंटएंड कनेक्शन द्वारा एकल बैकएंड कनेक्शन का पुन:उपयोग करने में सक्षम होने से बैकएंड डेटाबेस पर बोझ काफी कम हो जाता है।
एक बार ProxySQL से कनेक्शन हो जाने के बाद, जैसा कि हमने पहले बताया, इसे क्वेरी नियमों के अनुसार संसाधित किया जाएगा। यहां ट्रैफिक शेपिंग हो सकती है। आइए विकल्पों पर एक नज़र डालें
ProxySQL में कनेक्शन थ्रॉटलिंग
सबसे पहले, आइए सभी चयनों को छोड़ दें। हम अपना "एप्लिकेशन", Sysbench, निम्नलिखित तरीके से चला रहे हैं:
[email protected]:~# sysbench /root/sysbench/src/lua/oltp_read_only.lua --threads=4 --events=200 --time=0 --mysql-host=10.0.0.101 --mysql-user=sbtest --mysql-password=sbtest --mysql-port=6033 --tables=32 --report-interval=1 --skip-trx=on --table-size=100000 --db-ps-mode=disable --rate=10 run
sysbench 1.1.0-bbee5d5 (using bundled LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 4
Target transaction rate: 10/sec
Report intermediate results every 1 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!
[ 1s ] thds: 4 tps: 5.97 qps: 103.49 (r/w/o: 103.49/0.00/0.00) lat (ms,95%): 244.38 err/s: 0.00 reconn/s: 0.00
[ 1s ] queue length: 0, concurrency: 4
[ 2s ] thds: 4 tps: 13.02 qps: 181.32 (r/w/o: 181.32/0.00/0.00) lat (ms,95%): 580.02 err/s: 0.00 reconn/s: 0.00
[ 2s ] queue length: 5, concurrency: 4
[ 3s ] thds: 4 tps: 14.99 qps: 228.81 (r/w/o: 228.81/0.00/0.00) lat (ms,95%): 669.89 err/s: 0.00 reconn/s: 0.00
[ 3s ] queue length: 1, concurrency: 4
[ 4s ] thds: 4 tps: 16.99 qps: 232.88 (r/w/o: 232.88/0.00/0.00) lat (ms,95%): 350.33 err/s: 0.00 reconn/s: 0.00
[ 4s ] queue length: 0, concurrency: 3
[ 5s ] thds: 4 tps: 8.99 qps: 99.91 (r/w/o: 99.91/0.00/0.00) lat (ms,95%): 369.77 err/s: 0.00 reconn/s: 0.00
[ 5s ] queue length: 0, concurrency: 1
[ 6s ] thds: 4 tps: 3.99 qps: 55.81 (r/w/o: 55.81/0.00/0.00) lat (ms,95%): 147.61 err/s: 0.00 reconn/s: 0.00
[ 6s ] queue length: 0, concurrency: 1
[ 7s ] thds: 4 tps: 11.06 qps: 162.89 (r/w/o: 162.89/0.00/0.00) lat (ms,95%): 173.58 err/s: 0.00 reconn/s: 0.00
[ 7s ] queue length: 0, concurrency: 2
[ 8s ] thds: 4 tps: 7.99 qps: 112.88 (r/w/o: 112.88/0.00/0.00) lat (ms,95%): 200.47 err/s: 0.00 reconn/s: 0.00
[ 8s ] queue length: 0, concurrency: 2
[ 9s ] thds: 4 tps: 9.01 qps: 110.09 (r/w/o: 110.09/0.00/0.00) lat (ms,95%): 71.83 err/s: 0.00 reconn/s: 0.00
[ 9s ] queue length: 0, concurrency: 0
[ 10s ] thds: 4 tps: 9.99 qps: 143.87 (r/w/o: 143.87/0.00/0.00) lat (ms,95%): 153.02 err/s: 0.00 reconn/s: 0.00
[ 10s ] queue length: 0, concurrency: 1
[ 11s ] thds: 4 tps: 12.02 qps: 177.28 (r/w/o: 177.28/0.00/0.00) lat (ms,95%): 170.48 err/s: 0.00 reconn/s: 0.00
[ 11s ] queue length: 0, concurrency: 1
[ 12s ] thds: 4 tps: 5.00 qps: 70.95 (r/w/o: 70.95/0.00/0.00) lat (ms,95%): 231.53 err/s: 0.00 reconn/s: 0.00
[ 12s ] queue length: 0, concurrency: 2
[ 13s ] thds: 4 tps: 10.00 qps: 137.01 (r/w/o: 137.01/0.00/0.00) lat (ms,95%): 223.34 err/s: 0.00 reconn/s: 0.00
[ 13s ] queue length: 0, concurrency: 1
[ 14s ] thds: 4 tps: 11.01 qps: 143.14 (r/w/o: 143.14/0.00/0.00) lat (ms,95%): 130.13 err/s: 0.00 reconn/s: 0.00
[ 14s ] queue length: 0, concurrency: 0
[ 15s ] thds: 4 tps: 5.00 qps: 100.99 (r/w/o: 100.99/0.00/0.00) lat (ms,95%): 297.92 err/s: 0.00 reconn/s: 0.00
[ 15s ] queue length: 0, concurrency: 4
[ 16s ] thds: 4 tps: 10.98 qps: 122.82 (r/w/o: 122.82/0.00/0.00) lat (ms,95%): 344.08 err/s: 0.00 reconn/s: 0.00
[ 16s ] queue length: 0, concurrency: 0
[ 17s ] thds: 4 tps: 3.00 qps: 59.01 (r/w/o: 59.01/0.00/0.00) lat (ms,95%): 287.38 err/s: 0.00 reconn/s: 0.00
[ 17s ] queue length: 0, concurrency: 2
[ 18s ] thds: 4 tps: 13.01 qps: 165.14 (r/w/o: 165.14/0.00/0.00) lat (ms,95%): 173.58 err/s: 0.00 reconn/s: 0.00
[ 18s ] queue length: 0, concurrency: 0
[ 19s ] thds: 4 tps: 6.99 qps: 98.79 (r/w/o: 98.79/0.00/0.00) lat (ms,95%): 253.35 err/s: 0.00 reconn/s: 0.00
[ 19s ] queue length: 0, concurrency: 1
[ 20s ] thds: 4 tps: 9.98 qps: 164.60 (r/w/o: 164.60/0.00/0.00) lat (ms,95%): 590.56 err/s: 0.00 reconn/s: 0.00
[ 20s ] queue length: 0, concurrency: 3
SQL statistics:
queries performed:
read: 2800
write: 0
other: 0
total: 2800
transactions: 200 (9.64 per sec.)
queries: 2800 (134.89 per sec.)
ignored errors: 0 (0.00 per sec.)
reconnects: 0 (0.00 per sec.)
Throughput:
events/s (eps): 9.6352
time elapsed: 20.7573s
total number of events: 200
Latency (ms):
min: 44.36
avg: 202.66
max: 726.59
95th percentile: 590.56
sum: 40531.73
Threads fairness:
events (avg/stddev): 50.0000/0.71
execution time (avg/stddev): 10.1329/0.05
यह पूरी तरह से केवल-पढ़ने के लिए ट्रैफ़िक है, इसे प्रति सेकंड 10 लेनदेन (140 क्वेरीज़) में औसत होना चाहिए। चूंकि वे केवल चयन हैं, हम मौजूदा क्वेरी नियमों में से एक को आसानी से संशोधित कर सकते हैं और ट्रैफ़िक को अवरुद्ध कर सकते हैं:
इसके परिणामस्वरूप आवेदन पक्ष में निम्नलिखित त्रुटि होगी:
[email protected]:~# sysbench /root/sysbench/src/lua/oltp_read_only.lua --threads=4 --events=200 --time=0 --mysql-host=10.0.0.101 --mysql-user=sbtest --mysql-password=sbtest --mysql-port=6033 --tables=32 --report-interval=1 --skip-trx=on --table-size=100000 --db-ps-mode=disable --rate=10 run
sysbench 1.1.0-bbee5d5 (using bundled LuaJIT 2.1.0-beta3)
Running the test with following options:
Number of threads: 4
Target transaction rate: 10/sec
Report intermediate results every 1 second(s)
Initializing random number generator from current time
Initializing worker threads...
Threads started!
FATAL: mysql_drv_query() returned error 1148 (SELECT queries are not allowed!!!) for query 'SELECT c FROM sbtest25 WHERE id=83384'
FATAL: `thread_run' function failed: /usr/local/share/sysbench/oltp_common.lua:426: SQL error, errno = 1148, state = '42000': SELECT queries are not allowed!!!
अब, यह स्पष्ट रूप से कठोर है। हम अधिक विनम्र हो सकते हैं और केवल SELECT क्वेरी के लिए विलंब बढ़ा सकते हैं।
यह, ज़ाहिर है, क्वेरी के प्रदर्शन को प्रभावित करता है क्योंकि 10 मिलीसेकंड जोड़े जाते हैं निष्पादित होने वाले प्रत्येक चयन के लिए।
SQL statistics:
queries performed:
read: 2800
write: 0
other: 0
total: 2800
transactions: 200 (5.60 per sec.)
queries: 2800 (78.44 per sec.)
ignored errors: 0 (0.00 per sec.)
reconnects: 0 (0.00 per sec.)
Throughput:
events/s (eps): 5.6030
time elapsed: 35.6952s
total number of events: 200
Latency (ms):
min: 622.04
avg: 7957.01
max: 18808.60
95th percentile: 15934.78
sum: 1591401.12
Threads fairness:
events (avg/stddev): 50.0000/36.01
execution time (avg/stddev): 397.8503/271.50
हम प्रत्येक SELECT क्वेरी के लिए विलंब सेट करते हैं, जिसका यह दिखाने के अलावा कि आप इसे कर सकते हैं, कोई अर्थ नहीं है। आम तौर पर आप कुछ आपत्तिजनक प्रश्नों पर देरी का उपयोग करना चाहेंगे। मान लीजिए कि हमारे पास एक क्वेरी है जो बहुत भारी है और यह डेटाबेस के सीपीयू पर महत्वपूर्ण भार जोड़ती है। क्या बुरा है, इसे हाल ही में कोड परिवर्तन द्वारा पेश किया गया है और यह सभी एप्लिकेशन होस्ट से आता है। निश्चित रूप से, आप डेवलपर्स द्वारा परिवर्तन को वापस करने या एक फिक्स को धक्का देने की प्रतीक्षा कर सकते हैं लेकिन ProxySQL के साथ आप अपने हाथों में नियंत्रण ले सकते हैं और या तो क्वेरी को अवरुद्ध कर सकते हैं या इसके प्रभाव को काफी हद तक कम कर सकते हैं।
मान लें कि खतरे की घंटी बजने पर हमारा डेटाबेस अच्छी तरह से चल रहा है।
मैट्रिक्स पर एक त्वरित नज़र हमें बताती है कि इनके द्वारा निष्पादित प्रश्नों की संख्या ProxySQL नीचे चला जाता है जबकि CPU उपयोग बढ़ जाता है। हम यह देखने के लिए कि क्या हम कुछ असामान्य देख सकते हैं, हम ProxySQL में शीर्ष प्रश्नों को देख सकते हैं।
यह वास्तव में असामान्य है - एक नई क्वेरी जो इसका हिस्सा नहीं है नियमित क्वेरी मिक्स हमने अपने सिस्टम पर देखा। हम क्वेरी नियम बनाने के लिए विकल्प का उपयोग कर सकते हैं।
हम देरी को 50000 पर सेट करके क्वेरी में 50 सेकंड की देरी जोड़ देंगे एमएस.
हम पुष्टि कर सकते हैं कि क्वेरी नियम उपयोग में है और क्वेरीज़ इसे प्रभावित कर रही हैं ।
थोड़ी देर बाद हम यह भी नोटिस कर सकते हैं कि लोड गिर रहा है और संख्या घट रही है। निष्पादित प्रश्नों की संख्या फिर से अपेक्षित सीमा में है। बेशक, क्वेरी में देरी जोड़ने के बजाय हम इसे केवल ब्लॉक कर सकते हैं। इसे पूरा करना हमारे लिए और भी आसान होता, लेकिन क्वेरी को पूरी तरह से ब्लॉक करने से एप्लिकेशन पर महत्वपूर्ण प्रभाव पड़ सकता है।
हमें उम्मीद है कि यह संक्षिप्त ब्लॉग पोस्ट आपको कुछ अंतर्दृष्टि प्रदान करता है कि कैसे ProxySQL आपके ट्रैफ़िक को आकार देने में आपकी मदद कर सकता है और भगोड़ा क्वेरी द्वारा पेश किए गए प्रदर्शन को कम कर सकता है।