PostgreSQL và cài đặt tính nhất quán ghi theo kết nối cụ thể

Bản dịch của bài viết được chuẩn bị riêng cho các học viên của khóa học "Cơ sở dữ liệu". Quan tâm đến việc phát triển theo hướng này? Chúng tôi mời bạn Ngày khai trương, nơi chúng tôi nói chi tiết về chương trình, các tính năng của hình thức trực tuyến, năng lực và triển vọng nghề nghiệp đang chờ đợi sinh viên tốt nghiệp sau đào tạo.

PostgreSQL và cài đặt tính nhất quán ghi theo kết nối cụ thể

PostgreSQL và cài đặt tính nhất quán ghi theo kết nối cụ thể
Tại Compose, chúng tôi xử lý nhiều cơ sở dữ liệu, điều này cho chúng tôi cơ hội làm quen hơn với chức năng và những thiếu sót của chúng. Khi chúng ta bắt đầu yêu thích các tính năng của cơ sở dữ liệu mới, đôi khi chúng ta bắt đầu nghĩ sẽ tuyệt biết bao nếu các tính năng tương tự xuất hiện trong các công cụ hoàn thiện hơn mà chúng ta đã làm việc trong một thời gian dài. Một trong những tính năng mới mà tôi muốn thấy trong PostgreSQL là tính nhất quán khi ghi trên mỗi kết nối trên toàn bộ cụm. Và hóa ra, chúng tôi đã có nó và hôm nay chúng tôi muốn chia sẻ với bạn thông tin về cách bạn có thể sử dụng nó.

Tại sao tôi cần nó?

Cách hoạt động của cụm tùy thuộc vào ứng dụng của bạn. Lấy ví dụ, một ứng dụng thanh toán hóa đơn. Bạn sẽ cần tính nhất quán XNUMX% trên toàn cụm, vì vậy bạn sẽ phải kích hoạt các cam kết đồng bộ để cơ sở dữ liệu của bạn chờ tất cả các thay đổi được thực hiện. Tuy nhiên, nếu ứng dụng của bạn là một mạng xã hội đang phát triển nhanh thì có thể bạn sẽ thích phản hồi nhanh hơn là tính nhất quán XNUMX%. Để đạt được điều này, bạn có thể sử dụng các cam kết không đồng bộ trong cụm của mình.

Gặp gỡ thỏa hiệp

Bạn phải cân bằng giữa tính nhất quán của dữ liệu và hiệu suất. PostgreSQL tránh xa tính nhất quán vì khi đó cấu hình mặc định có thể dự đoán được và không có những bất ngờ không mong muốn. Bây giờ chúng ta hãy nhìn vào sự thỏa hiệp.

Sự đánh đổi 1: Hiệu suất

Nếu cụm PostgreSQL không yêu cầu tính nhất quán thì nó có thể chạy không đồng bộ. Việc ghi được thực hiện cho người đứng đầu cụm và các bản cập nhật sẽ được gửi đến các bản sao của nó sau vài mili giây. Khi một cụm PostgreSQL yêu cầu tính nhất quán, nó phải chạy đồng bộ. Việc ghi sẽ được thực hiện cho người đứng đầu cụm, người đứng đầu cụm sẽ gửi bản cập nhật tới các bản sao và chờ xác nhận rằng mỗi bản sao đã được ghi trước khi gửi xác nhận cho khách hàng đã bắt đầu ghi rằng nó đã thành công. Sự khác biệt thực tế giữa các phương pháp này là phương pháp không đồng bộ yêu cầu hai bước nhảy mạng, trong khi phương pháp đồng bộ yêu cầu bốn bước nhảy.

Sự đánh đổi 2: Tính nhất quán

Kết quả trong trường hợp người lãnh đạo thất bại trong hai cách tiếp cận này cũng sẽ khác nhau. Nếu công việc được thực hiện không đồng bộ, thì nếu xảy ra lỗi như vậy, không phải tất cả các bản ghi sẽ được thực hiện bởi các bản sao. Sẽ mất bao nhiêu? Phụ thuộc vào chính ứng dụng và hiệu quả của việc nhân rộng. Sao chép soạn thảo sẽ ngăn bản sao trở thành bản sao dẫn đầu nếu lượng thông tin trong đó ít hơn 1 MB so với bản dẫn đầu, nghĩa là có thể mất tới 1 MB bản ghi trong quá trình hoạt động không đồng bộ.

Điều này không xảy ra ở chế độ đồng bộ. Nếu đường dẫn đầu không thành công, tất cả các bản sao sẽ được cập nhật, vì bất kỳ thao tác ghi nào được xác nhận trên đường dẫn đầu đều phải được xác nhận trên các bản sao. Đây là sự nhất quán.

Hành vi đồng bộ có ý nghĩa trong một ứng dụng thanh toán trong đó tính nhất quán có lợi thế rõ ràng trong việc cân bằng giữa tính nhất quán và hiệu suất. Điều quan trọng nhất đối với một ứng dụng như vậy là dữ liệu hợp lệ. Bây giờ hãy nghĩ về một mạng xã hội trong đó nhiệm vụ chính là thu hút sự chú ý của người dùng bằng cách phản hồi các yêu cầu càng nhanh càng tốt. Trong trường hợp này, hiệu suất với ít bước nhảy mạng hơn và ít thời gian chờ xác nhận hơn sẽ được ưu tiên. Tuy nhiên, sự cân bằng giữa hiệu suất và tính nhất quán không phải là điều duy nhất bạn phải nghĩ đến.

Đánh đổi 3: Sự cố

Điều rất quan trọng là phải hiểu cách một cụm hoạt động khi có lỗi. Hãy xem xét tình huống trong đó một hoặc nhiều bản sao bị lỗi. Khi các cam kết được xử lý không đồng bộ, người lãnh đạo sẽ tiếp tục hoạt động, nghĩa là chấp nhận và xử lý việc ghi mà không cần chờ đợi các bản sao bị thiếu. Khi các bản sao quay trở lại cụm, chúng sẽ bắt kịp người dẫn đầu. Với bản sao đồng bộ, nếu bản sao không phản hồi thì người lãnh đạo sẽ không có lựa chọn nào khác và sẽ tiếp tục chờ xác nhận cam kết cho đến khi bản sao quay trở lại cụm và có thể chấp nhận và cam kết ghi.

Một kết nối cho mỗi giao dịch?

Mỗi ứng dụng cần một kiểu kết hợp khác nhau giữa tính nhất quán và hiệu suất. Tất nhiên, trừ khi đó là ứng dụng thanh toán hóa đơn mà chúng ta tưởng tượng là hoàn toàn nhất quán hoặc ứng dụng mạng xã hội gần như phù du của chúng ta. Trong tất cả các trường hợp khác, sẽ có lúc một số thao tác phải đồng bộ và một số thao tác phải không đồng bộ. Bạn có thể không muốn hệ thống đợi cho đến khi tin nhắn gửi đến cuộc trò chuyện được cam kết, nhưng nếu một khoản thanh toán được xử lý trong cùng một ứng dụng thì bạn sẽ phải đợi.

Tất nhiên, tất cả những quyết định này đều do nhà phát triển ứng dụng đưa ra. Việc đưa ra quyết định đúng đắn về thời điểm sử dụng từng phương pháp tiếp cận sẽ giúp bạn tận dụng tối đa cụm của mình. Điều quan trọng là nhà phát triển có thể chuyển đổi giữa chúng ở cấp độ SQL để kết nối và giao dịch.

Đảm bảo kiểm soát trong thực tế

Theo mặc định, PostgreSQL cung cấp tính nhất quán. Điều này được kiểm soát bởi tham số máy chủ synchronous_commit. Theo mặc định nó ở vị trí on, nhưng nó có ba tùy chọn khác: local, remote_write hoặc off.

Khi thiết lập tham số thành off tất cả các cam kết đồng bộ đều bị dừng, ngay cả trên hệ thống cục bộ. Tham số cục bộ chỉ định chế độ đồng bộ cho hệ thống cục bộ, nhưng việc ghi vào bản sao được thực hiện không đồng bộ. Remote_write thậm chí còn đi xa hơn: việc ghi vào bản sao được thực hiện không đồng bộ nhưng được trả về khi bản sao đã chấp nhận việc ghi nhưng chưa ghi vào đĩa.

Bằng cách xem xét phạm vi tùy chọn có sẵn, chúng tôi chọn một hành vi và ghi nhớ rằng on – đây là những bản ghi đồng bộ, chúng ta sẽ chọn local đối với các cam kết không đồng bộ qua mạng, trong khi vẫn để các cam kết cục bộ đồng bộ.

Bây giờ, chúng tôi sẽ hướng dẫn bạn cách thiết lập tính năng này sau, nhưng hãy tưởng tượng rằng chúng tôi thiết lập synchronous_commit в local cho máy chủ. Chúng tôi tự hỏi liệu có thể thay đổi tham số synchronous_commit một cách nhanh chóng, và hóa ra điều đó không chỉ có thể thực hiện được mà thậm chí còn có hai cách để làm điều này. Đầu tiên là đặt phiên kết nối của bạn như sau:

SET SESSION synchronous_commit TO ON;  
// Your writes go here

Tất cả các lần ghi tiếp theo trong phiên sẽ xác nhận việc ghi vào bản sao trước khi trả về kết quả dương tính cho máy khách được kết nối. Tất nhiên trừ khi bạn thay đổi cài đặt synchronous_commit lại. Bạn có thể bỏ qua phần SESSION trong lệnh vì nó sẽ ở giá trị mặc định.

Phương pháp thứ hai phù hợp khi bạn chỉ muốn đảm bảo rằng bạn nhận được bản sao đồng bộ cho một giao dịch. Trong nhiều cơ sở dữ liệu tạo NoSQL, khái niệm giao dịch không tồn tại nhưng có trong PostgreSQL. Trong trường hợp này bạn bắt đầu một giao dịch và sau đó thiết lập synchronous_commit в on trước khi thực hiện mục nhập cho giao dịch. COMMIT sẽ cam kết giao dịch bằng bất kỳ giá trị tham số nào synchronous_commit, được đặt vào thời điểm đó, mặc dù tốt nhất bạn nên đặt trước biến để đảm bảo các nhà phát triển khác hiểu rằng việc ghi không đồng bộ.

BEGIN;  
SET LOCAL synchronous_commit TO ON;  
// Your writes go here
COMMIT;  

Tất cả các cam kết giao dịch giờ đây sẽ được xác nhận là được ghi vào bản sao trước khi cơ sở dữ liệu trả về phản hồi tích cực cho máy khách được kết nối.

Định cấu hình PostgreSQL

Trước đó, chúng tôi đã tưởng tượng ra một hệ thống PostgreSQL với synchronous_commit, cài đặt trong local. Để biến điều này thành hiện thực ở phía máy chủ, bạn sẽ cần đặt hai tùy chọn cấu hình máy chủ. Một tham số nữa synchronous_standby_names sẽ trở thành của riêng nó khi synchronous_commit sẽ ở on. Nó xác định bản sao nào đủ điều kiện cho các cam kết đồng bộ và chúng tôi sẽ đặt nó thành *, điều đó có nghĩa là tất cả các bản sao đều có liên quan. Các giá trị này thường được cấu hình trong tập tin cấu hình bằng cách thêm:

synchronous_commit = local  
synchronous_standby_names='*'

Bằng cách thiết lập tham số synchronous_commit thành ý nghĩa local, chúng tôi tạo ra một hệ thống trong đó các đĩa cục bộ vẫn đồng bộ, nhưng các cam kết bản sao mạng không đồng bộ theo mặc định. Tất nhiên, trừ khi chúng ta quyết định thực hiện các cam kết này một cách đồng bộ, như được hiển thị ở trên.

Nếu bạn đã theo dõi sự phát triển dự án thống đốc, bạn có thể nhận thấy một số thay đổi gần đây (1, 2), cho phép người dùng Thống đốc kiểm tra các tham số này và theo dõi tính nhất quán của chúng.

Còn vài lời nữa...

Chỉ một tuần trước, tôi đã nói với bạn rằng không thể tinh chỉnh PostgreSQL một cách tinh vi như vậy. Đó là khi Kurt, một thành viên của nhóm nền tảng Compose, nhấn mạnh rằng cơ hội như vậy tồn tại. Anh ấy đã xoa dịu sự phản đối của tôi và tìm thấy trong tài liệu PostgreSQL tiếp theo:

PostgreSQL và cài đặt tính nhất quán ghi theo kết nối cụ thể

Cài đặt này có thể được thay đổi bất cứ lúc nào. Hành vi của bất kỳ giao dịch nào được xác định bởi cài đặt có hiệu lực tại thời điểm cam kết. Do đó, có thể và hữu ích đối với một số giao dịch được thực hiện đồng bộ và đối với các giao dịch khác không đồng bộ. Ví dụ, để buộc một multistatement giao dịch để thực hiện các cam kết không đồng bộ khi giá trị mặc định của tham số ngược lại, được đặt SET LOCAL synchronous_commit TO OFF trong một giao dịch.

Với sửa đổi nhỏ này đối với tệp cấu hình, chúng tôi đã cấp cho người dùng quyền kiểm soát tính nhất quán và hiệu suất của họ.

Nguồn: www.habr.com

Thêm một lời nhận xét