Jawaban singkat di sini adalah "percobaan dan kesalahan yang dipandu oleh metrik pemantauan dan kinerja".
Ada beberapa aturan umum yang dapat membantu Anda menemukan area samar yang harus Anda mulai, tetapi mereka sangat umum. Pedoman umum "jumlah CPU plus jumlah disk yang independen" sering dikutip, tetapi ini hanyalah titik awal yang sangat kasar.
Yang benar-benar perlu Anda lakukan adalah mendapatkan metrik kinerja yang kuat untuk aplikasi Anda. Mulai merekam statistik.
Tidak banyak cara untuk mengintegrasikan alat untuk ini. Ada beberapa hal seperti check_postgres
skrip nagios , pencatatan konter kinerja sistem Cacti, pengumpul statistik PostgreSQL, dll ... tetapi tidak banyak yang menyatukan semuanya. Sayangnya, Anda harus melakukannya sendiri. Untuk sisi PostgreSQL, lihat pemantauan di manual PostgreSQL. Ada beberapa opsi pihak ketiga, seperti Postgres Enterprise Monitor EnterpriseDB .
Untuk metrik tingkat aplikasi yang disebutkan di sini, Anda ingin merekamnya dalam struktur data bersama atau dalam DB eksternal yang tidak tahan lama seperti Redis dan menggabungkannya baik saat Anda merekamnya atau sebelum Anda menulisnya ke PostgreSQL DB Anda. Mencoba masuk langsung ke Pg akan mendistorsi pengukuran Anda dengan overhead yang dibuat dengan mencatat pengukuran dan memperburuk masalah.
Opsi paling sederhana mungkin adalah singleton di setiap server aplikasi yang Anda gunakan untuk merekam statistik aplikasi. Anda mungkin ingin terus memperbarui min, maks, n, total, dan rata-rata; dengan begitu Anda tidak perlu menyimpan setiap titik stat, hanya agregat. Singleton ini dapat menulis statistik agregatnya ke Pg setiap x menit, tingkat yang cukup rendah sehingga dampak kinerja akan minimal.
Dimulai dari:
Apa latensi permintaan? Dengan kata lain, berapa lama waktu yang dibutuhkan aplikasi dari menerima permintaan dari klien hingga menanggapi klien. Catat ini secara agregat selama periode waktu tertentu, bukan sebagai catatan individual. Kelompokkan menurut jenis permintaan; katakan, demi halaman.
Apa penundaan akses basis data untuk setiap permintaan atau jenis permintaan yang dijalankan aplikasi? Berapa lama dari meminta informasi / menyimpan informasi sampai DB selesai dan dapat melanjutkan ke tugas berikutnya? Sekali lagi, gabungkan statistik ini dalam aplikasi dan hanya tuliskan informasi agregat ke DB.
Seperti apa throughput Anda? Dalam setiap x menit tertentu, berapa banyak kueri dari setiap kelas utama yang dijalankan aplikasi Anda dilayani oleh DB?
Untuk rentang waktu yang sama yaitu x menit, ada berapa banyak permintaan klien?
Menyampling setiap beberapa detik dan menjumlahkan melalui windows x menit yang sama dalam DB, berapa banyak koneksi DB yang ada? Berapa banyak dari mereka yang menganggur? Berapa banyak yang aktif? Di sisipan? Pembaruan? memilih? menghapus? Berapa banyak transaksi yang terjadi selama periode itu? Lihat dokumentasi pengumpul statistik
Sekali lagi mengambil sampel dan menggabungkan dalam interval waktu yang sama, seperti apa metrik kinerja sistem host? Berapa banyak membaca dan berapa banyak menulis disk IOs / detik? Megabita per detik disk membaca dan menulis? Pemanfaatan CPU? Rata-rata beban? Penggunaan RAM?
Anda sekarang dapat mulai belajar tentang kinerja aplikasi Anda dengan mengkorelasikan data, membuat grafik, dll. Anda akan mulai melihat pola, mulai menemukan kemacetan.
Anda mungkin mengetahui bahwa sistem Anda macet INSERT
dan UPDATE
s pada tingkat transaksi yang tinggi, meskipun I / O disk yang cukup rendah dalam megabyte per detik. Ini akan menjadi petunjuk bahwa Anda perlu meningkatkan kinerja flush disk Anda dengan pengontrol caching RAID write-back yang didukung baterai atau beberapa SSD yang dilindungi oleh daya berkualitas tinggi. Anda juga dapat menggunakan synchronous_commit = off
jika OK untuk kehilangan beberapa transaksi pada server crash, dan / atau a commit_delay
, untuk mengambil beberapa beban sinkronisasi.
Ketika Anda membuat grafik transaksi Anda per detik terhadap jumlah koneksi bersamaan dan mengoreksi untuk berbagai tingkat permintaan aplikasi melihat, Anda akan bisa mendapatkan ide yang lebih baik di mana sweet spot throughput Anda berada.
Jika Anda tidak memiliki penyimpanan pembilasan cepat (BBU RAID atau SSD tahan lama), Anda tidak akan menginginkan lebih dari sejumlah kecil koneksi yang aktif menulis, mungkin paling banyak 2x jumlah disk yang Anda miliki, mungkin lebih sedikit tergantung pada pengaturan RAID , kinerja disk, dll. Dalam hal ini bahkan tidak layak coba-coba; cukup tingkatkan subsistem penyimpanan Anda menjadi satu dengan flush disk cepat .
Lihat pg_test_fsync
alat yang akan membantu Anda menentukan apakah ini masalah bagi Anda. Sebagian besar paket PostgreSQL menginstal alat ini sebagai bagian dari contrib, jadi Anda tidak perlu mengkompilasinya. Jika Anda mendapatkan kurang dari beberapa ribu ops / detik, pg_test_fsync
Anda harus segera meningkatkan sistem penyimpanan Anda. Laptop saya yang dilengkapi SSD mendapat 5000-7000. Workstation saya bekerja dengan array RAID 10-disk 4 disk dengan disk 7200rpm SATA dan write-through (non-write-caching) mendapat sekitar 80 ops / detik f_datasync
, turun hingga 20 ops / detik untuk fsync()
; itu ratusan kali lebih lambat . Bandingkan: laptop dengan ssd vs workstation dengan RAID 10 ( write-through -caching). SSD laptop ini murah dan saya tidak percaya untuk menghapus cache tulisnya pada kehilangan daya; Saya menyimpan cadangan yang baik dan tidak akan menggunakannya untuk data yang saya pedulikan. SSD berkualitas baik berkinerja baik jika tidak lebih baik dan tahan lama.
Dalam hal aplikasi Anda, saya sangat menyarankan Anda untuk melihat ke dalam:
- Subsistem penyimpanan yang baik dengan flush yang cepat. Saya tidak bisa cukup menekankan hal ini. SSD dengan daya-gagal-aman berkualitas baik dan / atau pengontrol RAID dengan cache write-back yang dilindungi daya.
- Menggunakan
UNLOGGED
tabel untuk data yang Anda bisa kehilangan. Gabungkan secara berkala ke dalam tabel yang dicatat. Misalnya, pertahankan game-in-progress dalam tabel yang tidak dicatat, dan tulis skornya ke tabel awet biasa.
- Menggunakan
commit_delay
(kurang berguna dengan penyimpanan pembilasan cepat - petunjuk)
- Mematikan
synchronous_commit
transaksi yang Anda sanggup kehilangan (kurang berguna dengan penyimpanan yang cepat - petunjuk)
- Tabel partisi, terutama tabel di mana data "menua" dan dibersihkan. Alih-alih menghapus dari tabel dipartisi, jatuhkan partisi.
- Indeks sebagian
- Mengurangi jumlah indeks yang Anda buat. Setiap indeks memiliki biaya penulisan.
- Batching bekerja menjadi transaksi yang lebih besar
- Menggunakan replika siaga panas hanya baca untuk mengambil beban baca dari DB utama
- Menggunakan lapisan caching seperti memcached atau redis untuk data yang kurang sering berubah atau bisa basi. Anda dapat menggunakan
LISTEN
dan NOTIFY
untuk melakukan pembatalan cache menggunakan pemicu pada tabel PostgreSQL.
Jika ragu: http://www.postgresql.org/support/professional_support/
synchronous_commit = off
ataucommit_delay
?