PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Hướng dẫn về Pgpool cho PostgreSQL:Phần một

Pgpool ngày nay ít thực tế hơn so với 10 năm trước, khi nó là phần mặc định của một PostgreSQL sản xuất được thiết lập. Thông thường khi ai đó nói về cụm PostgreSQL, họ đang đề cập đến postgreSQL đằng sau pgpool chứ không phải bản thân cá thể PostgreSQL (đó là thuật ngữ phù hợp). Pgpool được công nhận giữa những người chơi Postgres có ảnh hưởng nhất:cộng đồng postgresql, commandprompt, 2ndquadrant, EDB, citusdata, postgrespro (sắp xếp theo độ tuổi, không phải ảnh hưởng). Tôi nhận thấy mức độ công nhận trong các liên kết của tôi là rất khác nhau - tôi chỉ muốn nhấn mạnh tác động tổng thể của pgpool trong thế giới postgres. Một số "nhà cung cấp" postgres hiện tại được biết đến nhiều nhất đã được tìm thấy sau khi pgpool đã nổi tiếng. Vậy điều gì khiến nó trở nên nổi tiếng?

Chỉ cần danh sách các tính năng được cung cấp theo yêu cầu nhất đã làm cho nó trông tuyệt vời:

  • bản sao gốc
  • tổng hợp kết nối
  • cân bằng tải để có khả năng mở rộng đọc
  • tính khả dụng cao (cơ quan giám sát với IP ảo, khôi phục trực tuyến và chuyển đổi dự phòng)

Nào, chúng ta hãy tạo một hộp cát và chơi. Thiết lập mẫu của tôi là chế độ chủ nô lệ. Tôi sẽ cho rằng nó là phổ biến nhất hiện nay, bởi vì bạn thường sử dụng sao chép phát trực tuyến cùng với cân bằng tải. Chế độ sao chép hầu như không được sử dụng trong những ngày này. Hầu hết các DBA bỏ qua nó để ưu tiên phát trực tuyến sao chép và pglogical, và trước đó là slony.

Chế độ nhân bản có nhiều cài đặt thú vị và chức năng chắc chắn thú vị. Nhưng hầu hết các DBA đều có thiết lập master / multi slave vào thời điểm chúng chuyển đến pgpool. Vì vậy, họ đang tìm kiếm bộ chuyển đổi dự phòng và cân bằng tải tự động, và pgpool cung cấp nó cho các môi trường chủ / đa nô lệ hiện có. Chưa kể rằng từ Postgres 9.4, tính năng sao chép trực tuyến hoạt động mà không có lỗi lớn nào và từ 10 chỉ mục băm được hỗ trợ sao chép, vì vậy hầu như không có gì ngăn bạn sử dụng nó. Ngoài ra, sao chép trực tuyến là không đồng bộ theo mặc định (có thể định cấu hình để đồng bộ hóa và thậm chí không phải thiết lập phức tạp đồng bộ hóa “tuyến tính”, trong khi sao chép pgpool gốc là đồng bộ (có nghĩa là thay đổi dữ liệu chậm hơn) mà không có tùy chọn lựa chọn nào. Cũng áp dụng các giới hạn bổ sung. Bản thân hướng dẫn sử dụng pgpool đề xuất ưu tiên khi có thể sao chép trực tuyến qua pgpool gốc). Và đây là sự lựa chọn của tôi ở đây.

À, nhưng trước tiên chúng ta cần cài đặt nó - phải không?

Cài đặt (phiên bản cao hơn trên ubuntu).

Đầu tiên hãy kiểm tra phiên bản ubuntu bằng lsb_release -a. Đối với tôi repo là:

[email protected]:~# sudo add-apt-repository 'deb http://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
[email protected]:~# sudo apt-get update

Cuối cùng tự cài đặt:

sudo apt-get install pgpool2=3.7.2-1.pgdg16.04+1

Cấu hình:

Tôi sử dụng cấu hình mặc định từ chế độ được đề xuất:

zcat /usr/share/doc/pgpool2/examples/pgpool.conf.sample-stream.gz > /etc/pgpool2/pgpool.conf

Bắt đầu:

Nếu bạn bỏ lỡ cấu hình, bạn sẽ thấy:

2018-03-22 13:52:53.284 GMT [13866] FATAL:  role "nobody" does not exist

Ah đúng - lỗi của tôi, nhưng có thể sửa chữa dễ dàng (có thể làm được một cách mù quáng với một lớp lót nếu bạn muốn cùng một người dùng cho tất cả các lần kiểm tra sức khỏe và phục hồi):

[email protected]:~# sed -i s/'nobody'/'pgpool'/g /etc/pgpool2/pgpool.conf

Và trước khi chúng ta đi xa hơn, hãy tạo pgpool cơ sở dữ liệu và pgpool người dùng trong tất cả các cụm (Trong hộp cát của tôi, chúng là chính, chuyển đổi dự phòng và nô lệ, vì vậy tôi chỉ cần chạy nó trên chính):

t=# create database pgpool;
CREATE DATABASE
t=# create user pgpool;
CREATE ROLE

Cuối cùng - bắt đầu:

[email protected]:~$ /usr/sbin/service pgpool2 start
[email protected]:~$ /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

Tuyệt vời - vì vậy chúng ta có thể tiếp tục tính năng đầu tiên - hãy kiểm tra cân bằng tải. Nó có một số yêu cầu được sử dụng, hỗ trợ gợi ý (ví dụ:cân bằng trong cùng một phiên), có các chức năng được liệt kê trắng đen, có danh sách tùy chọn chuyển hướng dựa trên biểu thức chính quy. Nó là tinh vi. Rất tiếc, nếu tìm hiểu kỹ về tất cả chức năng đó sẽ nằm ngoài phạm vi của blog này, do đó chúng tôi sẽ kiểm tra các bản trình diễn đơn giản nhất:

Đầu tiên, một cái gì đó rất đơn giản sẽ hiển thị nút nào được sử dụng để chọn (trong thiết lập của tôi, vòng quay chính trên 5400, nô lệ trên 5402 và chuyển đổi dự phòng trên 5401, trong khi bản thân pgpool là trên 5433, vì tôi có một cụm khác đang chạy và không muốn can thiệp với nó):

[email protected]:~$ psql -h localhost -p 5433 t -c "select current_setting('port') from ts limit 1"
 current_setting
-----------------
 5400
(1 row)

Sau đó trong vòng lặp:

[email protected]:~$ (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

Tuyệt quá. Nó chắc chắn cân bằng tải giữa các nút, nhưng dường như cân bằng không bằng nhau - có lẽ nó thông minh đến mức biết trọng lượng của mỗi câu lệnh? Hãy kiểm tra sự phân phối với kết quả mong đợi:

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)

Không - pgpool không phân tích trọng lượng của các tuyên bố - đó là một DBA với cài đặt của cô ấy một lần nữa! Cài đặt (xem thuộc tính lb_weight) hài hòa với các mục tiêu đích truy vấn thực tế. Bạn có thể dễ dàng thay đổi nó (như chúng tôi đã làm ở đây) bằng cách thay đổi cài đặt tương ứng, ví dụ:

[email protected]:~$ grep weight /etc/pgpool2/pgpool.conf
backend_weight0 =0.2
backend_weight1 = 0.5
backend_weight2 = 0.9
[email protected]:~# sed -i s/'backend_weight2 = 0.9'/'backend_weight2 = 0.2'/ /etc/pgpool2/pgpool.conf
[email protected]:~# grep backend_weight2 /etc/pgpool2/pgpool.conf
backend_weight2 = 0.2
[email protected]:~# pgpool reload
[email protected]:~$ (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
Tải xuống Báo cáo chính thức hôm nay Quản lý &Tự động hóa PostgreSQL với ClusterControlTìm hiểu về những điều bạn cần biết để triển khai, giám sát, quản lý và mở rộng PostgreSQLTải xuống Báo cáo chính thức

Tuyệt quá! Tính năng tuyệt vời tiếp theo được cung cấp là gộp kết nối. Với 3.5, “vấn đề bầy đàn sấm sét” được giải quyết bằng cách tuần tự hóa các cuộc gọi accept (), tăng tốc đáng kể thời gian “kết nối máy khách”. Và tính năng này khá đơn giản. Nó không cung cấp một số mức gộp hoặc một số nhóm được định cấu hình cho cùng một cơ sở dữ liệu (pgpool cho phép bạn chọn nơi chạy các lựa chọn với database_redirect_preference_list cân bằng tải) hoặc các tính năng linh hoạt khác do pgBouncer cung cấp.

Bản demo ngắn gọn:

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)

Ah, đúng, tôi đã thay đổi chúng thấp hơn mặc định 32, vì vậy đầu ra sẽ không mất vài trang. Vậy thì, hãy thử vượt quá số phiên (bên dưới tôi mở các phiên postgres không đồng bộ trong vòng lặp, vì vậy, 6 phiên sẽ được yêu cầu nhiều hơn hoặc ít hơn cùng một lúc):

[email protected]:~$ 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
[email protected]:~$  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)

Nó cho phép các phiên đến sau ba phiên - dự kiến, như một phiên được thực hiện bởi phiên ở trên (chọn từ pg_stat_activity) vì vậy 4-1 =3. Ngay sau khi pg_sleep kết thúc giấc ngủ ngắn thứ hai và phiên đóng bởi postgres, phiên tiếp theo sẽ được truy cập. Vì vậy, sau khi ba bước đầu tiên kết thúc, ba bước tiếp theo sẽ xảy ra. Điều gì xảy ra với phần còn lại? Chúng được xếp hàng đợi cho đến khi giải phóng khe kết nối tiếp theo. Sau đó, quá trình được mô tả bên cạnh serialize_accept sẽ xảy ra và máy khách được kết nối.

Huh? Chỉ gộp phiên trong chế độ phiên? Có phải tất cả không? .. Không, đây là bước vào bộ nhớ đệm! Nhìn kìa:

postgres=# /*NO LOAD BALANCE*/ select 1;
 ?column?
----------
        1
(1 row)

Kiểm tra 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)

Sau đó, chạy lại câu lệnh đầu tiên và quan sát state_change không thay đổi, có nghĩa là bạn thậm chí không truy cập vào cơ sở dữ liệu để nhận được kết quả đã biết! Tất nhiên nếu bạn đặt một số hàm có thể thay đổi, kết quả sẽ không được lưu vào bộ nhớ đệm. Thử nghiệm với:

postgres=# /*NO LOAD BALANCE*/ select 1, now();
 ?column? |             now
----------+------------------------------
        1 | 2018-04-10 13:35:44.41823+01
(1 row)

Bạn sẽ thấy rằng state_change cũng thay đổi theo kết quả.

Điểm cuối cùng ở đây - tại sao / * KHÔNG CÓ CÂN BẰNG TẢI * /? .. để đảm bảo rằng chúng tôi kiểm tra pg_stat_activity trên master và chạy cả truy vấn trên master. Tương tự, bạn có thể sử dụng / * NO QUERY CACHE * / gợi ý để tránh nhận kết quả được lưu trong bộ nhớ cache.

Đã có nhiều cho một bài đánh giá ngắn? Nhưng chúng tôi thậm chí còn không chạm vào phần HA! Và nhiều người dùng hướng tới pgpool đặc biệt cho tính năng này. Chà, đây không phải là kết thúc của câu chuyện, đây là kết thúc của phần một. Phần hai sẽ đến, chúng tôi sẽ giới thiệu ngắn gọn về HA và một số mẹo khác khi sử dụng pgpool ...


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL:Truy vấn song song trong hành động

  2. Khóa cho CHỌN để một quy trình khác không lấy dữ liệu cũ

  3. Một số ý tưởng về tổng hợp tài nguyên cấp thấp trong PostgreSQL

  4. đặt mật khẩu trống cho người dùng PostgreSQL

  5. Trừ số ngày cho một ngày trong PostgreSQL