PostgreSQL hoạt động tốt như thế nào với một số lượng lớn cơ sở dữ liệu?


9

Chúng tôi có một ứng dụng web có kiến ​​trúc yêu cầu mọi người dùng đã đăng ký (thực tế là một công ty) nên tách biệt với người khác, tức là tôi sẽ chạy cùng một ứng dụng web với cùng một mô hình dữ liệu, nhưng với các bộ dữ liệu khác nhau cho mỗi khách hàng.

Vì vậy, chúng tôi đã nghĩ về việc tạo ra một cơ sở dữ liệu khác nhau trong Postgres cho mọi khách hàng. Giải pháp này có thể mở rộng quy mô cơ sở dữ liệu 10-20K không? Làm thế nào tốt?

Có ai có một giải pháp tốt hơn cho điều này?

Cảm ơn trước.

Câu trả lời:


10

Ở cấp độ thấp, về cơ bản, nó sôi lên "bạn hoàn toàn có thể nói rằng bạn không có dữ liệu chia sẻ?" Không giống như mysql, cơ sở dữ liệu là một ràng buộc tuyệt đối trong postgresql. Bạn không thể SELECT zip_code FROM common.city_zip WHERE city=...nếu bạn đi với cơ sở dữ liệu riêng biệt (ít nhất là không có dblink).

Nếu bạn có bất kỳ dữ liệu chia sẻ nào, "lược đồ" của postgresql tương tự như cái mà mysql gọi là "cơ sở dữ liệu" . Bạn có thể CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);. Bạn sẽ tạo một lược đồ cho mỗi khách hàng, người dùng của khách hàng đó sẽ có lược đồ của họ trước trong đường dẫn tìm kiếm của họ và quyền sẽ được cấp để người dùng của Khách hàng A có quyền truy cập vào clientapubliclược đồ (và bảng của họ).

Vấn đề của bạn sẽ là ở cấp cao của # khách hàng, mỗi bảng được lưu dưới dạng tệp, do đó, dù bạn đi với một cơ sở dữ liệu cho mỗi khách hàng, một lược đồ cho mỗi khách hàng hay sử dụng một cái gì đó như ${client}_customercho tên bảng của bạn, bạn sẽ có khả năng chạy vào giới hạn filedescriptor với 10k khách hàng ngay cả khi bạn chỉ có một bảng cho mỗi khách hàng (cộng với một filedescriptor cho mỗi kết nối). Tất nhiên, bạn có thể điều chỉnh số lượng mô tả tệp tối đa của hạt nhân một cách nhanh chóng bằng sysctl, nhưng giới hạn cho mỗi quá trình (ulimit) sẽ yêu cầu khởi động lại postgresql nếu bạn đặt nó quá thấp trong lần đầu tiên.

Cách khác là có "một bảng lớn" với một cột máy khách xác định hàng đó thuộc về khách hàng nào (lý tưởng nhất là theo tên người dùng nếu bạn có một người dùng cho mỗi khách hàng, điều này làm cho công cụ bên dưới RẤT dễ dàng hơn). Bằng cách không cấp bất kỳ quyền truy cập nào cho bảng này của khách hàng, bạn có thể tạo các chế độ xem cụ thể của khách hàng (hoặc sử dụng session_userđể xác định ứng dụng khách hiện tại). Cập nhật không thể được thực hiện trực tiếp thông qua một cái nhìn, mặc dù. Bạn sẽ cần phải có các hàm được xác định để chèn / cập nhật / xóa trên bảng (một bộ hàm cho mỗi máy khách hoặc người khác sử dụng session_user) với các hàm sử dụng SECURITY DEFINERđể thực thi như một người dùng đặc biệt có quyền chèn / cập nhật / xóa trên các bảng (lưu ý : session_userđược sử dụng vì usercurrent_user được dựa trên bối cảnh hiện tại và trong hàm DEFINER AN NINH, đây sẽ luôn là người dùng xác định hàm).

Hiệu suất khôn ngoan, ngoài vấn đề fd, tôi thực sự không biết điều gì sẽ xảy ra với 10000 cơ sở dữ liệu trong postgresql, so với việc có một bảng lớn với 10000 dữ liệu của khách hàng trong đó. Thiết kế chỉ mục phù hợp sẽ giữ cho bảng lớn không bị chậm truy vấn.

Tôi sẽ nói rằng tôi đã đi với cơ sở dữ liệu riêng biệt cho từng khách hàng ở đây (chúng tôi thêm máy chủ để giữ cho hệ thống có thể sử dụng được, chuyển cơ sở dữ liệu khách sang máy chủ mới khi cần, vì vậy chúng tôi sẽ không bao giờ nhận được cơ sở dữ liệu 10k trên một máy chủ). Tôi đã phải khôi phục dữ liệu của từng khách hàng từ các bản sao lưu để gỡ lỗi hoặc do lỗi người dùng thường xuyên, điều gì đó sẽ là một cơn ác mộng tuyệt đối trên thiết kế "một bàn lớn". Ngoài ra, nếu bạn có ý định bán tùy chỉnh sản phẩm của mình cho khách hàng, thiết kế "một bàn lớn" có thể sẽ khiến bạn phải bối rối về khả năng tùy chỉnh mô hình dữ liệu.


Xin chào, DerfK. Tôi không thể sử dụng phương pháp "một bàn lớn" vì lý do bạn nêu. Ngay cả khi ngày nay, các mô hình dữ liệu giống nhau cho mọi người dùng, chúng tôi không thể đảm bảo rằng chúng sẽ luôn giống nhau. Ngoài ra, tôi không biết về ràng buộc cơ sở dữ liệu tuyệt đối trong PSQL (vì chúng tôi có một số dữ liệu được chia sẻ). Tôi nghĩ rằng tôi đã để lại các cách tiếp cận đặt tên lược đồ và bảng còn lại. Theo kinh nghiệm của bạn, việc quản lý số lượng cơ sở dữ liệu này khó khăn như thế nào (ngay cả trong các máy chủ khác nhau)?
Carlos

@Eduardo Khó khăn lớn nhất tôi gặp phải là đảm bảo rằng khi mô hình dữ liệu cần thay đổi cho mọi người, nó sẽ được thực hiện. Một ngày nào đó chúng ta sẽ điều chỉnh một cái gì đó giống như hệ thống của Rails để quản lý các thay đổi cho mô hình dữ liệu, cho đến lúc đó tôi có một tập lệnh lặp qua các máy khách và thực hiện cùng một lệnh trên mọi cơ sở dữ liệu. Vì chúng tôi hoàn toàn không chia sẻ dữ liệu, mọi thứ khác đều khá dễ dàng. Nếu bạn đi với một db với nhiều lược đồ, bạn vẫn có thể kết xuất một lược đồ máy khách tại một thời điểm bằng cách sử dụng pg_dump -n(hãy chắc chắn kết xuất lược đồ chung của bạn!) Để liệt kê lược đồ: psql -Esau đó\dn
DerfK

@Eduardo không thiết kế cho các tính năng mà bạn không có quyền. Nếu đó là trường hợp xe của tôi sẽ là một chiếc tàu ngầm và sẽ đẩy lùi gấu và có thể bay lên mặt trăng. Có rất nhiều mẫu thiết kế cơ sở dữ liệu vững chắc sẽ cho phép bạn bắt đầu với một bảng lớn và thêm các tính năng bổ sung khi cần. Điều quan trọng là hãy tự hỏi bạn cần gì hôm nay và nhóm ops của bạn sẽ có thể hỗ trợ dựa trên dự đoán tăng trưởng.
Jeremiah Peschka

@DerfK, stack web bạn sử dụng hôm nay là gì?
Carlos

@Jeremiah, bạn có một điểm tốt. Bạn có kinh nghiệm với các ứng dụng đa năng?
Carlos

3

Nếu không có thêm thông tin chi tiết về ứng dụng của bạn, thật khó để nói rằng bạn sẽ nhận được bất kỳ bảo mật bổ sung nào từ thiết lập này. Nếu mỗi khách hàng kết nối với ứng dụng web và có một người dùng được chia sẻ từ ứng dụng web đến cơ sở dữ liệu, thì bạn đã tách biệt dữ liệu của mình theo cách khác với việc sử dụng một cơ sở dữ liệu nguyên khối. Truy cập dữ liệu của bạn thông qua các thủ tục được lưu trữ được tham số hóa chính xác sẽ cung cấp cho bạn mức độ cô lập mà bạn đang tìm kiếm mà không phải đau đầu về quản trị hơn 10.000 cơ sở dữ liệu trên bất kỳ số lượng máy chủ nào.

Cá nhân tôi đã chạy một thiết lập tương tự trên một máy chủ cơ sở dữ liệu bằng cách sử dụng không có gì nhiều hơn các thủ tục được lưu trữ được tham số hóa đánh vào một cơ sở dữ liệu. Nếu bạn có thể đảm bảo rằng quyền truy cập duy nhất vào cơ sở dữ liệu là thông qua các thủ tục được lưu trữ, thì không có nguy cơ kết hợp dữ liệu trong kết quả.

Nếu bạn muốn tiếp tục với thiết kế của mình, đây là những mối quan tâm chính của tôi:

  1. hết bộ mô tả tệp đang mở ( ulimit -n) trên hệ điều hành máy chủ của bạn
  2. điều chỉnh hơn 10.000 cơ sở dữ liệu cho các mẫu truy vấn khác nhau
  3. quản trị hơn 10.000 cơ sở dữ liệu với các mối quan tâm bảo mật khác nhau (sao lưu và khôi phục tiềm năng, bạn có thực sự muốn khôi phục hơn 10.000 cơ sở dữ liệu nếu có lỗi máy chủ không?)
  4. đưa ra các thay đổi trên 10.000 cơ sở dữ liệu

Và sao lưu khó khăn để sao lưu và khôi phục dữ liệu của khách hàng? Là dễ dàng hơn để làm điều này với các thủ tục được lưu trữ hoặc với các lược đồ? Như bạn đã nói, thiết kế ứng dụng chỉ sử dụng một người dùng chung để kết nối với cơ sở dữ liệu. Lúc đầu, cách tiếp cận nhiều cơ sở dữ liệu được xem xét cho mối quan tâm quản lý, thay vì bảo mật.
Carlos

Các thủ tục được lưu trữ được tham số hóa không bảo vệ chống lại bất cứ điều gì ngoại trừ việc tiêm SQL. Nếu một trong những thủ tục đó làm a SELECT * WHERE clientId = 3, bạn có một rò rỉ bảo mật.
mikerobi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.