Vì sao cơ chế connection pooling có sẵn của Odoo giữ kết nối PostgreSQL mở liên tục, PgBouncer chia sẻ kết nối giữa các worker như thế nào, và module OCA mà Trobz xây dựng để Odoo chạy được với PgBouncer.

PgBouncer là một connection pooler cho PostgreSQL. Công cụ này hữu ích trong các hệ thống Odoo, nhất là khi có nhiều người dùng và nhiều Odoo worker.

Vì sao connection pooling của Odoo chưa đủ?

Connection pooling có sẵn của Odoo hoạt động ở cấp tiến trình: mỗi tiến trình Odoo có ConnectionPool riêng, giới hạn bởi db_maxconn.

Cơ chế này tái sử dụng được các kết nối đang mở trong pool. Nhưng nó không bao giờ đóng các kết nối đó, trừ khi chạm tới db_maxconn.

Trên thực tế, chúng tôi thấy mỗi Odoo worker thường giữ tới 3 kết nối mở trong pool của mình. Với 10 HTTP worker, riêng một instance đã có tới 30 kết nối mở liên tục.

PgBouncer giải quyết vấn đề này

PgBouncer giới hạn số kết nối đang mở bằng cách dùng chung một pool kết nối cho tất cả worker ở cấp instance. Mỗi Odoo worker vẫn giữ tới 3 kết nối mở, nhưng đó là kết nối tới PgBouncer, và PgBouncer sẽ đóng các kết nối không cần thiết tới PostgreSQL.

Cách này đã được chứng minh là giúp cải thiện hiệu năng trên các hệ thống Odoo có nhiều instance.

PgBouncer còn cho phép quy định cách chia sẻ tài nguyên theo thứ tự ưu tiên của bạn. Ví dụ:

  • instance Odoo chính trên host A được mở tối đa 30 kết nối;
  • instance Odoo trên host B, chuyên chạy báo cáo, chỉ được mở tối đa 10 kết nối.

Quan trọng nhất, PgBouncer giúp bảo đảm phía PostgreSQL server không bao giờ chạm tới max_connections.

Odoo cần vài thay đổi để chạy với PgBouncer

Khi cấu hình PgBouncer, có hai chế độ pooling để chọn:

  • pool_mode = session
  • pool_mode = transaction

Với pool_mode = session, một kết nối tới server sẽ gắn với một tiến trình Odoo cho tới khi tiến trình đó kết thúc, cũng chính là điều chúng ta đang muốn thay đổi. Để giải phóng kết nối tới server ngay khi mỗi transaction hoàn tất, chúng tôi dùng pool_mode = transaction.

Chế độ này chạy tốt, trừ các tính năng longpolling của Odoo vốn dựa vào LISTEN/NOTIFY. LISTEN không tương thích với chế độ transaction.

Nói chính xác hơn, ở chế độ này PgBouncer vẫn chuyển tiếp đúng các lệnh NOTIFY. Chỉ có LISTEN là không được, vì lệnh này cần giữ kết nối tới server luôn mở.

Vì vậy, với kết nối “lắng nghe” duy nhất của mỗi instance cần tới lệnh này, Odoo phải kết nối thẳng tới PostgreSQL server, bỏ qua PgBouncer.

Module mới: bus_alt_connection

Tại Trobz, chúng tôi xây dựng bus_alt_connection để thực hiện các thay đổi này, bằng cách override method tương ứng của Dispatcher.

Module đã chạy ổn định trên production trong nhiều tháng, và gần đây chúng tôi đã mở mã nguồn bằng cách đưa lên OCA/server-tools. Nếu bạn định dùng PgBouncer cho hệ thống Odoo của mình, hãy thử module này. Mọi góp ý và review đều được hoan nghênh.