Trải nghiệm backend khi Optimizing Connection Pools - Tối ưu kết nối Database chuyên sâu - Phiên bản Business

Nội dung bài viết

Video học lập trình mỗi ngày

Từ học sinh, qua sinh viên, rồi đi làm, lên chức, và cuối cùng không dám lãng phí thời gian đó cũng là cách tối ưu hoá bản thân. Trong phần mềm cũng vậy có nhiều giai đoạn để tối ưu hoá, và mỗi lần là sẽ tối ưu hoá một điểm.

Bài viết cuối tuần chúng ta sẽ nói đến một điểm tối ưu đó là về việc tối ưu kết nối database dựa vào Connection Pools.

Bài viết này được đưa vào: Series: Chuyện cuối tuần của cựu chiến binh.

Nói về Connection Pools thì tôi đã có những bài viết trước đây mô phỏng sự chậm chạp khi connect sai trong hệ thống, bao gồm mysql, mongodb và redis.

Ngoài ra có cách viết connect đúng chuẩn cũng được đưa ra cũng là một cách tham khảo dành cho các lập trình viên muốn tìm hiểu và phát triển. Anh chị có thể xem những bài viết liên quan dưới đây.

CreatePool cách kết nối Mysql và Nodejs nhanh x3 lần so với cách thông thường createConnection

Tuyệt vời connect pool gồm 96 connects nhanh hơn gấp 50 lần so với 1000 or 4000 connections không dùng pool

Connection Pools - Cách hoạt động

Ngàn lời nói không bằng một bức tranh đúng không? Sau bức tranh là hoạt động thế nào? Trước tiên hãy xem mô hình tôi vẽ thông qua UML.

Nó rất rõ không cần phải giải thích thêm. Ở đây quan trọng là những thông số được thiết lập như thế nào?

Và mô hình này áp dụng được tất cả các ngôn ngữ không? Tôi sẽ đi lần lượt trong bài viết này cụ thể hơn so với các bài viết khác.

Connection Pools - Những thông số quan trọng.

Để cho Anh Chị copy xài thử luôn và thực hành thì tôi có chụp hai config của hai dự án lượng đồng thời cao - bán vé tàu tết - được phát triển song song hai ngôn ngữ JAVA và GO . Ở đây anh chị có thể xem các ngôn ngữ được tích hợp với các tool đều có thể hỗ trợ đầy đủ các tham số.

Hình 1 - JAVA: Kiến trúc DDD với một Server nhỏ nhưng chịu tại ~35.000 req/second. Lượng đặt vé tàu tết lên đến 1000 ticket/second. Có thể thấy đây cũng là mấu chốt tạo nên việc tối ưu.

Hình 2 - GO: Tương tự như JAVA kết hợp với GIN + Redis Cluster...

Các bạn cũng có thể xem từng Sesions tại blog này or có thể lấy Source về tại đây:

Source -> JAVA DDD

Source -> GO DDD

Source -> NODEJS -> Đầy đủ vũ khí với backend

Source -> NESTJS

Connection Pools - Giải thích cấu hình tối ưu

Sau đây tôi sẽ giải thích các tham số, vì sao phải đặt như vậy và vì sao phải đúng 6 tham số. Vì go đã tối ưu việc đóng gói cho nên chúng ta sẽ lấy JAVA ra để giải thích.

      maximum-pool-size: 10
      minimum-idle: 5
      idle-timeout: 30000
      max-lifetime: 1800000
      connection-timeout: 30000
      validation-timeout: 5000

Tôi có một nhà hàng (API) và chúng tôi có những quy tắc sau để đảm bảo việc nhà hàng hoạt động tốt cho dù khách ít hay nhiều mà giảm chi phí cho doanh nghiệp. Thì có những kịch bản như sau:

maximumPoolSize: Tổng số nhân viên tối đa: Kiểu nhà hàng dù có đông đến mấy thì nhân viên tối đa cũng là 20 nhân viên mà thôi. Xem đó mà làm. Cũng giống như việc server cũng chỉ có thể set maximumPoolSize=20 phục vụ.

Theo như UML trên tôi đã vẽ thì nếu như đạt giới hạn thì sẽ phải chờ đến khi phục vụ (connect) rảnh thì ok. Con số 20 connects này không phải là cố định. Nếu bạn quan tâm hãy xem đề xuất này của Oracle:

Tuyệt vời connect pool gồm 96 connects nhanh hơn gấp 50 lần so với 1000 or 4000 connections không dùng pool

minimumIdle: Số nhân viên nòng cốt (luôn túc trực): Khi nhà hàng vắng khách thì ít nhất tối thiểu có vài nhân viên ở đó luôn có sẵn.

Để khi anh tôi vào thì có em xinh đẹp phục vụ khà khà... Cũng giống trong hệ thống khi có request đột ngột, ứng dụng không phải chờ Pool tạo kết nối mới mà có thể lấy ngay một kết nối có sẵn. Giá trị của minimumIdle=maximumPoolSize/2

idleTimeout: Thời gian "thử thách" cho nhân viên tạm thời:

Quy tắc nhà hàng: "Trong giờ cao điểm, chúng ta đã thuê thêm 5 nhân viên thời vụ (từ 5 lên 10 người). Nhưng sau đó, khách vãn dần. Nếu một nhân viên thời vụ đứng không làm gì quá 10 phút, tôi sẽ cho họ về để tiết kiệm chi phí." Ý nghĩa kỹ thuật: Tham số này chỉ có tác dụng khi minimumIdle < maximumPoolSize. Nếu một kết nối (vượt quá số lượng minimumIdle) không được sử dụng trong một khoảng thời gian nhất định (ví dụ 10 phút), Pool sẽ đóng nó lại để giải phóng tài nguyên. Giá trị đề xuất: 30000 (30 giây). Giá trị này nên đủ dài để xử lý các đợt tải đột ngột ngắn, nhưng không quá dài để lãng phí tài nguyên.

maxLifetime: Ca làm việc tối đa của một nhân viên:

Quy tắc nhà hàng: "Để đảm bảo chất lượng phục vụ và sức khỏe của nhân viên, không ai được làm việc quá 8 tiếng liên tục. Hết 8 tiếng, dù đang bận, nhân viên đó sẽ được thay bằng một người mới hoàn toàn để tránh sai sót do mệt mỏi." Ý nghĩa kỹ thuật: Mỗi kết nối có một "vòng đời" tối đa. Sau khoảng thời gian này (ví dụ 30 phút), Pool sẽ đóng kết nối đó (dù nó đang rảnh hay bận) và thay thế bằng một kết nối mới. Điều này giúp ngăn ngừa các vấn đề do rò rỉ bộ nhớ hoặc các lỗi tiềm ẩn trên các kết nối cũ, giống như việc "làm mới" đội ngũ nhân viên. Giá trị đề xuất: 1800000 (30 phút).

connectionTimeout: Thời gian chờ tối đa của khách hàng:

Quy tắc nhà hàng: "Khi nhà hàng đã hết nhân viên phục vụ, chúng ta sẽ nói với khách hàng: 'Xin quý khách vui lòng chờ trong 5 phút'. Nếu sau 5 phút vẫn không có nhân viên nào rảnh, chúng ta phải thành thật xin lỗi và họ có thể sẽ rời đi." Ý nghĩa kỹ thuật: Đây là thời gian tối đa mà một yêu cầu (ứng dụng) sẽ chờ để lấy được kết nối từ Pool khi Pool đang bận. Nếu hết thời gian này mà vẫn không có kết nối, Pool sẽ ném ra một ngoại lệ (Exception). Điều này giúp ứng dụng không bị "treo" vô thời hạn. Giá trị đề xuất: 30000 (30 giây).

validationTimeout: Thời gian "kiểm tra sức khỏe" nhân viên:

Quy tắc nhà hàng: "Trước khi giao một khách hàng mới cho nhân viên, tôi sẽ hỏi nhanh: 'Sẵn sàng chưa?'. Tôi sẽ không đợi câu trả lời quá 2 giây. Nếu họ không phản hồi ngay, có nghĩa là họ đang gặp vấn đề, tôi sẽ tìm người khác ngay." Ý nghĩa kỹ thuật: Thời gian tối đa để Pool kiểm tra xem một kết nối có còn "sống" và hợp lệ hay không trước khi trao nó cho ứng dụng. Nếu việc kiểm tra mất quá nhiều thời gian, kết nối đó được coi là hỏng. Giá trị đề xuất: 5000 (5 giây).

Trên đây là những thông số anh em cố gắng hiểu và triển khai. Tất nhiên còn có nhiều cách, và đây là một cách tham khảo cho dự án trên.

[12.07.2025] - Cuối tuần vui vẻ anh em

Có thể bạn đã bị missing