Seberapa baik kinerja PostgreSQL dengan sejumlah besar database?

9

Kami memiliki aplikasi web yang arsitekturnya mengharuskan pengguna terdaftar (perusahaan, sebenarnya) harus diisolasi dari yang lain, yaitu, saya akan menjalankan aplikasi web yang sama dengan model data yang sama, tetapi dengan set data yang berbeda untuk setiap pelanggan.

Jadi, kami memang berpikir untuk membuat database berbeda di Postgres untuk setiap pelanggan. Dapatkah solusi ini menskalakan, katakanlah, database 10-20K? Seberapa baik?

Adakah yang punya solusi yang lebih baik untuk ini?

Terima kasih sebelumnya.

Carlos
sumber

Jawaban:

10

Pada akhirnya, itu pada dasarnya bermuara pada "dapatkah Anda benar-benar mengatakan bahwa Anda tidak memiliki data bersama?" Tidak seperti mysql, database adalah batas absolut di postgresql. Anda tidak bisa SELECT zip_code FROM common.city_zip WHERE city=...jika Anda pergi dengan database terpisah (setidaknya bukan tanpa dblink).

Jika Anda memiliki data yang dibagikan sama sekali, "skema" postgresql mirip dengan apa yang disebut mysql sebagai "database" . Kamu bisa CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);. Anda akan membuat skema untuk setiap klien, pengguna klien akan memiliki skema pertama mereka di jalan pencarian mereka, dan izin akan diberikan sehingga Klien A pengguna akan memiliki akses ke clientadan publicskema (dan meja mereka).

Masalah Anda adalah bahwa pada ujung # klien, setiap tabel disimpan sebagai file, jadi apakah Anda menggunakan satu basis data per klien, satu skema per klien, atau menggunakan sesuatu seperti ${client}_customeruntuk nama tabel Anda, Anda akan kemungkinan bertemu dengan batas pengajuan arsip dengan 10 ribu klien meskipun Anda hanya memiliki satu tabel per klien (ditambah satu pengajuan pengajuan arsip per koneksi). Tentu saja, Anda dapat menyesuaikan jumlah maksimum file deskriptor kernel saat itu menggunakan sysctl, tetapi batas per-proses (ulimit) akan membutuhkan memulai kembali postgresql jika Anda mengaturnya terlalu rendah pada kali pertama.

Alternatifnya adalah memiliki "satu tabel besar" dengan kolom klien yang mengidentifikasi klien mana yang dimiliki baris (idealnya, dengan nama pengguna jika Anda memiliki satu pengguna per klien, ini membuat barang-barang di bawah BANYAK lebih mudah). Dengan tidak memberikan akses apa pun ke tabel ini oleh klien, Anda dapat membuat tampilan khusus klien (atau gunakan session_useruntuk mengidentifikasi klien saat ini). Pembaruan tidak dapat dilakukan secara langsung melalui tampilan. Anda harus memiliki fungsi yang telah ditentukan untuk menyisipkan / memperbarui / menghapus di atas meja (satu set fungsi per klien atau yang lain menggunakan session_user) dengan fungsi menggunakan SECURITY DEFINERuntuk mengeksekusi sebagai pengguna khusus dengan izin untuk memasukkan / memperbarui / menghapus tabel (catatan : session_userdigunakan karena userdancurrent_user didasarkan pada konteks saat ini, dan dalam fungsi SECURITY DEFINER ini akan selalu menjadi pengguna yang mendefinisikan fungsi).

Kinerja-bijaksana, di luar masalah fd, jujur ​​saya tidak tahu apa yang akan terjadi dengan 10.000 database di postgresql, dibandingkan memiliki satu tabel besar dengan data senilai 10.000 klien di dalamnya. Desain indeks yang tepat harus menjaga tabel besar agar tidak lambat untuk kueri.

Saya akan mengatakan bahwa saya pergi dengan database terpisah untuk setiap klien di sini (kami menambahkan server agar sistem dapat digunakan, menggeser database klien ke server baru sesuai kebutuhan, jadi kami tidak akan pernah mendapatkan 10 ribu basis data pada satu server). Saya harus memulihkan data masing-masing klien dari cadangan untuk debugging atau karena kesalahan pengguna secara teratur, sesuatu yang akan menjadi mimpi buruk mutlak pada desain "satu tabel besar". Juga, jika Anda berniat untuk menjual kustomisasi produk Anda kepada klien Anda, desain "satu meja besar" mungkin akan membuat Anda terpincang-pincang sejauh kemampuan untuk menyesuaikan model data.

DerfK
sumber
Hai, DerfK. Saya tidak bisa menggunakan pendekatan "satu meja besar" karena alasan yang Anda sebutkan. Bahkan jika hari ini, model data adalah sama untuk setiap pengguna, kami tidak dapat menjamin bahwa mereka akan selalu sama. Juga, saya tidak tahu tentang batas basis data absolut dalam PSQL (karena kami memiliki beberapa data bersama). Saya pikir saya telah meninggalkan skema dan pendekatan penamaan tabel yang tersisa. Dalam pengalaman Anda, seberapa sulitkah mengelola jumlah basis data ini (bahkan di server yang berbeda)?
Carlos
@Eduardo Kesulitan terbesar yang saya miliki adalah memastikan bahwa ketika model data perlu diubah untuk semua orang, itu akan selesai. Suatu hari nanti kami akan mengadaptasi sesuatu seperti sistem Rails untuk mengelola perubahan pada model data, sampai saat itu saya memiliki skrip yang melewati klien dan mengeksekusi perintah yang sama pada setiap database. Karena kami tidak melakukan data yang dibagikan sama sekali, semua hal lain menjadi sangat mudah. Jika Anda menggunakan satu db dengan beberapa skema, Anda masih dapat membuang satu skema klien sekaligus menggunakan pg_dump -n(pastikan untuk membuang skema umum Anda juga!) psql -E\dn
Ke
@Eduardo tidak merancang untuk fitur yang tidak Anda miliki. Jika itu yang terjadi, mobil saya akan menjadi kapal selam dan akan mengusir beruang dan dapat terbang ke bulan. Ada banyak pola desain basis data yang solid yang akan memungkinkan Anda memulai dengan tabel besar dan menambahkan fitur tambahan sesuai kebutuhan. Kuncinya adalah bertanya pada diri sendiri apa yang Anda butuhkan hari ini dan apa yang dapat didukung oleh tim ops Anda berdasarkan proyeksi pertumbuhan.
Jeremiah Peschka
@ DerfK, apa tumpukan web yang Anda gunakan hari ini?
Carlos
@ Yeremia, Anda punya poin bagus. Apakah Anda memiliki pengalaman dengan aplikasi multitenant?
Carlos
3

Tanpa rincian lebih lanjut tentang aplikasi Anda, sulit untuk mengatakan bahwa Anda akan mendapatkan keamanan tambahan dari pengaturan ini. Jika setiap klien terhubung ke aplikasi web dan ada pengguna bersama dari aplikasi web ke database, maka Anda belum mengisolasi data Anda dengan cara yang berbeda dari menggunakan database monolitik tunggal. Mengakses data Anda melalui prosedur tersimpan yang diparameterisasi dengan benar akan memberi Anda tingkat isolasi yang Anda cari tanpa kesulitan administrasi mengelola 10.000+ basis data di sejumlah server.

Saya pribadi menjalankan set up serupa pada satu server basis data dengan menggunakan tidak lebih dari prosedur tersimpan berparameter yang mengenai satu basis data. Jika Anda dapat menjamin bahwa satu-satunya akses ke database adalah melalui prosedur yang tersimpan, tidak ada bahaya data ikut tercampur dalam hasil.

Jika Anda ingin maju dengan desain Anda, berikut ini adalah kekhawatiran utama saya:

  1. kehabisan deskriptor file terbuka ( ulimit -n) pada OS host Anda
  2. menyetel 10.000+ basis data untuk pola kueri yang berbeda
  3. mengelola 10.000+ database dengan masalah keamanan yang berbeda (cadangan dan pemulihan potensial, apakah Anda benar-benar ingin memulihkan 10.000+ database jika ada kegagalan server?)
  4. meluncurkan perubahan di 10.000+ basis data
Jeremiah Peschka
sumber
Dan seberapa sulit untuk membuat cadangan dan mengembalikan data klien? Apakah lebih mudah melakukan ini dengan prosedur tersimpan atau dengan skema? Seperti yang Anda nyatakan, desain aplikasi tidak hanya menggunakan satu pengguna bersama untuk terhubung ke database. Pada awalnya, beberapa pendekatan basis data dipertimbangkan untuk masalah manajemen, bukan keamanan.
Carlos
Prosedur tersimpan yang diparameterisasi tidak melindungi terhadap apa pun selain injeksi SQL. Jika salah satu dari prosedur tersebut melakukan SELECT * WHERE clientId = 3, Anda memiliki kebocoran keamanan.
mikerobi