Pgpool आज कम वास्तविक है, यह 10 साल पहले हुआ करता था, जब यह एक उत्पादन PostgreSQL सेट अप का डिफ़ॉल्ट हिस्सा था। अक्सर जब कोई पोस्टग्रेएसक्यूएल क्लस्टर के बारे में बात कर रहा था, तो वे पीजीपूल के पीछे पोस्टग्रेएसक्यूएल का जिक्र कर रहे थे, न कि पोस्टग्रेएसक्यूएल इंस्टेंस के लिए (जो सही शब्द है)। Pgpool को सबसे प्रभावशाली Postgres खिलाड़ियों के बीच पहचाना जाता है:postgresql समुदाय, कमांडप्रॉम्प्ट, 2ndquadrant, EDB, citusdata, postgrespro (उम्र के अनुसार आदेशित, प्रभाव नहीं)। मुझे एहसास है कि मेरे लिंक में मान्यता का स्तर बहुत अलग है - मैं सिर्फ पोस्टग्रेज दुनिया में पीजीपूल के समग्र प्रभाव पर जोर देना चाहता हूं। पीजीपूल पहले से ही प्रसिद्ध होने के बाद कुछ सबसे ज्ञात वर्तमान पोस्टग्रेज "विक्रेता" पाए गए थे। तो क्या बात इसे इतना प्रसिद्ध बनाती है?
सबसे अधिक मांग वाली पेशकश की गई सुविधाओं की सूची ही इसे शानदार बनाती है:
- मूल प्रतिकृति
- कनेक्शन पूलिंग
- पढ़ने की मापनीयता के लिए लोड संतुलन
- उच्च उपलब्धता (वर्चुअल आईपी के साथ वॉचडॉग, ऑनलाइन रिकवरी और फेलओवर)
ठीक है, चलो एक सैंडबॉक्स बनाते हैं और खेलते हैं। मेरा नमूना सेटअप मास्टर स्लेव मोड है। मुझे लगता है कि यह आज सबसे लोकप्रिय है, क्योंकि आप आमतौर पर लोड संतुलन के साथ स्ट्रीमिंग प्रतिकृति का उपयोग करते हैं। प्रतिकृति मोड इन दिनों बमुश्किल उपयोग किया जाता है। अधिकांश DBA इसे प्रतिकृति और pglogic स्ट्रीमिंग के पक्ष में छोड़ देते हैं, और पहले slony के लिए।
प्रतिकृति मोड में कई दिलचस्प सेटिंग्स और निश्चित रूप से दिलचस्प कार्यक्षमता है। लेकिन अधिकांश डीबीए में मास्टर/मल्टी स्लेव सेटअप तब तक होता है जब तक वे पीजीपूल तक पहुंच जाते हैं। इसलिए वे स्वचालित विफलता और लोड बैलेंसर की तलाश में हैं, और पीजीपूल मौजूदा मास्टर/मल्टी स्लेव वातावरण के लिए बॉक्स से बाहर की पेशकश करता है। उल्लेख नहीं है कि पोस्टग्रेस 9.4 से, स्ट्रीमिंग प्रतिकृति बिना किसी बड़े बग के काम करती है और 10 हैश इंडेक्स प्रतिकृति से समर्थित है, इसलिए इसका उपयोग करने से रोकने के लिए मुश्किल से कुछ भी है। इसके अलावा स्ट्रीमिंग प्रतिकृति डिफ़ॉल्ट रूप से एसिंक्रोनस है (सिंक्रोनस के लिए कॉन्फ़िगर करने योग्य और यहां तक कि "रैखिक" सिंक्रनाइज़ेशन जटिल सेटअप नहीं, जबकि देशी पीजीपूल प्रतिकृति सिंक्रोनस (जिसका अर्थ है धीमा डेटा परिवर्तन) बिना किसी विकल्प विकल्प के। अतिरिक्त सीमाएं भी लागू होती हैं। पीजीपूल मैनुअल स्वयं पसंद करने का सुझाव देता है जब संभव स्ट्रीमिंग प्रतिकृति pgpool देशी एक पर)। और इसलिए यहाँ मेरी पसंद है।
आह, लेकिन पहले हमें इसे स्थापित करने की आवश्यकता है - है ना?
स्थापना (उबंटू पर उच्च संस्करण की)।
सबसे पहले उबंटू संस्करण को lsb_release -a के साथ जांचें। मेरे लिए रेपो है:
example@sqldat.com:~# sudo add-apt-repository 'deb https://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
> sudo apt-key add -
OK
example@sqldat.com:~# sudo apt-get update अंत में स्वयं स्थापना:
sudo apt-get install pgpool2=3.7.2-1.pgdg16.04+1 कॉन्फिग:
अनुशंसित मोड से मैं उपयोगकर्ता डिफ़ॉल्ट कॉन्फ़िगरेशन:
zcat /usr/share/doc/pgpool2/examples/pgpool.conf.sample-stream.gz > /etc/pgpool2/pgpool.conf प्रारंभ:
यदि आप कॉन्फ़िगरेशन से चूक गए हैं, तो आप देखें:
2018-03-22 13:52:53.284 GMT [13866] FATAL: role "nobody" does not exist आह सच - मेरा बुरा, लेकिन आसानी से ठीक करने योग्य (एक लाइनर के साथ आँख बंद करके करने योग्य यदि आप सभी स्वास्थ्य जांच और पुनर्प्राप्ति के लिए एक ही उपयोगकर्ता चाहते हैं):
example@sqldat.com:~# sed -i s/'nobody'/'pgpool'/g /etc/pgpool2/pgpool.conf और इससे पहले कि हम आगे बढ़ें, आइए सभी समूहों में डेटाबेस pgpool और उपयोगकर्ता pgpool बनाएं (मेरे सैंडबॉक्स में वे मास्टर, फ़ेलओवर और स्लेव हैं, इसलिए मुझे इसे केवल मास्टर पर चलाने की आवश्यकता है):
t=# create database pgpool;
CREATE DATABASE
t=# create user pgpool;
CREATE ROLE अंत में - प्रारंभ:
example@sqldat.com:~$ /usr/sbin/service pgpool2 start
example@sqldat.com:~$ /usr/sbin/service pgpool2 status
pgpool2.service - pgpool-II
Loaded: loaded (/lib/systemd/system/pgpool2.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2018-04-09 10:25:16 IST; 4h 14min ago
Docs: man:pgpool(8)
Process: 19231 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCESS)
Main PID: 8770 (pgpool)
Tasks: 10
Memory: 5.5M
CPU: 18.250s
CGroup: /system.slice/pgpool2.service
├─ 7658 pgpool: wait for connection reques
├─ 7659 pgpool: wait for connection reques
├─ 7660 pgpool: wait for connection reques
├─ 8770 /usr/sbin/pgpool -n
├─ 8887 pgpool: PCP: wait for connection reques
├─ 8889 pgpool: health check process(0
├─ 8890 pgpool: health check process(1
├─ 8891 pgpool: health check process(2
├─19915 pgpool: postgres t ::1(58766) idl
└─23730 pgpool: worker proces बढ़िया - इसलिए हम पहली सुविधा के लिए आगे बढ़ सकते हैं - आइए लोड संतुलन की जाँच करें। इसका उपयोग करने के लिए कुछ आवश्यकताएं हैं, संकेतों का समर्थन करता है (उदाहरण के लिए एक ही सत्र में संतुलन के लिए), इसमें श्वेत-श्याम-सूचीबद्ध कार्य हैं, इसमें नियमित अभिव्यक्ति आधारित पुनर्निर्देशन वरीयता सूची है। यह परिष्कृत है। काश, यह पूरी तरह से समाप्त हो जाता कि कार्यक्षमता इस ब्लॉग के दायरे से बाहर होगी, इस प्रकार हम सबसे सरल डेमो की जाँच करेंगे:
सबसे पहले, कुछ बहुत ही सरल दिखाएगा कि कौन सा नोड चयन के लिए उपयोग किया जाता है (मेरे सेटअप में, 5400 पर मास्टर स्पिन, 5402 पर गुलाम और 5401 पर फेलओवर, जबकि पीजीपूल 5433 पर है, क्योंकि मेरे पास एक और क्लस्टर चल रहा है और हस्तक्षेप नहीं करना चाहता था इसके साथ):
example@sqldat.com:~$ psql -h localhost -p 5433 t -c "select current_setting('port') from ts limit 1"
current_setting
-----------------
5400
(1 row) फिर लूप में:
example@sqldat.com:~$ (for i in $(seq 1 99); do psql -h localhost -p 5433 t -c "select current_setting('port') from ts limit 1" -XAt; done) | sort| uniq -c
9 5400
30 5401
60 5402 महान। यह निश्चित रूप से नोड्स के बीच भार को संतुलित करता है, लेकिन ऐसा लगता है कि संतुलन समान रूप से नहीं है - शायद यह इतना स्मार्ट है कि यह प्रत्येक कथन का वजन जानता है? आइए अपेक्षित परिणामों के साथ वितरण की जांच करें:
t=# show pool_nodes;
node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay
---------+-----------+------+--------+-----------+---------+------------+-------------------+-------------------
0 | localhost | 5400 | up | 0.125000 | primary | 122 | false | 0
1 | localhost | 5401 | up | 0.312500 | standby | 169 | false | 0
2 | localhost | 5402 | up | 0.562500 | standby | 299 | true | 0
(3 rows) नहीं - पीजीपूल बयानों के वजन का विश्लेषण नहीं करता है - यह फिर से उसकी सेटिंग्स के साथ एक डीबीए था! सेटिंग्स (lb_weight विशेषता देखें) वास्तविक क्वेरी गंतव्य लक्ष्यों के साथ मेल खाती हैं। आप इसे आसानी से बदल सकते हैं (जैसा कि हमने यहां किया था) संबंधित सेटिंग को बदलकर, जैसे:
example@sqldat.com:~$ grep weight /etc/pgpool2/pgpool.conf
backend_weight0 =0.2
backend_weight1 = 0.5
backend_weight2 = 0.9
example@sqldat.com:~# sed -i s/'backend_weight2 = 0.9'/'backend_weight2 = 0.2'/ /etc/pgpool2/pgpool.conf
example@sqldat.com:~# grep backend_weight2 /etc/pgpool2/pgpool.conf
backend_weight2 = 0.2
example@sqldat.com:~# pgpool reload
example@sqldat.com:~$ (for i in $(seq 1 9); do psql -h localhost -p 5433 t -c "select current_setting('port') from ts limit 1" -XAt; done) | sort| uniq -c
6 5401
3 5402 आज श्वेतपत्र डाउनलोड करें क्लस्टरकंट्रोल के साथ पोस्टग्रेएसक्यूएल प्रबंधन और स्वचालन इस बारे में जानें कि पोस्टग्रेएसक्यूएल को तैनात करने, मॉनिटर करने, प्रबंधित करने और स्केल करने के लिए आपको क्या जानना चाहिए। श्वेतपत्र डाउनलोड करें महान! पेशकश की जाने वाली अगली महान विशेषता कनेक्शन पूलिंग है। 3.5 के साथ "थंडरिंग झुंड की समस्या" को स्वीकार () कॉल को क्रमबद्ध करके हल किया जाता है, जिससे "क्लाइंट कनेक्शन" समय में बहुत तेजी आती है। और फिर भी यह सुविधा बहुत सीधी है। यह पूलिंग के कई स्तरों या एक ही डेटाबेस के लिए कॉन्फ़िगर किए गए कई पूलों की पेशकश नहीं करता है (पीजीपूल आपको यह चुनने देता है कि लोड संतुलन के डेटाबेस_redirect_preference_list के साथ चयन कहां चलाया जाए), या पीजीबाउंसर द्वारा प्रदान की जाने वाली अन्य लचीली सुविधाएं।
इतना छोटा डेमो:
t=# select pid,usename,backend_type, state, left(query,33) from pg_stat_activity where usename='vao' and pid <> pg_backend_pid();
pid | usename | backend_type | state | left
------+---------+----------------+-------+--------------
8911 | vao | client backend | idle | DISCARD ALL
8901 | vao | client backend | idle | DISCARD ALL
7828 | vao | client backend | idle | DISCARD ALL
8966 | vao | client backend | idle | DISCARD ALL
(4 rows)
Hm - did I set up this little number of children?
t=# pgpool show num_init_children;
num_init_children
-------------------
4
(1 row) आह, सच है, मैंने उन्हें डिफ़ॉल्ट 32 से कम बदल दिया है, इसलिए आउटपुट में कई पेज नहीं होंगे। ठीक है, तो आइए सत्रों की संख्या को पार करने का प्रयास करें (नीचे मैं लूप में पोस्टग्रेज सत्र async खोलता हूं, इसलिए 6 सत्रों का अनुरोध कमोबेश एक ही समय में किया जाएगा):
example@sqldat.com:~$ for i in $(seq 1 6); do (psql -h localhost -p 5433 t -U vao -c "select pg_backend_pid(), pg_sleep(1), current_setting('port'), clock_timestamp()" &); done
example@sqldat.com:~$ pg_backend_pid | pg_sleep | current_setting | clock_timestamp
----------------+----------+-----------------+-------------------------------
8904 | | 5402 | 2018-04-10 12:46:55.626206+01
(1 row)
pg_backend_pid | pg_sleep | current_setting | clock_timestamp
----------------+----------+-----------------+-------------------------------
9391 | | 5401 | 2018-04-10 12:46:55.630175+01
(1 row)
pg_backend_pid | pg_sleep | current_setting | clock_timestamp
----------------+----------+-----------------+------------------------------
8911 | | 5400 | 2018-04-10 12:46:55.64933+01
(1 row)
pg_backend_pid | pg_sleep | current_setting | clock_timestamp
----------------+----------+-----------------+-------------------------------
8904 | | 5402 | 2018-04-10 12:46:56.629555+01
(1 row)
pg_backend_pid | pg_sleep | current_setting | clock_timestamp
----------------+----------+-----------------+-------------------------------
9392 | | 5402 | 2018-04-10 12:46:56.633092+01
(1 row)
pg_backend_pid | pg_sleep | current_setting | clock_timestamp
----------------+----------+-----------------+------------------------------
8910 | | 5402 | 2018-04-10 12:46:56.65543+01
(1 row) यह सत्रों को तीन-अपेक्षित आने देता है, जैसा कि उपरोक्त सत्र (pg_stat_activity से चयन) द्वारा लिया जाता है, इसलिए 4-1 =3। जैसे ही pg_sleep अपनी एक सेकंड की झपकी पूरी करता है और सत्र पोस्टग्रेज़ द्वारा बंद कर दिया जाता है, अगले एक को अंदर जाने दिया जाता है। इसलिए पहले तीन समाप्त होने के बाद, अगला तीन चरण अंदर आता है। बाकी का क्या होता है? वे तब तक कतारबद्ध हैं जब तक कि अगला कनेक्शन स्लॉट मुक्त नहीं हो जाता। फिर serialize_accept के आगे वर्णित प्रक्रिया होती है और क्लाइंट कनेक्ट हो जाता है।
हुह? सत्र मोड में बस सत्र पूलिंग? क्या यह सब है?.. नहीं, यहाँ कैशिंग कदम है! देखो.:
postgres=# /*NO LOAD BALANCE*/ select 1;
?column?
----------
1
(1 row) pg_stat_activity की जाँच करना:
postgres=# select pid, datname, state, left(query,33),state_change::time(0), now()::time(0) from pg_stat_activity where usename='vao' and query not like '%DISCARD%';
pid | datname | state | left | state_change | now
-------+----------+-------+-----------------------------------+--------------+----------
15506 | postgres | idle | /*NO LOAD BALANCE*/ select 1, now | 13:35:44 | 13:37:19
(1 row) फिर पहले स्टेटमेंट को फिर से चलाएँ और देखें कि State_change नहीं बदल रहा है, जिसका अर्थ है कि आप ज्ञात परिणाम प्राप्त करने के लिए डेटाबेस तक नहीं पहुँचते हैं! बेशक, यदि आप कुछ परिवर्तनशील फ़ंक्शन डालते हैं, तो परिणाम कैश नहीं होंगे। इसके साथ प्रयोग करें:
postgres=# /*NO LOAD BALANCE*/ select 1, now();
?column? | now
----------+------------------------------
1 | 2018-04-10 13:35:44.41823+01
(1 row) आप पाएंगे कि State_change परिणाम के अनुसार बदलता है।
यहां अंतिम बिंदु - क्यों /*नो लोड बैलेंस*/ ?.. यह सुनिश्चित करने के लिए कि हम मास्टर पर pg_stat_activity चेक करते हैं और मास्टर पर भी क्वेरी चलाते हैं। उसी तरह आप कैश्ड परिणाम प्राप्त करने से बचने के लिए /*NO QUERY CACHE*/ संकेत का उपयोग कर सकते हैं।
एक छोटी समीक्षा के लिए पहले से ही बहुत कुछ? लेकिन हमने हा भाग को छुआ तक नहीं! और कई उपयोगकर्ता विशेष रूप से इस सुविधा के लिए pgpool की ओर देखते हैं। खैर, यह कहानी का अंत नहीं है, यह भाग एक का अंत है। भाग दो आ रहा है, जहाँ हम संक्षेप में HA और कुछ अन्य युक्तियों को pgpool का उपयोग करने के बारे में बताएंगे...