Saya sedang mengerjakan sebuah aplikasi yang melibatkan eksekusi sangat tinggi dari pembaruan / pilih pertanyaan dalam database.
Saya memiliki tabel dasar (A) yang akan memiliki sekitar 500 catatan untuk entitas selama sehari. Dan untuk setiap pengguna dalam sistem, variasi entitas ini dibuat berdasarkan beberapa preferensi pengguna dan mereka disimpan dalam tabel lain (B). Ini dilakukan oleh pekerjaan cron yang berjalan pada tengah malam setiap hari.
Jadi jika ada 10.000 pengguna dan 500 catatan di tabel A, akan ada 5 juta catatan di tabel B untuk hari itu. Saya selalu menyimpan data untuk satu hari di tabel ini dan pada tengah malam saya mengarsipkan data historis ke HBase. Penyiapan ini berfungsi dengan baik dan saya tidak memiliki masalah kinerja sejauh ini.
Ada beberapa perubahan dalam persyaratan bisnis akhir-akhir ini dan sekarang beberapa atribut dalam tabel dasar A (untuk 15-20 catatan) akan berubah setiap 20 detik dan berdasarkan itu saya harus menghitung ulang beberapa nilai untuk semua catatan variasi dalam tabel B untuk semua pengguna. Meskipun hanya 20 catatan master yang berubah, saya perlu melakukan perhitungan ulang dan memperbarui 200.000 catatan pengguna yang membutuhkan waktu lebih dari 20 detik dan pada saat itu pembaruan berikutnya terjadi pada akhirnya yang mengakibatkan semua kueri pemilihan semakin antri. Saya mendapatkan sekitar 3 permintaan permintaan / 5 detik dari pengguna online yang menghasilkan 6-9 Pilih kueri. Untuk menanggapi permintaan api, saya selalu menggunakan bidang di tabel B.
Saya dapat membeli lebih banyak kekuatan pemrosesan dan menyelesaikan situasi ini, tetapi saya tertarik memiliki sistem dengan skala yang benar yang dapat menangani bahkan satu juta pengguna.
Adakah yang bisa menyarankan alternatif yang lebih baik di sini? Apakah basis data nosql + relasional membantu saya di sini? Apakah ada platform / datastore yang akan membiarkan saya memperbarui data sering tanpa mengunci dan pada saat yang sama memberi saya fleksibilitas menjalankan kueri pemilihan pada berbagai bidang dalam suatu entitas?
sumber
Jawaban:
Sepertinya tabel
B
adalah semacam cache. Tapi cache semacam itu yang menurunkan produktivitas ..Bahkan jika Anda memiliki 25 kueri per detik, Anda bisa menolak penggunaan tabel
B
, dan menghitung jawaban untuk setiap permintaan.Lagi pula , jika Anda memiliki 30 detik keterlambatan memperbarui 20 catatan - itu adalah kegagalan dalam arsitektur perangkat lunak (saya salah, jika DB Anda menghitung 10 ^ 100 tanda PI pertama untuk setiap catatan).
Seperti yang saya tahu, DB relasional tanpa query SQL jelek, dengan indeks, dan dengan kurang dari 1.000 catatan akan bekerja dengan baik untuk hampir semua pertanyaan.
Cobalah untuk menolak penggunaan tabel
B
dan menambahkan indeks yang sesuai ke tabel AndaA
(kebanyakan database modern memiliki alat bantu). Berikutnya: mencoba mengoptimalkan struktur data (tabelA
) dan kueri (menggunakan penganalisis kueri, atau dengan ahli SQL) untuk mempercepat perhitungan. Jika Anda akan memperbarui hanya 20 catatan - keberadaan indeks tidak akan membahayakan produktivitas dari proses pembaruan , tetapi secara signifikan meningkatkan kecepatan pilih .sumber
Pertanyaannya adalah sistem apa yang menghitung catatan untuk dimasukkan ke dalam B dan ukuran data B.
Basis data apa pun (mis. MSSQL) harus dapat menangani volume sisipan yang Anda bicarakan tanpa masalah dengan asumsi objek tersebut tidak besar.
Pembaruan mungkin karena masalah yang lebih sulit, tetapi dengan pengindeksan dan penguncian yang benar, sekali lagi seharusnya tidak menjadi masalah besar.
99% dari waktu ketika saya melihat masalah seperti ini karena catatan B sedang dihitung oleh proc yang disimpan. Ini menempatkan semua beban pada server db
Jika ini masalahnya solusinya adalah memindahkan kode ini ke layanan offline yang dapat dipanggil melalui sistem antrian.
Jadi pembaruan Anda Sebuah pesan akan memicu proses pekerja yang akan melewati pengguna dan membuat pesan B pembaruan untuk setiap pengguna
Proses pekerja kedua B akan mengambil pembaruan Pengguna X dengan data Peristiwa membuat catatan B dan memperbarui DB
Ini dapat diskalakan dengan menambahkan lebih banyak kotak dengan pekerja antrian di atasnya, sehingga Anda memiliki kekuatan pemrosesan yang semakin banyak di belakang perhitungan, membuat db Anda bebas untuk berkonsentrasi pada pembaruan dan pemilihan.
Anda dapat lebih mengoptimalkan dengan memisahkan pilihan dari pembaruan / sisipan. memiliki DB baru yang mendapatkan semua permintaan pilih sebagai budak replikasi DB lama yang mendapatkan semua pembaruan.
sumber
Jika Anda menjalankan di Amazon saya akan mempertimbangkan DynamoDB. Ini berbasis memori flash. Berikut ini tautannya: https://aws.amazon.com/dynamodb/ .
RDBMS jenis apa yang Anda gunakan? Anda mungkin dapat meningkatkan kinerja dengan menggunakan UDF, atau bidang terhitung dalam tampilan. Apakah Anda menjalankan perhitungan dalam database melalui satu permintaan pembaruan, atau apakah Anda memilih data dari database, menjalankan perhitungan dalam proses lain dan kemudian memuatnya kembali?
Oracle dikonfigurasi secara default untuk menggunakan eksekusi mode snapshot, artinya baris tidak dikunci selama pembaruan dan pilihan bersamaan mendapatkan nilai asli. SQL Server dikonfigurasi secara default dengan konkurensi pesimis, sehingga pilihan bersamaan akan diblokir sampai pembaruan selesai. Beberapa versi SQL Server dapat dimasukkan ke mode snapshot, namun sangat meningkatkan tekanan pada tabel temp.
Lingkungan seperti apa yang Anda jalankan? Jika itu RDBMS pada instance EC2 di Amazon, maka coba letakkan DB datafile pada flash disk lokal. Saya telah melihat urutan perbedaan besar dalam memindahkan file dari EBS ke disk lokal.
sumber