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

Hướng dẫn sử dụng pgBouncer cho PostgreSQL

Khi đọc PostgreSQL bắt đầu, bạn sẽ thấy dòng:“ Máy chủ PostgreSQL có thể xử lý nhiều kết nối đồng thời từ các máy khách. Để đạt được điều này, nó bắt đầu (“fork”) một quy trình mới cho mỗi kết nối. Từ thời điểm đó, máy khách và quy trình máy chủ mới giao tiếp với nhau mà không cần sự can thiệp của quy trình postgres ban đầu. Do đó, quy trình máy chủ chính luôn chạy, chờ kết nối máy khách, trong khi quy trình máy khách và máy chủ được liên kết đến và đi.

Ý tưởng tuyệt vời. Tuy nhiên, điều đó có nghĩa là mỗi kết nối mới sẽ quay một quá trình mới, dự trữ RAM và có thể quá nặng với nhiều phiên. Để tránh sự cố, postgres có cài đặt max_connections với 100 kết nối mặc định. Tất nhiên bạn có thể tăng nó, nhưng hành động như vậy sẽ yêu cầu khởi động lại (pg_settings.context là ‘postmaster’):

t=# select name,setting,short_desc,context from pg_settings where name = 'max_connections';
-[ RECORD 1 ]--------------------------------------------------
name       | max_connections
setting    | 100
short_desc | Sets the maximum number of concurrent connections.
context    | postmaster
Một số bài đọc thú vị Cách sử dụng PgBouncer Điểm nảy là gì? PgBouncer Changelog Bài đăng có chứa 'pgbouncer' trên Stack Overflow Các bài đăng được gắn thẻ 'pgbouncer' trên 2ndQuadrant

Và thậm chí sau khi tăng - tại một số điểm bạn có thể cần nhiều kết nối hơn (tất nhiên là khẩn cấp như mọi khi đang chạy sản phẩm). Tại sao tăng nó lại khó chịu như vậy? Bởi vì nếu nó thoải mái, bạn có thể sẽ kết thúc với việc tăng số lượng tự phát không kiểm soát được cho đến khi cụm bắt đầu chậm lại. Có nghĩa là các kết nối cũ chậm hơn - vì vậy chúng mất nhiều thời gian hơn, vì vậy bạn thậm chí cần nhiều hơn và nhiều hơn mới hơn. Để tránh tuyết lở có thể xảy ra như vậy và thêm một số tính linh hoạt, chúng tôi có superuser_reserved_connections - để có thể kết nối và khắc phục sự cố với SU khi max_connections hết. Và rõ ràng chúng tôi thấy sự cần thiết của một số công cụ kết nối. Vì chúng tôi muốn các ứng viên kết nối mới phải đợi trong hàng đợi thay vì thất bại với ngoại lệ FATAL:xin lỗi, đã có quá nhiều khách hàng và đừng mạo hiểm với người quản lý bưu điện.

Tổng hợp kết nối được cung cấp ở một số cấp độ bởi nhiều "khách hàng" phổ biến. Bạn có thể sử dụng nó với jdbc trong một thời gian. Gần đây node-postgres đã cung cấp node-pg-pool của riêng nó. Ít nhiều thì việc triển khai cũng đơn giản (như ý tưởng là như vậy):pooler bắt đầu các kết nối hướng tới cơ sở dữ liệu và giữ chúng. Máy khách kết nối với db chỉ nhận được kết nối hiện có "được chia sẻ" và sau khi đóng nó, kết nối sẽ quay trở lại nhóm. Chúng tôi cũng có nhiều phần mềm phức tạp hơn, như pgPool. Và pgbouncer là một lựa chọn cực kỳ phổ biến cho nhiệm vụ. Tại sao? Bởi vì nó chỉ làm phần gộp, nhưng làm đúng. Nó miễn phí. Nó khá đơn giản để thiết lập. Và bạn gặp nó ở hầu hết các nhà cung cấp dịch vụ lớn nhất theo khuyến nghị hoặc được sử dụng, ví dụ như citusdata, aws, heroku và các tài nguyên được đánh giá cao khác.

Vì vậy, hãy để chúng tôi xem xét kỹ hơn những gì nó có thể và cách bạn sử dụng nó. Trong thiết lập của mình, tôi sử dụng pool_mode =transaction (phần [pgbouncer]) mặc định, đây là một lựa chọn rất phổ biến. Bằng cách này, chúng tôi không chỉ xếp hàng đợi các kết nối vượt quá max_connections mà còn sử dụng lại các phiên mà không cần đợi kết nối trước đó đóng:

[databases]
mon = host=1.1.1.1 port=5432 dbname=mon
mons = host=1.1.1.1 port=5432 dbname=mon pool_mode = session pool_size=2 max_db_connections=2
monst = host=1.1.1.1 port=5432 dbname=mon pool_mode = statement
[pgbouncer]
listen_addr = 1.1.1.1
listen_port = 6432
unix_socket_dir = /tmp
auth_file = /pg/pgbouncer/bnc_users.txt
auth_type = hba
auth_hba_file = /pg/pgbouncer/bnc_hba.conf
admin_users = root vao
pool_mode = transaction
server_reset_query = RESET ALL; --DEALLOCATE ALL; /* custom */
ignore_startup_parameters = extra_float_digits
application_name_add_host = 1
max_client_conn = 10000
autodb_idle_timeout = 3600
default_pool_size = 100
max_db_connections = 100
max_user_connections = 100
#server_reset_query_always = 1 #uncomment if you want older global behaviour

Tổng quan ngắn gọn về các cài đặt và mẹo và thủ thuật phổ biến nhất:

  • server_reset_query rất tiện dụng và quan trọng. Trong chế độ tổng hợp phiên, nó "xóa sạch" "hiện vật" của phiên trước đó. Nếu không, bạn sẽ gặp sự cố với cùng tên cho các câu lệnh đã chuẩn bị, cài đặt phiên ảnh hưởng đến các phiên tiếp theo, v.v. Mặc định là BỎ TẤT CẢ, "đặt lại" tất cả các trạng thái phiên. Tuy nhiên, bạn có thể chọn các giá trị phức tạp hơn, ví dụ:ĐẶT LẠI TẤT CẢ; XÓA TẤT CẢ; chỉ để quên PHẦN CÀI ĐẶT và các tuyên bố đã chuẩn bị, giữ các bảng và kế hoạch TEMP được “chia sẻ”. Hoặc ngược lại - bạn có thể muốn đưa ra các tuyên bố đã chuẩn bị sẵn “toàn cầu” từ bất kỳ phiên nào. Cấu hình như vậy là có thể thực hiện được, mặc dù rủi ro. Bạn phải làm cho pgbouncer sử dụng lại phiên cho tất cả (do đó làm cho kích thước nhóm rất nhỏ hoặc bỏ qua các phiên), điều này không hoàn toàn đáng tin cậy. Dù sao - đó là một khả năng hữu ích. Đặc biệt là trong các thiết lập mà bạn muốn các phiên khách cuối cùng (không phải ngay lập tức) thay đổi thành cài đặt phiên gộp đã định cấu hình. Điểm rất quan trọng ở đây là chế độ nhóm phiên. Trước 1.6, cài đặt này cũng ảnh hưởng đến các chế độ tổng hợp khác, vì vậy nếu bạn dựa vào nó, bạn cần sử dụng cài đặt mới server_reset_query_always =1. Có thể một lúc nào đó mọi người sẽ muốn server_reset_query linh hoạt hơn và có thể định cấu hình cho mỗi cặp db / người dùng ( và client_reset_query thay thế). Nhưng tính đến thời điểm hiện tại, tháng 3 năm 2018, đó không phải là một lựa chọn. Ý tưởng đằng sau việc làm cho cài đặt này chỉ hợp lệ theo mặc định cho chế độ phiên là - nếu bạn chia sẻ kết nối ở cấp giao dịch hoặc cấp sao kê - thì bạn hoàn toàn không thể dựa vào cài đặt phiên.

  • Auth_type =hba. Trước ngày 1.7, vấn đề lớn với pgbouncer là không có xác thực dựa trên máy chủ - “tường lửa postgres”. Tất nhiên bạn vẫn có nó cho kết nối cụm postgres, nhưng pgbouncer “mở” cho bất kỳ nguồn nào. Bây giờ chúng ta có thể sử dụng cùng một hba.conf để giới hạn kết nối cho máy chủ / db / người dùng dựa trên mạng kết nối.

  • connect_query không được thực hiện trên mọi ứng dụng khách "kết nối" với pgbouncer, mà là khi pgbouncer kết nối với một phiên bản Postgres. Vì vậy, bạn không thể sử dụng nó để thiết lập hoặc ghi đè cài đặt "mặc định". Ở chế độ phiên, các phiên khác không ảnh hưởng lẫn nhau và khi ngắt kết nối, đặt lại truy vấn sẽ loại bỏ tất cả - vì vậy bạn không cần phải làm phiền nó. Trong chế độ tổng hợp giao dịch, bạn sẽ hy vọng sử dụng nó cho các cài đặt ghi đè do các phiên khác đặt sai, nhưng nó sẽ không hoạt động, than ôi. Ví dụ. bạn muốn chia sẻ báo cáo đã chuẩn bị sẵn giữa các "phiên" trong chế độ giao dịch, vì vậy bạn đặt một cái gì đó như

    trns = dbname=mon pool_mode = transaction connect_query = 'do $$ begin raise warning $w$%$w$, $b$new connection$b$; end; $$; prepare s(int) as select $1;'

    và thực sự - mọi máy khách mới đều thấy các câu lệnh đã chuẩn bị sẵn (trừ khi bạn bật server_reset_query_always, vì vậy pgbouncer loại bỏ nó khi cam kết). Nhưng nếu một số khách hàng chạy DISCARD s; trong phiên của mình, nó ảnh hưởng đến tất cả các khách hàng trên kết nối này và các khách hàng mới kết nối với nó sẽ không thấy các báo cáo đã chuẩn bị nữa. Nhưng nếu bạn muốn có một số cài đặt ban đầu cho các kết nối postgres đến từ pgbouncer, thì đây là nơi.

  • application_name_add_host đã được thêm vào 1.6, nó có hạn chế tương tự. Nó “đặt” IP của ứng dụng khách thành application_name, vì vậy bạn có thể dễ dàng nhận được nguồn truy vấn không hợp lệ của mình, nhưng dễ dàng bị ghi đè bởi application_name đơn giản TO ‘wasn’n’t me’; Bạn vẫn có thể "chữa lành" điều này bằng cách sử dụng lượt xem - hãy theo dõi bài đăng này để có ý tưởng hoặc thậm chí sử dụng các hướng dẫn ngắn này. Về cơ bản, ý tưởng là hiển thị cho khách hàng; sẽ hiển thị IP của ứng dụng khách, vì vậy bạn có thể truy vấn trực tiếp từ cơ sở dữ liệu pgbouncer trên mỗi lựa chọn từ pg_stat_activity để kiểm tra xem nó có được đặt lại hay không. Nhưng tất nhiên việc sử dụng một cài đặt đơn giản sẽ đơn giản và gọn gàng hơn nhiều. Mặc dù nó không đảm bảo kết quả ...

  • pool_mode có thể được chỉ định cả làm mặc định, cho mỗi cơ sở dữ liệu và cho mỗi người dùng - làm cho nó rất linh hoạt. Các chế độ trộn làm cho pgbouncer cực kỳ hiệu quả để gộp. Đây là một tính năng mạnh mẽ, nhưng người ta phải cẩn thận khi sử dụng nó. Thông thường người dùng sử dụng nó mà không hiểu kết quả để kết hợp hoàn toàn nguyên tử của mỗi giao dịch / mỗi phiên / mỗi người dùng / mỗi cơ sở dữ liệu / cài đặt chung hoạt động khác nhau cho cùng một người dùng hoặc cơ sở dữ liệu, do các chế độ gộp khác nhau với pgbouncer. Đây là hộp diêm mà bạn không đưa cho trẻ em nếu không có sự giám sát. Ngoài ra, nhiều tùy chọn khác có thể được định cấu hình cho mặc định và theo db và trên mỗi người dùng.

  • Vui lòng không hiểu theo nghĩa đen, nhưng bạn có thể “so sánh” các phần khác nhau của ini với SET và ALTER:SET LOCAL ảnh hưởng đến các giao dịch và rất tốt để sử dụng khi thăm dò ý kiến ​​=giao dịch, SET PHIÊN BẢN ảnh hưởng đến các phiên và an toàn để sử dụng khi thăm dò ý kiến ​​=phiên làm việc , ALTER USER SET ảnh hưởng đến các vai trò và sẽ ảnh hưởng đến phần pgbouncer.ini của phần [người dùng], ALTER DATABASE SET ảnh hưởng đến cơ sở dữ liệu và sẽ ảnh hưởng đến phần pgbouncer.ini của phần [databases], ALTER SYSTEM SET hoặc chỉnh sửa toàn cầu postgres.conf ảnh hưởng đến giá trị mặc định và có thể so sánh theo hiệu ứng với phần mặc định của pgbouncer.ini.

  • Một lần nữa - hãy sử dụng chế độ hồ bơi một cách có trách nhiệm. Các câu lệnh chuẩn bị trước hoặc cài đặt toàn phiên sẽ là một mớ hỗn độn trong chế độ gộp giao dịch. Tương tự như giao dịch SQL không có ý nghĩa trong chế độ gộp câu lệnh. Chọn một chế độ gộp phù hợp cho các kết nối phù hợp. Một phương pháp hay là tạo các vai trò với ý tưởng rằng:

    • một số sẽ chỉ chạy các lựa chọn nhanh, do đó có thể chia sẻ một phiên mà không có giao dịch cho hàng trăm lựa chọn nhỏ không quan trọng đồng thời.
    • Một số thành viên có vai trò an toàn cho đồng thời cấp phiên và LUÔN LUÔN sử dụng các giao dịch. Vì vậy, họ có thể chia sẻ một số phiên một cách an toàn cho hàng trăm giao dịch đồng thời.
    • Một số vai trò quá lộn xộn và phức tạp để chia sẻ phiên của họ với những người khác. Vì vậy, bạn sử dụng chế độ tổng hợp phiên để tránh lỗi kết nối khi tất cả các "vị trí" đã được sử dụng.
  • Không sử dụng nó thay vì HAProxy hoặc một số trình cân bằng tải khác. Mặc dù thực tế là pgbouncer có một số tính năng có thể định cấu hình giải quyết địa chỉ của bộ cân bằng tải, như dns_max_ttl và bạn có thể thiết lập cấu hình DNS cho nó, hầu hết các môi trường sản xuất đều sử dụng HAProxy hoặc một số bộ cân bằng tải khác cho HA. Điều này là do HAProxy thực sự tốt trong việc cân bằng tải trên các máy chủ trực tiếp theo kiểu vòng tròn, tốt hơn pgbouncer. Mặc dù pgbouncer tốt hơn để tổng hợp kết nối postgres, nhưng có thể tốt hơn nếu sử dụng một daemon nhỏ thực hiện hoàn hảo một tác vụ, thay vì một trình nền lớn hơn thực hiện hai tác vụ, nhưng tệ hơn.

  • Thay đổi cấu hình có thể phức tạp. Một số thay đổi đối với pgbouncer.ini yêu cầu khởi động lại (listening_port, v.v.), trong khi những thay đổi khác như admin_users yêu cầu tải lại hoặc SIGHUP. Các thay đổi bên trong auth_hba_file yêu cầu tải lại, trong khi các thay đổi đối với auth_file thì không.

Tổng quan cực ngắn về cài đặt ở trên bị giới hạn bởi định dạng. Tôi mời bạn xem qua danh sách đầy đủ. Pgbouncer là loại phần mềm có số lượng “cài đặt nhàm chán” rất nhỏ - tất cả chúng đều có tiềm năng rất lớn và đáng kinh ngạc.

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

Và cuối cùng, chuyển từ một bài đánh giá nhiệt tình ngắn sang một thứ mà bạn có thể ít hài lòng hơn - cài đặt. Quy trình được mô tả rõ ràng trong phần tài liệu này. Tùy chọn duy nhất được mô tả là xây dựng từ các nguồn git. Nhưng mọi người đều biết có những gói! Đang thử cả hai cách phổ biến nhất:

sudo yum install pgbouncer
sudo apt-get install pgbouncer

có thể làm việc. Nhưng đôi khi bạn phải thực hiện thêm một bước. Ví dụ:khi không có gói pgbouncer nào, hãy thử cái này.

Hoặc thậm chí:

sudo yum install pgbouncer
Loaded plugins: priorities, update-motd, upgrade-helper
amzn-main                                                                                                                    | 2.1 kB  00:00:00
amzn-updates                                                                                                                 | 2.5 kB  00:00:00
docker-ce-edge                                                                                                               | 2.9 kB  00:00:00
docker-ce-stable                                                                                                             | 2.9 kB  00:00:00
docker-ce-test                                                                                                               | 2.9 kB  00:00:00
pgdg10                                                                                                                       | 4.1 kB  00:00:00
pgdg95                                                                                                                       | 4.1 kB  00:00:00
pgdg96                                                                                                                       | 4.1 kB  00:00:00
pglogical                                                                                                                    | 3.0 kB  00:00:00
sensu                                                                                                                        | 2.5 kB  00:00:00
(1/3): pgdg96/x86_64/primary_db                                                                                              | 183 kB  00:00:00
(2/3): pgdg10/primary_db                                                                                                     | 151 kB  00:00:00
(3/3): pgdg95/x86_64/primary_db                                                                                              | 204 kB  00:00:00
50 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package pgbouncer.x86_64 0:1.8.1-1.rhel6 will be installed
--> Processing Dependency: libevent2 >= 2.0 for package: pgbouncer-1.8.1-1.rhel6.x86_64
--> Processing Dependency: c-ares for package: pgbouncer-1.8.1-1.rhel6.x86_64
--> Processing Dependency: libcares.so.2()(64bit) for package: pgbouncer-1.8.1-1.rhel6.x86_64
--> Running transaction check
---> Package c-ares.x86_64 0:1.13.0-1.5.amzn1 will be installed
---> Package pgbouncer.x86_64 0:1.8.1-1.rhel6 will be installed
--> Processing Dependency: libevent2 >= 2.0 for package: pgbouncer-1.8.1-1.rhel6.x86_64
--> Finished Dependency Resolution
Error: Package: pgbouncer-1.8.1-1.rhel6.x86_64 (pgdg10)
           Requires: libevent2 >= 2.0
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

Tất nhiên, việc thêm pgdg vào /etc/yum.repos.d/ sẽ không còn hữu ích nữa. Cả --skip-bị hỏng hoặc rpm -Va --nofiles --nodigest. Một

đơn giản
sudo yum install libevent2
Loaded plugins: priorities, update-motd, upgrade-helper
50 packages excluded due to repository priority protections
No package libevent2 available.
Error: Nothing to do

sẽ quá dễ dàng. Vì vậy, bạn phải tự xây dựng libevent2, đưa bạn trở lại vị trí khi bạn phải tự biên dịch mọi thứ. Nó là pgbouncer hoặc một trong những phụ thuộc của nó.

Một lần nữa - đào quá sâu với các đặc thù của cài đặt nằm ngoài phạm vi. Bạn nên biết rằng bạn có cơ hội lớn để cài đặt nó dưới dạng gói.

Cuối cùng - những câu hỏi như “tại sao postgres không cung cấp trình tổng hợp phiên gốc” lặp đi lặp lại. Thậm chí còn có những đề xuất và suy nghĩ rất mới mẻ về nó. Nhưng cho đến nay, cách tiếp cận phổ biến nhất ở đây là sử dụng pgbouncer.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để áp dụng một hàm cho từng phần tử của cột mảng trong Postgres?

  2. Làm cách nào để tự động cập nhật dấu thời gian trong PostgreSQL

  3. psql:FATAL:Xác thực ngang hàng không thành công cho nhà phát triển người dùng

  4. Cách tải xuống cột Postgres bytea dưới dạng tệp

  5. Ràng buộc bảng chéo trong PostgreSQL