Penyimpanan data mana yang terbaik untuk skenario saya?

10

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?

Kendi
sumber
Apakah Anda benar-benar perlu menyimpan semua data itu? Ini terdengar entah bagaimana seolah-olah Anda lebih baik menghitung berdasarkan permintaan. Jika Anda dapat menghitung 200 ribu catatan dalam lebih dari 20 detik, Anda harus menghitung 20 catatan tersebut * 3 pengguna = 60 catatan dalam waktu singkat. Mungkin Anda bisa melihat pengguna mana yang sedang online saat itu dan lebih mengoptimalkan? Sepertinya Anda menghasilkan banyak data yang tidak pernah digunakan siapa pun (selama data tersebut setidaknya masih valid)
thorsten müller
Menghasilkan hanya untuk pengguna yang sudah masuk adalah pilihan yang sangat baik untuk mereka. Saya memang memikirkan hal itu juga, tetapi tetap saja itu bukan pendekatan yang dapat diskalakan. Platform saya akan digunakan hanya pada siang hari dan karenanya selama waktu itu, sebagian besar pengguna akan aktif. Adakah saran lain jodoh?
Kendi
@ Kendi - Itu masih menyisakan pertanyaan apakah Anda bisa menghitung dengan cepat. Apakah Anda harus memperbarui catatan, atau apakah aplikasi Anda hanya perlu data ada di sana?
Bobson
Saya khawatir saya tidak dapat menghitung dengan cepat karena tabel entri B diberi peringkat untuk pengguna (5 bintang hingga 1 bintang) dan setelah perhitungan ini dilakukan, kami melakukan pemeringkatan lagi untuk pengguna. Seluruh proses untuk pengguna membutuhkan 500 msecs dan jika saya melakukannya dengan cepat, itu akan memengaruhi waktu respons API kami
Kendi
Saya berpikir jika masuk akal untuk menyimpan skor dan peringkat di luar RDBMS mungkin dalam nosql db sehingga pernyataan pilih akan tetap berjalan tanpa cegukan namun kadang-kadang saya perlu menanyakan skor dan peringkat juga. Jadi saya agak tersesat saat ini dan itulah sebabnya saya mencari saran dari beberapa ahli seperti kalian
Jugs

Jawaban:

1

Sepertinya tabel Badalah semacam cache. Tapi cache semacam itu yang menurunkan produktivitas ..

Bahkan jika Anda memiliki 25 kueri per detik, Anda bisa menolak penggunaan tabelB , 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 Bdan menambahkan indeks yang sesuai ke tabel Anda A(kebanyakan database modern memiliki alat bantu). Berikutnya: mencoba mengoptimalkan struktur data (tabel A) 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 .

maxkoryukov
sumber
1

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.

Ewan
sumber
0

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.

Robert-Ryan.
sumber